proftpd-dfsg-1.3.5~rc3/0000755000175000017500000000000012156653653014561 5ustar frankiefrankieproftpd-dfsg-1.3.5~rc3/m4/0000755000175000017500000000000012156653653015101 5ustar frankiefrankieproftpd-dfsg-1.3.5~rc3/m4/proftpd.m40000644000175000017500000001031311653707002017004 0ustar frankiefrankie# PR_FUNC_SETGRENT_VOID # --------------------- # Check whether setgret returns void, and #define SETGRENT_VOID in # that case. AC_DEFUN([PR_FUNC_SETGRENT_VOID], [AC_CACHE_CHECK([whether setgrent returns void], [ac_cv_func_setgrent_void], [AC_RUN_IFELSE([ #include #include int main(int argc, char *argv[]) { int i = 0; getgrent(); i = setgrent(); return (i != 1); } ], [ac_cv_func_setgrent_void=no], [ac_cv_func_setgrent_void=yes], [ac_cv_func_setgrent_void=yes], )]) if test $ac_cv_func_setgrent_void = yes; then AC_DEFINE(SETGRENT_VOID, 1, [Define to 1 if the `setgrent' function returns void instead of `int'.]) fi ]) # PR_CHECK_CC_OPT # --------------------- # Check whether the C compiler accepts the given option AC_DEFUN(PR_CHECK_CC_OPT, [AC_MSG_CHECKING([whether ${CC-cc} accepts -[$1]]) echo 'void f(){}' > conftest.c if test -z "`${CC-cc} -c -$1 conftest.c 2>&1`"; then AC_MSG_RESULT(yes) CFLAGS="$CFLAGS -$1" else AC_MSG_RESULT(no) fi rm -f conftest* ]) # PR_CHECK_SS_FAMILY # --------------------- # Check which member of the struct sockaddr_storage contains the family # information AC_DEFUN([PR_CHECK_SS_FAMILY], [ AC_MSG_CHECKING([whether ss_family is defined]) AC_TRY_COMPILE([ #include #include #include #include ], [ do { struct sockaddr_storage a; (void) a.ss_family; } while(0) ], [ AC_MSG_RESULT(yes) AC_DEFINE(HAVE_SS_FAMILY, 1, [Define if you have sockaddr_storage.ss_family.]) ], [ AC_MSG_RESULT(no) AC_MSG_CHECKING([whether __ss_family is defined]) AC_TRY_COMPILE([ #include #include #include #include ], [ do { struct sockaddr_storage a; (void) a.__ss_family; } while(0) ], [ AC_MSG_RESULT(yes) AC_DEFINE(HAVE___SS_FAMILY, 1, [Define if you have sockaddr_store.__ss_family.]) ], [ AC_MSG_RESULT(no) ]) ]) ]) # PR_CHECK_STRUCT_ADDRINFO # --------------------- # Check whether the system has a struct addrinfo defined AC_DEFUN([PR_CHECK_STRUCT_ADDRINFO], [AC_MSG_CHECKING([whether struct addrinfo is defined]) AC_TRY_COMPILE( [ #include #ifdef HAVE_UNISTD_H # include #endif #include #include #include ], [do { struct addrinfo a; (void) a.ai_flags; } while(0) ], [AC_MSG_RESULT(yes) AC_DEFINE(HAVE_STRUCT_ADDRINFO, 1, [Define if you have struct addrinfo]) ], [AC_MSG_RESULT(no) ]) ]) # PR_CHECK_STRUCT_SS # --------------------- # Check whether the system has a struct sockaddr_storage defined AC_DEFUN([PR_CHECK_STRUCT_SS], [AC_MSG_CHECKING([whether struct sockaddr_storage is defined]) AC_TRY_COMPILE( [ #include #ifdef HAVE_UNISTD_H # include #endif #include #include #include ], [do { struct sockaddr_storage ss; } while(0) ], [AC_MSG_RESULT(yes) AC_DEFINE(HAVE_STRUCT_SS, 1, [Define if you have struct sockaddr_storage]) ], [AC_MSG_RESULT(no) ]) ]) # PR_CHECK_SS_LEN # --------------------- # Check which member of the struct sockaddr_storage contains the length # information AC_DEFUN([PR_CHECK_SS_LEN], [ AC_MSG_CHECKING([whether ss_len is defined]) AC_TRY_COMPILE([ #include #include #include #include ], [ do { struct sockaddr_storage a; (void) a.ss_len; } while(0) ], [ AC_MSG_RESULT(yes) AC_DEFINE(HAVE_SS_LEN, 1, [Define if you have sockaddr_storage.ss_len.]) ], [ AC_MSG_RESULT(no) AC_MSG_CHECKING([whether __ss_len is defined]) AC_TRY_COMPILE([ #include #include #include #include ], [ do { struct sockaddr_storage a; (void) a.__ss_len; } while(0) ], [ AC_MSG_RESULT(yes) AC_DEFINE(HAVE___SS_LEN, 1, [Define if you have sockaddr_storage.__ss_len.]) ], [ AC_MSG_RESULT(no) ]) ]) ]) proftpd-dfsg-1.3.5~rc3/doc/0000755000175000017500000000000012162064002015303 5ustar frankiefrankieproftpd-dfsg-1.3.5~rc3/doc/contrib/0000755000175000017500000000000012156653653016766 5ustar frankiefrankieproftpd-dfsg-1.3.5~rc3/doc/contrib/mod_quotatab_radius.html0000644000175000017500000000435510566667704023716 0ustar frankiefrankie ProFTPD module mod_quotatab_radius

ProFTPD module mod_quotatab_radius



This mod_quotatab submodule is contained in the mod_quotatab_radius.c, part of the mod_quotatab package and is not compiled by default. See the mod_quotatab documentation for installation instructions.

This submodule provides the RADIUS-specific "driver" for retrieving quota limit table information from a RADIUS server.

Author

Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.


RADIUS Limit Quota Tables

RADIUS-based quota tables (source-type of "radius") can only be used for limit tables, not for tally tables. The frequent updates needed for maintaining tally tables mean that RADIUS is not well-suited to handle tally table storage.

The mod_quotatab_radius module supports the "radius" string for the source-type parameter of the QuotaLimitTable configuration directive. To configure these quota attributes, use the RadiusQuotaInfo configuration directive.

An example proftpd.conf configuration might look like:

  <IfModule mod_quotatab.c>
    <IfModule mod_quotatab_radius.c>
      # Use a RADIUS-based limit table
      QuotaLimitTable radius:
    </IfModule>

    # Use a file-based tally table
    QuotaTallyTable file:/usr/local/proftpd/ftpquota.tallytab

    # See the RadiusQuotaInfo description for more details
    RadiusQuotaInfo false soft 3.0 2.0 1.0 7 8 9
  </IfModule>


© Copyright 2005-2007 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/ftpmail.html0000644000175000017500000002035312113316067021277 0ustar frankiefrankie ftpmail: Automated Email Notifications of Uploads

ftpmail: Automated Email Notifications of Uploads



The ftpmail program is a Perl script designed to read ProFTPD's TransferLog log entries, watching for uploads, and to send an automatic email notification when uploads occur. To use ftpmail, you configure your proftpd daemon to write its TransferLog to a FIFO; the ftpmail program is a FIFO reading program which then processes those log messages.

The most current version of ftpmail is distributed with the ProFTPD source code.

Author

Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this program.



Usage

First, you have the following Perl modules installed:
  • Mail::Sendmail
  • Time::HiRes
You can easily determine if your Perl has these modules present, using:
  # perl -MMail::Sendmail -e0
  # perl -MTime::HiRes -e0
If you see an error similar to:
  Can't location Mail/Sendmail.pm in @INC (@INC contains: ...)
it means that you do not have that Perl module installed. Go to search.cpan.org to download the latest versions of these modules, and install them as per their instructions.

Next, you need to create the FIFO that ftpmail will read from. See the mkfifo(1) man page for instructions on how to create a FIFO. Note that you must use mkfifo to create a FIFO; using an ordinary file that happens to have a ".fifo" extension will not work for this.

After that, you need to start ftpmail running, before starting proftpd. For example, you might do:

   # ./ftpmail \
       --fifo=/var/proftpd/log/transfer.fifo \
       --from='tj@castaglia.org' \
       --recipient='tj@castaglia.org' \
       --smtp-server=mail.domain.com \
       --attach-file \
       --log=/var/proftpd/log/transfer.log &
The key is to make ftpmail run in the background, so that it is constantly running. If the ftpmail process dies, then proftpd will not be able to write the TransferLog.

The next step is to configure your proftpd daemon to write to the FIFO you created. Thus in your proftpd.conf, you would use the same path as given to ftpmail's --fifo option, e.g.:

  TransferLog /var/proftpd/log/transfer.fifo

Then start proftpd, log in, upload a file, and see what happens. One user modified their init for proftpd such that the ftpmail program was automatically started before the proftpd daemon was started.

Options
The following shows the full list of ftpmail options; this can also be obtained by running:

  # ftpmail --help

  usage: ftpmail [--help] [--fifo $path] [--from $addr] [--log $path]
    [--recipient $addrs] [--upload-recipient \$addrs]
    [--download-recipient $addrs] [--subject $string] [--smtp-server $addr]
    [--attach-file] [--ignore-users $regex | --watch-users $regex]

  The purpose of this script is to monitor the TransferLog written by proftpd
  for uploaded files.  Whenever a file is uploaded by a user, an email
  will be sent to the specified recipients.  In the email there will be
  the timestamp, the name of the user who uploaded the file, the path to
  the uploaded file, the size of the uploaded file, and the time it took
  to upload.

  Command-line options:

    --attach-file         If used, this will cause a copy of the uploaded file
                          to be included, as an attachment, in the generated
                          email.

    --auth $path          Configures the path to a file containing SMTP
                          authentication information.

                          The configured file should look like this:

                              user = $user
                              password = $password

    --fifo $path          Indicates the path to the FIFO to which proftpd is
                          writing its TransferLog.  That is, this is the path
                          that you used for the TransferLog directive in your
                          proftpd.conf.  This parameter is REQUIRED.

    --from $addr          Specifies the email address to use in the From header.
                          This parameter is REQUIRED.

    --help                Displays this message.

    --ignore-users $regex Specifies a Perl regular expression.  If the
                          uploading user name matches this regular expression,
                          then an email notification is NOT sent; otherwise,
                          an email is sent.

    --log $path           Since this script reads the TransferLog using FIFOs,
                          the actual TransferLog file is not written by default.
                          Use this option to write the normal TransferLog file,
                          in addition to watching for uploads.

    --recipient $addr     Specifies an email address to which to send an email
                          notification of the upload.  This option can be
                          used multiple times to specify multiple recipients.
                          AT LEAST ONE recipient is REQUIRED.

    --upload-recipient $addr
                          Same as --recipient.

    --download-recipient $addr
                          Specifies an email address to which to send an email
                          notification of the download.  This option can be
                          used multiple times to specify multiple recipients.

                          If this option is specified, then ftpmail will watch
                          for FTP downloads as well as uploads.

    --smtp-server $addr   Specifies the SMTP server to which to send the email.
                          This parameter is REQUIRED.

    --subject $string     Specify a custom Subject header for the email sent.
                          The default Subject is:

                            User '$user' uploaded file '$file' via FTP

    --watch-users $regex  Specifies a Perl regular expression.  If the
                          uploading user name matches this regular expression,
                          then an email notification is sent; otherwise,
                          no email is sent.

FAQ

Question: I would like to use ftpmail to send emails, but only for files uploaded to specific domains. How do I do this?
Answer: To do this, you will need to configure different TransferLog files in your different <VirtualHost> sections in your proftpd.conf.

The TransferLog file format does not include a field indicating the IP address (or DNS name) of the server on which the file transfer is occurring. This means that ftpmail does not know which server is handling the transfer. So, in order to have ftpmail send emails only for certain domains/servers, you will have to do something like:

 <VirtualHost a.b.c.d>
    ...
    TransferLog /path/to/vhost1.xferlog
    ..
  </VirtualHost>

  <VirtualHost e.f.g.h>
    ...
    TransferLog /path/to/vhost2.xferlog
    ...
  </VirtualHost>
Then start instances of ftpmail running, but only for the TransferLog files of the domains/virtual servers to be monitored.



Author: $Author: castaglia $
Last Updated: $Date: 2013/02/27 05:40:07 $


© Copyright 2008-2013 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_load.html0000644000175000017500000000631610165602373021427 0ustar frankiefrankie ProFTPD module mod_load

ProFTPD module mod_load



This module is contained in the mod_load.h and mod_load.c files for ProFTPD 1.2.x, and is not compiled by default. Installation instructions are discussed here. There are also some interesting notes on the usage of this module.

The code for determining load average on a given system is hairy, to say the least. Unfortunately, it is necessary to do it this way, as there is no standard method for extracting such information from the kernel. This module uses code from GNU's make application, which should function properly. If not, please contact the author as soon as possible.

The most current version of mod_load is distributed with the ProFTPD source code.

Author

Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.

Directives


MaxLoad

Syntax: MaxLoad number|"none" [message]
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_load
Compatibility: 1.2.2 and later

The MaxLoad directive configures the server to refuse to accept connections if the system load is at or above the configured number. An optional message can be specified, which will be displayed to clients who have been rejected. The rejection is also logged.

The number can also be "none", which is used to override any inherited load limits, as from a <Global> context.

The system load is the average number of processes ready to run during the last minute; this number varies from system to system.

Example:

  # Reject connections to our busy server
  MaxLoad 10.0 "Server busy, seek elsewhere"


Usage

The mod_load module is very straightforward, providing only the single configuration directive.

Display Variables
The following variables are provided by mod_load, and can be used in any Display file e.g. DisplayConnect and DisplayLogin.

  %{mod_load.curr_load}
  %{mod_load.max_load}


Installation

To install mod_load, follow the usual steps for using third-party modules in proftpd:
  ./configure --with-modules=mod_load
  make
  make install



Author: $Author: castaglia $
Last Updated: $Date: 2005/01/01 20:15:55 $


© Copyright 2000-2005 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_shaper.html0000644000175000017500000005637411175701031021774 0ustar frankiefrankie ProFTPD module mod_shaper

ProFTPD module mod_shaper



The mod_shaper module is designed to split overall rates, both download and upload, for the proftpd daemon among all connected FTP clients, shaping each session to use only a portion of the overall rate. mod_shaper shapes both transmitted traffic, e.g. bits being downloaded via the RETR command, and received traffic, e.g. bits being uploaded via the APPE, STOR, and STOU commands.

This module is contained in the mod_shaper.c file for ProFTPD 1.2.x/1.3.x, and is not compiled by default. Installation instructions are discussed here. Detailed documentation on mod_shaper usage can be found here.

The most current version of mod_shaper is distributed with the ProFTPD source code.

Author

Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.

Directives

Control Actions


ShaperAll

Syntax: ShaperAll ["priority" num] ["rate" num] ["downrate" num] ["uprate" num] ["shares" num] ["downshares" num] ["upshares" num]
Default: ShaperAll priority 10 rate -1.0 shares 5
Context: server config
Module: mod_shaper
Compatibility: 1.2.10rc1 and later

The ShaperAll directive is used to configure the overall mod_shaper settings: the rate for the entire daemon, the default shares for shaped sessions, and the default priority for shaped sessions. If specified, the priority cannot be a negative number, the rates are in KB/s and must be greater than zero, and the shares must be greater than one. For configuring the priority and shares for individual sessions, use the ShaperSession directive.

The rate parameter sets both the downrate (i.e. download rate from the server) and the uprate (i.e. the upload rate to the server) at the same time. Use downrate and uprate if you wish to configure different rates for downloads and uploads. Similarly, the shares parameter sets both downshares and upshares.

The default rate is -1.0, which means that in order for mod_shaper to function properly, a rate, either rate, downrate or uprate, must be specified. The default shares setting is 5, the default priority is 10.

Examples:

  # Change the overall daemon rate to 100 KB/s
  ShaperAll rate 100

  # Give 20 shares to each session by default, and have an overall rate of 1000
  ShaperAll rate 1000 shares 20

  # Have a larger number of downshares than upshares
  ShaperAll rate 1000 downshares 2000 upshares 20

  # Configure separate download and upload rates
  ShaperAll downrate 1000 uprate 500

See also: ShaperSession


ShaperControlsACLs

Syntax: ShaperControlsACLs actions|"all" "allow"|"deny" "user"|"group" list
Default: None
Context: server config
Module: mod_shaper
Compatibility: 1.2.10rc1 and later

The ShaperControlsACLs directive configures access lists of users or groups who are allowed (or denied) the ability to use the actions implemented by mod_shaper. The default behavior is to deny everyone unless an ACL allowing access has been explicitly configured.

If "allow" is used, then list, a comma-delimited list of users or groups, can use the given actions; all others are denied. If "deny" is used, then the list of users or groups cannot use actions all others are allowed. Multiple ShaperControlsACLs directives may be used to configure ACLs for different control actions, and for both users and groups.

The actions provided by mod_shaper are "all", "info", and "sess".

Examples:

  # Allow only user root to alter the overall settings
  ShaperControlsACLs all allow user root

  # Allow the ftpadm group to shape current sessions
  ShaperControlsACLs sess allow group ftpadm

  # Allow everyone but user bob to see the current shaper stats
  ShaperControlsACLs info deny user bob


ShaperEngine

Syntax: ShaperEngine on|off
Default: off
Context: server config, <VirtualHost>, <Global>
Module: mod_shaper
Compatibility: 1.2.10rc1 and later

The ShaperEngine directive enables or disables the "shaping" of sessions by mod_shaper. If it is set to off this module does no shaping of transmitted traffic. Use this directive to disable the module instead of commenting out all mod_shaper directives.


ShaperLog

Syntax: ShaperLog path|"none"
Default: None
Context: server config
Module: mod_shaper
Compatibility: 1.2.10rc1 and later

The ShaperLog directive is used to a specify a log file for mod_shaper reporting and debugging. The path parameter must be the full path to the file to use for logging. Note that this path must not be to a world-writeable directory and, unless AllowLogSymlinks is explicitly set to on (generally a bad idea), the path must not be a symbolic link.

If path is "none", no logging will be done at all.


ShaperSession

Syntax: ShaperSession ["priority" num] ["shares" +|-num] ["downshares" +|-num] ["upshares" +|-num]
Default: ShaperSession priority 10
Context: server config, <VirtualHost>, <Global>, <Anonymous>
Module: mod_shaper
Compatibility: 1.2.10rc1 and later

The ShaperSession directive is used to set shaping data on a per-session basis. It is intended to be used within mod_ifsession conditional configuration blocks. If used, the priority must not be a negative number. The shares parameters must start with '+' or '-'; these values adjust the default numbers of shares allotted to a session, increasing or reducing the sessions's shares. The ShaperAll directive is used for configuring overall shaping data.

The shares parameter sets both the downshares (i.e. shares of the download rate) and the upshares (i.e. shares of the upload rate) at the same time. Use downshares and upshares if you wish to configure different shares for downloads and uploads for the session.

Example:

  # Reward my friends
  ShaperSession shares +2

  # Punish my enemies
  ShaperSession shares -4

  # Allow for finer control over downloads by allocating more download
  # shares than upload shares for this session
  ShaperSession downshares +3 upshares -1

  # Let <Directory>-level TransferRate directives take priority
  ShaperSession priority 3

See also: ShaperAll


ShaperTable

Syntax: ShaperTable path
Default: None
Context: server config
Module: mod_shaper
Compatibility: 1.2.10rc1 and later

The ShaperTable directive configures a path to a file that mod_shaper uses for storing its shaping data. The given path must be an absolute path. Note: this directive is required for mod_shaper to function.


Control Actions


shaper all

Syntax: ftpdctl shaper all [priority num] [rate num] [downrate num] [uprate num] [shares num] [downshares num] [upshares num]
Purpose: Alter overall mod_shaper settings

The shaper all action is used to change the overall mod_shaper settings on-the-fly. If specified, the priority cannot be a negative number, the rates are in KB/s and must be greater than zero, and the shares must be greater than one. For changing the priority and shares for individual sessions, use the shaper sess control action.

The rate parameter sets both the downrate (i.e. download rate from the server) and the uprate (i.e. the upload rate to the server) at the same time. Use downrate and uprate if you wish to configure different rates for downloads and uploads. Similarly, the shares parameter sets both downshares and upshares.

For example, to set the overall rate for the entire daemon to be 2000 KB/s:

  ftpdctl shaper all rate 2000
To give every session 10 shares, both downshares and upshares, by default:
  ftpdctl shaper all shares 10
To set the default priority for sessions:
  ftpdctl shaper all priority 3
Note that multiple parameters can also be used simultaneously:
  ftpdctl shaper all rate 2000 shares 10 priority 3

See also: shaper sess


shaper info

Syntax: ftpdctl shaper info
Purpose: Print information about current shaped sessions

The shaper info control action can be used to view information on currently shaped sessions. This includes the current overall rate, the default number of shares per session, and the total number of currently shaped sessions. It also lists the following for each shaped session: process ID (PID), priority, downshare ("D") and upshare ("U") adjustments, and session downrate and uprate.

Example listing:

  # ftpdctl shaper info
  ftpdctl: Overall Rates: 1000.00 KB/s down, 500.00 KB/s up
  ftpdctl: Default Shares Per Session: 10 down, 10 up
  ftpdctl: Default Priority: 2
  ftpdctl: Number of Shaped Sessions: 2
  ftpdctl: PID   Priority DShares        DRate (KB/s) UShares        URate (KB/s)
  ftpdctl: ----- -------- -------------- ------------ -------------- ------------
  ftpdctl: 21750        2     12/24 (+2)       500.00      7/14 (-3)       250.00
  ftpdctl: 21753        2     12/24 (+2)       500.00      7/14 (-3)       250.00

The "DShares" and "UShares" columns are formatted as:
  sharessession/sharestotal (+|-sharesadjust)
The +2 and -3 in the listing above is due to a ShaperSession affecting these sessions:
  ShaperSession downshares +2 upshares -3


shaper sess

Syntax: ftpdctl shaper sess class|host|user name [priority num] [shares +|-num]
Purpose: Alter specific session's mod_shaper settings

The shaper sess action is used to change session-specific shaping data on-the-fly. If given, the priority must not be a negative number. The shares parameters must start with '+' or '-'; these values adjust the default numbers of shares allotted to a session, increasing or reducing the sessions's shares.

The shares parameter sets both the downshares (i.e. shares of the download rate) and the upshares (i.e. shares of the upload rate) at the same time. Use downshares and upshares if you wish to configure different shares for downloads and uploads for the session.

This example gives user alex an additional 10 shares:

  ftpdctl shaper sess user alex shares +10
The following sets the priority for host cache.example.com such that TransferRate directives in <Anonymous> sections, <Directory> sections and .ftpacccess files have precedence (see the usage instructions for more details on priority):
  ftpdctl shaper sess host cache.example.com priority 2
One can even change the settings on entire Classes of sessions:
  ftpdctl shaper sess class proxy downshares -3 priority 1

See also: shaper all


Installation

To install mod_shaper, copy the mod_shaper.c file into:
  proftpd-dir/contrib/
after unpacking the latest proftpd-1.2.x or proftpd-1.3.x source code. Then follow the usual steps for using third-party modules in proftpd, making sure to include the --enable-ctrls configure option, which mod_shaper requires:
  ./configure --enable-ctrls --with-modules=mod_shaper
  make
  make install


Usage

The ShaperTable is used to hold overall rates, both download and upload, for the entire daemon, the default number of shares and the default priority for each session. Then there is a list of shaping data for each particular session. To determine the portion of the overall rate that a session gets, mod_shaper calculates the total number of shares, and divides the overall rate by the total number of shares, resulting in a rate-per-share value:

  ratetotal / sharestotal = rateshare
The rate for a session is then the rate-per-share multiplied by the number of shares for that session:
  rateshare * sharessession = ratesession
Whenever a session starts or ends, mod_shaper recalculates the total number of shares and each session's rate, thus always adjusting values for each session so that the total of the session transfer rates never exceeds the overall mod_shaper rate. This means that mod_shaper divides the overall rate among all sessions (unless exempted), not just those sessions that are currently transferring files. Only if all shaped sessions are transferring data simultaneously will the overall rates be reached. Note that this calculation is performed separately for downloads and for uploads; sessions can have different shares of the download and upload rates.

Also, the transfer rate is calculated at the start of each transfer; the core proftpd engine does not recalculate the rate during the data transfer. This means, for example, that if a session gets 100 KB/s and starts a transfer, then a second session begins and gets 50 KB/s, the first session's transfer will continue to get 100 KB/s, until that transfer ends. The next transfer started by the first session would then get 50 KB/s, just like the second session.

By default, mod_shaper allots 5 shares for every session. Increasing the default number of shares for a session (using the ShaperAll configuration directive or the shaper all control action) does not increase the rate used by every session. If every session has the same number of shares, then the overall rate is divided evenly among the sessions; a higher default shares value results in a smaller rate-per-share value.

What is the benefit of increasing the default shares setting, then? It allows for finer-grained tuning of shaped sessions, using the ShaperSession directive and the shaper sess control actions. An example: given an overall rate of 100 KB/s, a default shares of 1, and 4 sessions, the rate-per-share will be 25 KB/s (100 / 4 = 25), and since each session has 1 share, the download rate for each session is 25 KB/s. Now, what if you want to change these setting on-the-fly, allow one of the sessions a higher transfer rate, and reduce the transfer rate for another session? You could add another share to the session for user dave:

  ftpdctl sess user dave shares +1
After this, the rate-per-share is 20 KB/s. The session belonging to user dave now has 2 shares, which means it has a download rate of 40 KB/s; the other sessions now have download rates of 20 KB/s. What about reducing the rate for one of the other sessions, one belonging to user anonymous? One might think that:
  ftpdctl sess user ftp shares -1
would work. It will not. You cannot reduce the number of shares for a given session below 1. mod_shaper rules do not allow this. However, if the default shares setting was higher, like 5 or 10, then the administrator would have enough shares for reducing a session's rate. The more default shares, the smaller the rate-per-share value, and thus the finer control, by adding or removing smaller increments, the administrator has over the shaped sessions.

mod_shaper uses the same mechanism that the standard proftpd configuration directive, TransferRate, uses for controlling a session's download rate. Using the same mechanism, though, means that mod_shaper may interfere with any TransferRate directives in your proftpd.conf. Which takes priority, mod_shaper or TransferRate? This is handled by assigning a priority to each each shaped session. The priority for TransferRate directives depends on the configuration context in which the directive appears:

TransferRate Priority
Context Priority
<Global> 1
server config 2
<VirtualHost> 2
<Anonymous> 3
<Directory> 4
.ftpaccess 5

The default priority assigned to mod_shaper sessions is 10. This means that mod_shaper takes precedence over TransferRate. However, if the site administrator needs <Directory>-level or .ftpaccess-level TransferRate directives to take priority, then the ShaperSession directive and shaper sess control action can be used to assign a priority to shaped sessions that is lower than that for <Directory> and .ftpaccess.

Configuring mod_shaper
Now that you know how the module works, it's time to see how to construct a proftpd.conf that enforces the desired shaper policy. Configuration directives that affect the shaping of sessions have control action equivalents, i.e. ShaperAll and shaper all, ShaperSession and shaper sess.

This example mod_shaper configuration uses the defaults and shapes all sessions:

  <IfModule mod_shaper.c>
    ShaperEngine on
    ShaperLog /var/log/ftpd/shaper.log
    ShaperTable /var/log/ftpd/shaper.tab

    # An overall rate (in KB/s) must be set.  This line explicitly
    # sets both the download and upload rates to be the same.
    ShaperAll downrate 1500 uprate 1500

    # Allow all system users to see shaper info
    ShaperControlsACLs info allow user *

    # Allow FTP admins to alter settings both overall and per-session
    ShaperControlsACLs all,sess allow group ftpadm
  </IfModule>

To exclude some user from having their sessions shaped by mod_shaper, use mod_ifsession for a configuration that adds the following:

  <IfModule mod_shaper.c>
    <IfUser lucky>
      ShaperEngine off
    </IfUser>
  </IfModule>
which says "If mod_shaper is present, and if the user logging in is named 'lucky', then disable mod_shaper for this session." Note that sessions that are not shaped by mod_shaper cannot be shaped once the user has logged in. Normal TransferRate directives will still apply to non-shaped sessions.

Similarly, you may wish to have a user that should have a greater portion of the overall download rate available to them:

  <IfModule mod_shaper.c>
    <IfUser lucky>
      ShaperSession downshares +5
    </IfUser>
  </IfModule>
This gives user lucky an additional 5 shares of the download rate, on top of the default number of shares for a session. Users can likewise have their default number of shares reduced, if necessary:
  <IfModule mod_shaper.c>
    <IfGroup anonftp>
      ShaperSession downshares -3
    </IfUser>
  </IfModule>
The control actions supported by mod_shaper can also be used, while the daemon and sessions are running, to set the desired shaping values.



Author: $Author: castaglia $
Last Updated: $Date: 2009/04/28 22:24:25 $


© Copyright 2004 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_exec.html0000644000175000017500000005642211630210400021417 0ustar frankiefrankie ProFTPD module mod_exec

ProFTPD module mod_exec



This module is contained in the mod_exec.c file for ProFTPD 1.3.x, found here, and is not compiled by default. Installation instructions are discussed here.

The mod_exec module can be used to execute external programs or scripts at various points in the process of handling FTP commands. By conscious design, the core ProFTPD engine does not and will not execute external programs. This is a security decision, as it was decided not to allow ProFTPD to serve as a means of compromising a system or disclosing information via bugs in external programs or scripts. Use of this module allows for such external programs to be executed, and also opens up the server to the mentioned possibilities of compromise or disclosure via those programs.

YOU HAVE BEEN WARNED
USE AT YOUR OWN RISK

Please read the usage section to know the other caveats with this module.

The most current version of mod_exec is distributed with the ProFTPD source code.

Author

Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.

Directives


ExecBeforeCommand

Syntax: ExecBeforeCommand cmds path [arg1 arg2 ...]
Default: None
Context: "server config" <VirtualHost>, <Global>, <Anonymous>, <Directory>
Module: mod_exec
Compatibility: 1.2.8 and later

The ExecBeforeCommand directive is used to execute the program or script at path before the handling of any FTP command listed in cmds, where cmds is a comma-delimited list of FTP commands. The command groups of the <Limit> directive, such as READ, WRITE, and ALL, may also be used. The program will be executed with the privileges of the logged-in user.

Any number of arbitrary arguments may be configured to pass to the script. In addition, the "cookies" supported by the ExecEnviron directive may also be used in the script argument list.

Important: use of DefaultRoot will cause complications (to be elaborated upon soon).

Example:

  ExecBeforeCommand RETR /path/to/ftp-prep --file %f

See Also: ExecEnviron, ExecOnCommand, ExecOnConnect, ExecOnError, ExecOnExit, ExecOnRestart, <Limit>


ExecEngine

Syntax: ExecEngine on|off
Default: None
Context: "server config", <VirtualHost>, <Global>
Module: mod_exec
Compatibility: 1.2.5rc2 and later

The ExecEngine directive enables or disables the module's runtime exec engine. If it is set to off this module will not manipulate environment variables or execute external scripts. Use this directive to disable the module instead of commenting out all mod_exec directives.


ExecEnviron

Syntax: ExecEnviron key value
Default: None
Context: "server config", <VirtualHost>, <Global>
Module: mod_exec
Compatibility: 1.2.5rc2 and later

The ExecEnviron directive is used to set the environment variables in the environment created for the script to be executed. The current environment is not passed directly to the script; this is to prevent unwanted information leakage. The given key parameter will be uppercased, to follow the convention for environment variable keys.

The value parameter may be any arbitrary string which may contain any of the following "cookies", which will be substituted with the corresponding value before the script is executed:

  • %A - Anonymous login password
  • %a - client's IP address
  • %C - current working directory
  • %c - connection class
  • %F - transfered file as seen by client
  • %f - full transfered file path
  • %g - name of primary group of local user
  • %h - client's DNS name
  • %m - FTP command (e.g. RETR, STOR, etc)
  • %r - full FTP command
  • %U - original username sent by client
  • %u - name of local user
  • %v - name of server handling session
  • %w - RNFR path ("whence" a rename comes, i.e. the source path)
The value parameter may be also be "-", which indicates that the current value of the environment variable of name key should be used (e.g. PATH). If there is no environment of name key when "-" is used, it will be created with a blank string as the value.


ExecLog

Syntax: ExecLog file|"none"
Default: None
Context: "server config", <VirtualHost>, <Global>
Module: mod_exec
Compatibility: 1.2.5rc2 and later

The ExecLog directive is used to a specify a log file for mod_exec reporting and debugging, and can be done a per-server basis. The file parameter must be the full path to the file to use for logging. Note that this path must not be to a world-writeable directory and, unless AllowLogSymlinks is explicitly set to on (generally a bad idea), the path must not be a symbolic link.

If file is "none", no logging will be done at all; this setting can be used to override an ExecLog setting inherited from a <Global> context.


ExecOnCommand

Syntax: ExecOnCommand cmds path [arg1 arg2 ...]
Default: None
Context: "server config" <VirtualHost>, <Global>, <Anonymous>, <Directory>
Module: mod_exec
Compatibility: 1.2.5rc2 and later

The ExecOnCommand directive is used to execute the program or script at path after the successful completion of any FTP command listed in cmds, where cmds is a comma-delimited list of FTP commands. The command groups of the <Limit> directive, such as READ, WRITE, and ALL, may also be used. The program will be executed with the privileges of the logged-in user.

Any number of arbitrary arguments may be configured to pass to the script. In addition, the "cookies" supported by the ExecEnviron directive may also be used in the script argument list.

Important: use of DefaultRoot will cause complications (to be elaborated upon soon).

Example:

  ExecOnCommand APPE,STOR /path/to/ftp-email-script --user %u --file %f

See Also: ExecBeforeCommand, ExecEnviron, ExecOnConnect, ExecOnError, ExecOnExit, ExecOnRestart, <Limit>


ExecOnConnect

Syntax: ExecOnConnect path [arg1 arg2 ...]
Default: None
Context: "server config" <VirtualHost>, <Global>, <Anonymous>, <Directory>
Module: mod_exec
Compatibility: 1.2.5rc2 and later

The ExecOnConnect directive is used to execute the program or script at path whenever a client connects to the server. The program will be executed with the privileges of the contacted server, which are set via the User/Group directives.

Any number of arbitrary arguments may be configured to pass to the script. In addition, the "cookies" supported by the ExecEnviron directive may also be used in the script argument list.

Example:

  ExecOnConnect /path/to/ftp-logger --ip %a --dns %h

See Also: ExecBeforeCommand, ExecEnviron, ExecOnCommand, ExecOnError, ExecOnExit, ExecOnRestart


ExecOnError

Syntax: ExecOnError cmds path [arg1 arg2 ...]
Default: None
Context: "server config" <VirtualHost>, <Global>, <Anonymous>, <Directory>
Module: mod_exec
Compatibility: 1.2.5rc2 and later

The ExecOnError directive is used to execute the program or script at path if an error occurs while processing any FTP command listed in cmds, where cmds is a comma-delimited list of FTP commands. The command groups of the <Limit> directive, such as READ, WRITE, and ALL, may also be used. The program will be executed with the privileges of the logged-in user.

Any number of arbitrary arguments may be configured to pass to the script. In addition, the "cookies" supported by the ExecEnviron directive may also be used in the script argument list.

Important: use of DefaultRoot will cause complications (to be elaborated upon soon).

Example:

  ExecOnError APPE,STOR /path/to/ftp-cleanup-script --user %u --file %f
See Also: ExecBeforeCommand, ExecEnviron, ExecOnCommand, ExecOnConnect, ExecOnExit, ExecOnRestart, <Limit>


ExecOnEvent

Syntax: ExecOnEvent event[*] path [arg1 arg2 ...]
Default: None
Context: "server config"
Module: mod_exec
Compatibility: 1.2.10rc1 and later

The ExecOnEvent directive is used to execute the program or script at path when the given event occurs. The program will be executed with the privileges of the server (set via the User and Group directives in the proftpd.conffile), unless the event name is followed by a "*", in which case the program will be executed with root privileges. Note: this feature should be used very carefully. It allows scripts to modify things like firewall rules, but should be used only for such sensitive tasks.

Any number of arbitrary arguments may be configured to pass to the script. In addition, the "cookies" supported by the ExecEnviron directive may also be used in the script argument list.

Presently only two specific events are supported: MaxConnectionRate and MaxInstances. These events happen when ever the limit configured by these configuration directives is reached.

This directive may be used several times to configure multiple programs to be invoked when event occurs.

Important: use of DefaultRoot will cause complications (to be elaborated upon soon).

Example:

  ExecOnEvent MaxConnectionRate* /path/to/ftp-firewall-script --ip %a
See Also: ExecBeforeCommand, ExecEnviron, ExecOnCommand, ExecOnConnect, ExecOnExit, ExecOnRestart


ExecOnExit

Syntax: ExecOnExit path [arg1 arg2 ...]
Default: None
Context: "server config" <VirtualHost>, <Global>, <Anonymous>, <Directory>
Module: mod_exec
Compatibility: 1.2.8 and later

The ExecOnExit directive is used to execute the program or script at path whenever a client disconnects to the server. The program will be executed with the privileges of the contacted server, which are set via the User/Group directives.

Any number of arbitrary arguments may be configured to pass to the script. In addition, the "cookies" supported by the ExecEnviron directive may also be used in the script argument list.

Example:

  ExecOnExit /path/to/ftp-logger --ip %a --dns %h

See Also: ExecBeforeCommand, ExecEnviron, ExecOnCommand, ExecOnConnect, ExecOnError, ExecOnRestart


ExecOnRestart

Syntax: ExecOnRestart path [arg1 arg2 ...]
Default: None
Context: "server config" <VirtualHost>, <Global>, <Anonymous>, <Directory>
Module: mod_exec
Compatibility: 1.2.5rc2 and later

The ExecOnRestart directive is used to execute the program or script at path whenever the server receives a SIGHUP signal. The program will be executed with the privileges of the contacted server, which are set via the User/Group directives.

Any number of arbitrary arguments may be configured to pass to the script. In addition, the "cookies" supported by the ExecEnviron directive may also be used in the script argument list.

Example:

  ExecOnRestart /path/to/ftp-counter-reset
See Also: ExecBeforeCommand, ExecEnviron, ExecOnCommand, ExecOnConnect, ExecOnError, ExecOnExit


ExecOptions

Syntax: ExecOptions opt1 ...
Default: None
Context: "server config" <VirtualHost>, <Global>
Module: mod_exec
Compatibility: 1.2.9rc2 and later

The ExecOptions directive is used to configure various optional behavior of mod_exec.

Example:

  ExecOptions logStderr sendStdout

The currently implemented options are:

  • logStderr

    When executing commands, mod_exec usually ignore any stderr output of the command. If this option is enabled, mod_exec will monitor for and log any stderr from the executed command to the ExecLog.

  • logStdout

    When executing commands, mod_exec usually ignore any stdout output of the command. If this option is enabled, mod_exec will monitor for and log any stdout from the executed command to the ExecLog.

  • sendStdout

    If this option is enabled, mod_exec will attempt to send any stdout output from the executed command to the connected client. Note that this only works for commands that are executed via ExecOnCommand or ExecOnConnect.

    Note this this option should not be used for SSH2/SFTP/SCP sessions, as it will only cause connection problems for SSH2/SFTP/SCP clients.

  • useStdin

    If this option is enabled, mod_exec will not send arguments to the command being executed using the command line; instead, those arguments will written to the stdin stream. Each command-line argument will be written as a newline-terminated string to stdin; the end of arguments is indicated by writing the period ('.') character on a line by itself (again, terminated with a newline).

    For example, a Perl script reading its arguments from stdin would use something like:

        while (my $line = <STDIN>) {
          chomp($line);
    
          if ($line eq ".") {
            last;
          }
    
          # Handle $line appropriately here
        }
    
    The advantange of using this useStdin option is that some systems have tools (e.g. ps) which will show the command-line arguments to commands being executed. For the security conscious, using stdin to pass arguments is less visible to other users of the system.


ExecTimeout

Syntax: ExecTimeout seconds
Default: None
Context: "server config" <VirtualHost>, <Global>
Module: mod_exec
Compatibility: 1.2.9rc2 and later

The ExecTimeout directive is used to set a limit on how long the executed commands can run. Processes that exceed the configured timeout will first be sent SIGTERM, to allow them to cleanly shutdown. If the process is still around, it will then be sent SIGKILL, which cannot be ignored. A value of zero configures an infinite timeout (not recommended).


Usage

Example configuration:
  <IfModule mod_exec.c>
    ExecEngine on
    ExecLog /var/log/ftpd/exec.log
    ExecOnConnect /path/to/script
  </IfModule>

This module will not work properly for <Anonymous> logins, or for logins that are affected by DefaultRoot. These directives use the chroot(2) system call, which wreaks havoc when it comes to scripts. The path to script/shell interpreters often assume a certain location that is no longer valid within a chroot. In addition, most modern operating systems use dynamically loaded libraries (.so libraries) for many binaries, including script/shell interpreters. The location of these libraries, when they come to be loaded, are also assumed; those assumptions break within a chroot. Perl, in particular, is so wrought with filesystem location assumptions that it's almost impossible to get a Perl script to work within a chroot, short of installing Perl itself into the chroot environment.

In short, this module is probably not what you want. And, try as I might, I cannot convince users that this module is not what they want. Therefore, I'll let you try to use this module yourself, and you can prove to yourself that it probably won't do what you want.

As an alternative to mod_exec for executing arbitrary scripts/commands based on FTP command issued, file uploaded/downloaded, etc, I recommend using a logging FIFO-based approach, similar to what is illustrated here. This approach allows for any script you wish, and is not subject to the restrictions of a chroot, meaning that you can use DefaultRoot and still have arbitrary scripts executed. If requested, I can provide help in writing a FIFO reader to execute the necessary scripts.


Installation

To install mod_exec, copy the mod_exec.c file into
  proftpd-dir/contrib/
after unpacking the latest proftpd-1.3.x source code. Then follow the usual steps for using third-party modules in proftpd:
  ./configure --with-modules=mod_exec
  make
  make install

Alternatively, if your proftpd was compiled with DSO support, you can use the prxs tool to build mod_exec as a shared module:

  prxs -c -i -d mod_exec.c

Frequently Asked Questions
Question: Why do %U/%u not work properly with ExecOnConnect?
Answer: Both %U and %u will be empty on ExecOnConnect because, at that point, the client has done a TCP connect to the server, but has not sent any sort of information (including user name). Which means that mod_exec does not have a user name to use at connect time.

One way to work around this limitation is to use a different trigger, e.g.:

  ExecOnCommand PASS ...
By the time the client sends the USER and PASS commands, the server will have the necessary user information to populate the %U/%u variables.



Author: $Author: castaglia $
Last Updated: $Date: 2011/09/02 17:23:12 $


© Copyright 2000-2011 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_deflate.html0000644000175000017500000001440411345740512022110 0ustar frankiefrankie ProFTPD module mod_deflate

ProFTPD module mod_deflate



The mod_deflate module is designed to provide support for MODE Z commands, which allows FTP clients and servers to compress data for transfer.

This module is contained in the mod_deflate.c file for ProFTPD 1.3.x, and is not compiled by default. Installation instructions are discussed here. Detailed documentation on mod_deflate usage can be found here.

The most current version of mod_deflate can be found at:

  http://www.castaglia.org/proftpd/

Author

Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.

Directives


DeflateEngine

Syntax: DeflateEngine on|off
Default: off
Context: server config, <VirtualHost>, <Global>
Module: mod_deflate
Compatibility: 1.3.0rc1 and later

The DeflateEngine directive enables or disables the mod_deflate compression functionality. If set to on, then mod_deflate will advertise support for MODE Z compression via the FEAT command, and handle MODE Z requests appropriately.


DeflateLog

Syntax: DeflateLog path|"none"
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_deflate
Compatibility: 1.3.0rc1 and later

The DeflateLog directive is used to a specify a log file for mod_deflate reporting and debugging. The path parameter must be the full path to the file to use for logging. Note that this path must not be to a world-writable directory and, unless AllowLogSymlinks is explicitly set to on (generally a bad idea), the path must not be a symbolic link.

If path is "none", no logging will be done at all.


Installation

To install mod_deflate, copy the mod_deflate.c file into:
  proftpd-dir/contrib/
after unpacking the latest proftpd-1.3.x source code. Then follow the usual steps for using third-party modules in proftpd:
  ./configure --with-modules=mod_deflate
  make
  make install


Usage

Example mod_deflate configuration:

  <IfModule mod_deflate.c>
    DeflateEngine on
    DeflateLog /var/log/proftpd/deflate.log
  </IfModule>

Sites that run proftpd 1.3.0 should disable sendfile use when using mod_deflate, as the two features do not interoperate well:

  <IfModule mod_deflate.c>
    DeflateEngine on
    DeflateLog /var/log/proftpd/deflate.log

    UseSendfile off
  </IfModule>

Frequently Asked Questions

Question: I have compiled and configured mod_deflate properly in my proftpd, but I still can't use the MODE Z functionality. In my client, I see the following error. Why?

  501 'MODE Z' unrecognized transfer mode
Answer: The most likely culprit is that your FTP client is using an RFC 2228 protection mechanism (e.g. SSL/TLS). In the DeflateLog, you might see a message like:
  Jul 21 23:01:37 mod_deflate/0.3.2[31084]: declining MODE Z (RFC2228 mechanism 'TLS' in effect)

There are two reasons for the current behavior. First, the SSL/TLS ciphersuite that is negotiated can (depending on the ciphersuite) already include compression of the encrypted data -- in which case, MODE Z is redundant (and in effect inefficient, as it would waste CPU cycles trying to re-compress already-compressed data). Second, the internal ProFTPD APIs that mod_deflate uses are the same APIs that mod_tls uses; and that API does not currently handle chaining together of registered handlers. This would be needed in order to support mod_deflate's MODE Z functionality and the mod_tls encryption at the same time.

Question: I'm uploading a file using MODE Z, but the upload always fails. In the DeflateLog, I see:

 error inflating data: [-3] Data error
What is going wrong? It is a mod_deflate bug?
Answer: The most common cause of this error is when the client is trying to upload a binary file (e.g. PDF, MPG, etc) in
ASCII mode.

If MODE Z is not used in cases like this, the upload succeeds, but the uploaded file on the server is corrupted. When MODE Z is in effect, the corruption (translation of newlines inappropriately) is detected earlier (since mod_deflate can't uncompress the compressed data properly, hence the report of a "Data error"), and the upload fails.

The solution is make sure that the client uploads (and downloads) non-ASCII files as binary files, not as ASCII files.



Author: $Author: castaglia $
Last Updated: $Date: 2010/03/10 15:56:58 $


© Copyright 2006-2010 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_tls.html0000644000175000017500000020205312115700244021277 0ustar frankiefrankie ProFTPD module mod_tls

ProFTPD module mod_tls



This module is contained in the mod_tls.c file for ProFTPD 1.3.x, and is not compiled by default. Installation instructions are discussed here.

The most current version of mod_tls is distributed with the ProFTPD source code.

This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/).

This product includes cryptographic software written by Eric Young (eay@cryptsoft.com).

Author

Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.

Thanks

2002-09-01: Thanks to Peter 'Luna' Runestig <peter at runestig.com> for his original mod_tls, upon which this version is based. His module can be found here:

  ftp://ftp.runestig.com/pub/proftpd-tls/

Directives

Control Actions


TLSCACertificateFile

Syntax: TLSCACertificateFile file
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_tls
Compatibility: 1.2.7rc1 and later

The TLSCACertificateFile directive configures one file where you can assemble the certificates of Certification Authorities (CA) for your clients. The CA certificates in the file are then used to verify client certificates, if presented. Such a file is merely the concatenation of the various PEM-encoded CA certificates, in order of preference. This directive can be used in addition to, or as an alternative for, TLSCACertificatePath.

Example:

  TLSCACertificateFile /etc/ftpd/ca-bundle.pem

If neither TLSCACertificateFile nor TLSCACertificatePath are specified, the following message will appear in the TLSLog:

   using default OpenSSL verification locations (see $SSL_CERT_DIR)
This means that the SSL_CERT_DIR environment variable, if set, will be used to determine the location of a CA certificate directory, to be used when verifying clients. Note, though, that this directive is only meaningful if TLSVerifyClient is set to on; otherwise, no client verification occurs.

See also: TLSCACertificatePath


TLSCACertificatePath

Syntax: TLSCACertificatePath directory
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_tls
Compatibility: 1.2.7rc1 and later

The TLSCACertificatePath directive sets the directory for the certificates of Certification Authorities (CAs) for your clients. These are used to verify the client certificates presented. This directive may be used in addition to, or as alternative for, TLSCACertificateFile.

The files in the configured directory have to be PEM-encoded, and are accessed through hash filenames. This means one cannot simply place the CA certificates there: one also has to create symbolic links named hash-value.N. The c_rehash utility that comes with OpenSSL can be used to create the necessary symlinks.

Example:

  TLSCACertificatePath /etc/ftpd/ca/

If neither TLSCACertificateFile nor TLSCACertificatePath are specified, the following message will appear in the TLSLog:

   using default OpenSSL verification locations (see $SSL_CERT_DIR)
This means that the SSL_CERT_DIR environment variable, if set, will be used to determine the location of a CA certificate directory, to be used when verifying clients.

See also: TLSCACertificateFile


TLSCARevocationFile

Syntax: TLSCARevocationFile file
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_tls
Compatibility: 1.2.7rc1 and later

The TLSCARevocationFile directive configures one file that can contain the Certificate Revocation Lists (CRL) of Certification Authorities (CA) for your clients. These CRLs are used during the verification of client certificates, if presented. Such a file is merely the concatenation of the various PEM-encoded CRL files, in order of preference. This directive can be used in addition to, or as an alternative for, TLSCARevocationPath.

Example:

  TLSCARevocationFile /etc/ftpd/ca-crl-bundle.pem

See also: TLSCARevocationPath


TLSCARevocationPath

Syntax: TLSCARevocationPath directory
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_tls
Compatibility: 1.2.7rc1 and later

The TLSCARevocationPath directive sets the directory for the Certificate Revocation Lists (CRL) of Certification Authorities (CAs) for your clients. These are used during the verification of client certificates, if presented. This directive may be used in addition to, or as alternative for, TLSCARevocationFile.

The files in the configured directory have to be PEM-encoded, and are accessed through hash filenames. This means one cannot simply place the CRLs there: one also has to create symbolic links named hash-value.N. The c_rehash utility that comes with OpenSSL can be used to create the necessary symlinks.

Example:

  TLSCARevocationPath /etc/ftpd/crl/

See also: TLSCARevocationFile


TLSCertificateChainFile

Syntax: TLSCertificateChainFile file
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_tls
Compatibility: 1.2.7rc1 and later

The TLSCertificateChainFile directive sets the optional all-in-one file where you can assemble the certificates of Certification Authorities (CA) which form the certificate chain of the server certificate. This starts with the issuing CA certificate of the server certificate and can range up to the root CA certificate. Such a file is simply the concatenation of the various PEM-encoded CA Certificate files in certificate chain order. (Certificate chain order means that the list must be sorted starting with the subject's certificate (actual server certificate), followed by intermediate CA certificates if applicable, and ending at the highest level root CA.) This server certificate chain is sent to the client, in addition to the server's certificate.

If TLSCertificateChainFile is not used, and TLSCACertificatePath is used, the certificate chain is built from the certificates in that path. TLSCertificateChainFile should be used as an alternative to TLSCACertificatePath for explicitly constructing the server certificate chain. It is especially useful to avoid conflicts with CA certificates when using client authentication. For although placing a CA certificate of the server certificate chain into the TLSCACertificatePath has the same effect for the certificate chain construction, it has the side-effect that client certificates issued by this same CA certificate are also accepted on client authentication. This is usually not what one expects.

Be careful: providing the certificate chain works only if you are using a single (either RSA or DSA) based server certificate. If you are using a coupled RSA+DSA certificate pair, this will work only if actually both certificates use the same certificate chain. Otherwise, clients will become confused.

Example:

  TLSCertificateChainFile /etc/ftpd/client-ca-list.pem

Note: If you use the NoCertRequest TLSOption, then any configured TLSCertificateChainFile directive will be ignored. It is a waste of time to construct a certificate chain to send to the client if the server does not request that the client send a certificate to be verified.


TLSCipherSuite

Syntax: TLSCipherSuite cipher-list
Default: DEFAULT:!EXPORT:!DES
Context: server config, <VirtualHost>, <Global>
Module: mod_tls
Compatibility: 1.2.7rc1 and later

Default cipher list is "DEFAULT:!EXPORT:!DES".

How to put together a cipher list parameter:

  Key Exchange Algorithms:
    "kRSA"      RSA key exchange
    "kDHr"      Diffie-Hellman key exchange (key from RSA cert)
    "kDHd"      Diffie-Hellman key exchange (key from DSA cert)
    "kEDH'      Ephemeral Diffie-Hellman key exchange (temporary key)

  Authentication Algorithm:
    "aNULL"     No authentication
    "aRSA"      RSA authentication
    "aDSS"      DSS authentication
    "aDH"       Diffie-Hellman authentication

  Cipher Encoding Algorithm:
    "eNULL"     No encodiing
    "DES"       DES encoding
    "3DES"      Triple DES encoding
    "RC4"       RC4 encoding
    "RC2"       RC2 encoding
    "IDEA"      IDEA encoding

  MAC Digest Algorithm:
    "MD5"       MD5 hash function
    "SHA1"      SHA1 hash function
    "SHA"       SHA hash function (should not be used)

  Aliases:
    "ALL"       all ciphers
    "SSLv2"     all SSL version 2.0 ciphers (should not be used)
    "SSLv3"     all SSL version 3.0 ciphers
    "EXP"       all export ciphers (40-bit)
    "EXPORT56"  all export ciphers (56-bit)
    "LOW"       all low strength ciphers (no export)
    "MEDIUM"    all ciphers with 128-bit encryption
    "HIGH"      all ciphers using greater than 128-bit encryption
    "RSA"       all ciphers using RSA key exchange
    "DH"        all ciphers using Diffie-Hellman key exchange
    "EDH"       all ciphers using Ephemeral Diffie-Hellman key exchange
    "ADH"       all ciphers using Anonymous Diffie-Hellman key exchange
    "DSS"       all ciphers using DSS authentication
    "NULL"      all ciphers using no encryption

Each item in the list may include a prefix modifier:

    "+"         move cipher(s) to the current location in the list
    "-"         remove cipher(s) from the list (may be added again by a
                subsequent list entry)
    "!"         kill cipher from the list (it may not be added again by a
                subsequent list entry)

If no modifier is specified the entry is added to the list at the current position. "+" may also be used to combine tags to specify entries such as "RSA+RC4" describes all ciphers that use both RSA and RC4.

For example, all available ciphers not including ADH key exchange:

  ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP

All algorithms including ADH and export but excluding patented algorithms:

  HIGH:MEDIUM:LOW:EXPORT56:EXP:ADH:!kRSA:!aRSA:!RC4:!RC2:!IDEA

The OpenSSL command

  openssl ciphers -v <list of ciphers>
may be used to list all of the ciphers and the order described by a specific <list of ciphers>.


TLSControlsACLs

Syntax: TLSControlsACLs actions|"all" "allow"|"deny" "user"|"group" list
Default: None
Context: server config
Module: mod_tls
Compatibility: 1.3.3rc1 and later

The TLSControlsACLs directive configures access lists of users or groups who are allowed (or denied) the ability to use the actions implemented by mod_tls. The default behavior is to deny everyone unless an ACL allowing access has been explicitly configured.

If "allow" is used, then list, a comma-delimited list of users or groups, can use the given actions; all others are denied. If "deny" is used, then the list of users or groups cannot use actions all others are allowed. Multiple TLSControlsACLs directives may be used to configure ACLs for different control actions, and for both users and groups.

The actions provided by mod_tls are "sesscache clear" , "sesscache info", and "sesscache remove".

Examples:

  # Allow only user root to examine/update the external SSL session cache
  TLSControlsACLs all allow user root


TLSCryptoDevice

Syntax: TLSCryptoDevice driver|"all"|"none"
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_tls
Compatibility: 1.3.1rc1 and later

The TLSCryptoDevice directive is used to configure mod_tls to use an OpenSSL "engine", a cryptographic module that OpenSSL library can use for accelerated cryptographic support, or HSM keys, etc.

To use all of the engines compiled into OpenSSL, use:

  TLSCryptoDevice all
OpenSSL will find, from the list of supported engines, the first one usable, if any. If no usable engines are found, OpenSSL will default to its normal software implementation. If a specific engine is desired as the default engine to use, specify the engine name, e.g.:
  TLSCryptoDevice chil

The OpenSSL command

  openssl engine
may be used to list all of the engine drivers supported by OpenSSL.


TLSDHParamFile

Syntax: TLSDHParamFile file
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_tls
Compatibility: 1.2.7rc1 and later

The TLSDHParamFile directive is used to configure a file that contains pre-computed Diffie-Hellman (DH) group parameters. The mod_tls module will use these parameters when engaging in Diffie-Hellman key exchanges.

Such key exchanges can be computationally intensive, in terms for parameter generation. To help speed up the process and avoid latency for Diffie-Hellman key exchanges, the DH group parameters used may be generated in advance, and stored in a TLSDHParamFile. The dhparam utility that comes with OpenSSL may be used to generate an appropriate file for this directive:

  # openssl dhparam -outform PEM -2 nbits >> dhparams.pem
  # openssl dhparam -outform PEM -5 nbits >> dhparams.pem
Using either -2 or -5 as the generator is fine. The nbits value used
should vary between 512 and 4096, inclusive.

The file parameter must be an absolute path.


TLSDSACertficateFile

Syntax: TLSDSACertificateFile file
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_tls
Compatibility: 1.2.7rc1 and later

The TLSDSACertificateFile directive points to the PEM-encoded file containing the DSA certificate file for the server and optionally also the corresponding DSA private key file.

If the contained private key is encrypted, the administrator will be prompted for the passphrase when the daemon starts up, and when the daemon is restarted. Alternatively, the TLSPassPhraseProvider directive can be used to supply a source for that passphrase.

Example:

  TLSDSACertificateFile /etc/ftpd/server-dsa-cert.pem


TLSDSACertificateKeyFile

Syntax: TLSDSACertificateKeyFile file
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_tls
Compatibility: 1.2.7rc1 and later

The TLSDSACertificateKeyFile directive points to the PEM-encoded private key file for the server. If the private key is not combined with the certificate in the TLSDSACertificateFile, use this additional directive to point to the file with the standalone private key. When TLSDSACertificateFile is used and the file contains both the certificate and the private key, this directive need not be used. However, this practice is strongly discouraged. Instead we recommend you to separate the certificate and the private key.

If the contained private key is encrypted, the administrator will be prompted for the passphrase when the daemon starts up, and when the daemon is restarted.

Example:

  TLSDSACertificateKeyFile /etc/ftpd/server-dsa-key.pem


TLSEngine

Syntax: TLSEngine on|off
Default: off
Context: server config, <VirtualHost>, <Global>
Module: mod_tls
Compatibility: 1.2.7rc1 and later

The TLSEngine directive toggles the use of the SSL/TLS protocol engine (e.g. mod_tls). This is usually used inside a <VirtualHost> section to enable SSL/TLS sessions for a particular virtual host. By default mod_tls is disabled for both the main server and all configured virtual hosts.


TLSLog

Syntax: TLSLog file
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_tls
Compatibility: 1.2.7rc1 and later

The TLSLog directive is used to specify a log file for mod_tls's reporting on a per-server basis. The file parameter given must be the full path to the file to use for logging.

Note that this path must not be to a world-writable directory and, unless AllowLogSymlinks is explicitly set to on (generally a bad idea), the path must not be a symbolic link.


TLSMasqueradeAddress

Syntax: TLSMasqueradeAddress ip-address|dns-name|device-name
Default: None
Context: server config, <VirtualHost>
Module: mod_tls
Compatibility: 1.3.5rc2 and later

The TLSMasqueradeAddress directive functions exactly like the MasqueradeAddress, except that it applies only to FTPS sessions. (Note that if both MasqueradeAddress and TLSMasqueradeAddress are configured, then the TLSMasqueradeAddress directive will take precedence, but only for FTPS sessions.)

Discussion
Why is something like TLSMasqueradeAddress needed? There are cases where some sites run proftpd within a restricted VLAN/DMZ, with some sort of firewall/proxy/router device which handles FTP and FTPS connections from the Internet to that proftpd server:

  client <---> firewall <---> load balancer <---> server
In many cases, the firewall/proxy/router device will look at the FTP responses for the PASV/EPSV commands (in which proftpd may be sending its internal, non-public IP address), and rewrite the responses to have the IP address of the firewall/proxy/router device.

Normally, the MasqueradeAddress directive can be used for such cases, so that proftpd sends the configured address in the PASV/EPSV responses. With that configuration, the firewall/proxy/router device will not need to rewrite the responses. And this approach works for FTPS sessions as well, where the firewall/proxy/router device cannot rewrite the response due to the SSL/TLS protection.

Sometimes, though, sites want their firewall/proxy/router device to be able to properly rewrite FTP responses. But due to bugs/implementation details in the firewall/proxy/router devices, if a PASV/EPSV response contains a public IP address, the device will drop/break that FTP connection.

This leaves the site in a case where it does not want to use MasqueradeAddress (so that the device can properly rewrite FTP responses), which works -- but only for plain FTP sessions. Yet the site does want to use MasqueradeAddress -- but only for FTPS sessions, since the device cannot rewrite FTPS responses.

For these situations, then, the TLSMasqueradeAddress directive can/should be used: it provides MasqueradeAddress functionality, but only for FTPS sessions.


TLSOptions

Syntax: TLSOptions opt1 ...
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_tls
Compatibility: 1.2.7rc1 and later

The TLSOptions directive is used to configure various optional behavior of mod_tls. Note: all of the configured TLSOptions parameters must appear on the same line in the configuration; only the first TLSOptions directive that appears in the configuration is used.

Example:

  TLSOptions iPAddressRequired StdEnvVars NoSessionReuseRequired

The currently implemented options are:

  • AllowClientRenegotiations

    The mod_tls will reject any SSL/TLS session renegotiation attempts by the client, in order to mitigate any issues arising from the SSL/TLS session renegotiation vulnerability (CVE-2009-3555) or SSL/TLS session renegotiation DoS (CVE-2011-1473). If, however, your particular site or clients absolutely require support for client-initiated SSL/TLS session renegotiations, then this option can be used. Not recommended.

    Note, however, that SSL/TLS session renegotiation requests that are initiated by mod_tls, via the TLSRenegotiate directive, are still handled (depending on the OpenSSL version).

  • AllowDotLogin

    By default, mod_tls still requires that a user supply a password for authentication, even if a valid client certificate is presented. If this option is enabled, mod_tls will check in the user's home directory for a .tlslogin file, which should contain one or more PEM-encoded certificates. If the certificate presented by the client, if any, matches a certificate in this .tlslogin file, the user will be considered authenticated and the server will not prompt for a password. If the user's .tlslogin does not exist, or does not contain the client's certificate, then the server will fallback to requesting a password for authentication.

  • AllowPerUser

    This option affects how mod_tls evaluates any TLSRequired directives. Usually mod_tls will reject any FTP commands, when TLSRequired on or TLSRequired ctrl is in effect, if the client has not successfully negotiated a SSL/TLS handshake. The FTPS specification requires that the SSL/TLS handshake occur, via the AUTH FTP command, before the USER and PASS commands. This means that mod_tls does not know the identity of the connecting client when enforcing TLSRequired. If this AllowPerUser is used, mod_tls will wait until after the PASS command has been processed to enforce any TLSRequired settings.

    Important: if AllowPerUser is used, even if TLSRequired on or TLSRequired ctrl are in effect, it will be possible for the connecting client to send usernames and password unprotected before mod_tls rejects the connection. This results in a slightly weaker security policy enforcement; please consider carefully if this tradeoff is acceptable for your site.

    However, TLSRequired auth and TLSRequired auth+data configurations will override the AllowPerUser option.

  • CommonNameRequired

    This option will cause mod_tls to perform checks on a client's certificate once the SSL handshake has been completed: the client's certificate will be searched for the CommonName (CN) X509v3 value. Unless a CommonName value is present, and the value matches the DNS name to which the client's IP address resolves, the SSL session is closed. This check is only performed during SSL handshakes on the control channel. Note that if UseReverseDNS is off, this option is automatically disabled.

  • EnableDiags
    Sets callbacks in the OpenSSL library such that a lot of SSL/TLS protcol information is logged to the TLSLog file. This option is very useful when debugging strange interactions with FTPS clients.

  • ExportCertData

    Sets the following environment variables, if applicable. Note that doing so increases the memory size of the process quite a bit:
    TLS_SERVER_CERT Server certificate, PEM-encoded
    TLS_CLIENT_CERT Client certificate, PEM-encoded
    TLS_CLIENT_CERT_CHAINn PEM-encoded certificates in client certificate chain

  • NoCertRequest

    Some FTP clients are known to be buggy when handling a server's certificate request. This option causes the server to not send such a request during an SSL handshake.

  • NoEmptyFragments

    In order to prevent certain attacks (e.g. the so-called "BEAST" attack), the mod_tls module was changed to use OpenSSL's builtin countermeasure of inserting empty fragments. However, some browsers/clients may not handle such empty fragments well. Use this NoEmptyFragaments TLSOption in order to interoperate with such clients, with risk of losing the protective countermeasure.

    Note that this protective countermeasure only applies to SSLv3 and TLSv1 sessions; it does not affect TLSv1.1 or TLSv1.2 sessions.

    Added in ProFTPD 1.3.4rc4.

  • NoSessionReuseRequired

    As of ProFTPD 1.3.3rc1, mod_tls only accepts SSL/TLS data connections that reuse the SSL session of the control connection, as a security measure. Unfortunately, there are some clients (e.g. curl) which do not reuse SSL sessions.

    To relax the requirement that the SSL session from the control connection be reused for data connections, use the following in the proftpd.conf:

        <IfModule mod_tls.c>
          ...
          TLSOptions NoSessionReuseRequired
          ...
        </IfModule>
    

  • StdEnvVars

    Sets the following environment variables, if applicable. These environment variables are then avaiable for use, such as in LogFormats. Note that doing so may increase the memory size of the process quite a bit:
    FTPS Present if FTP over SSL/TLS is being used
    TLS_PROTOCOL SSL protocol version (e.g. SSLv3, TLSv1)
    TLS_SESSION_ID Hex-encoded SSL session ID
    TLS_CIPHER Cipher specification name
    TLS_CIPHER_EXPORT Present if cipher is an export cipher
    TLS_CIPHER_KEYSIZE_POSSIBLE Number of cipher bits possible
    TLS_CIPHER_KEYSIZE_USED Number of cipher bits used
    TLS_LIBRARY_VERSION OpenSSL version
    TLS_CLIENT_M_VERSION Client certificate version
    TLS_CLIENT_M_SERIAL Client certificate serial number
    TLS_CLIENT_S_DN Subject DN of client certificate
    TLS_CLIENT_S_DN_x509 Component of client certificate's Subject DN, where x509 is a component of a X509 DN:
    C,CN,D,I,G,L,O,OU,S,ST,T,UID,Email
    TLS_CLIENT_I_DN Issuer DN of client certificate
    TLS_CLIENT_I_DN_x509 Component of client certificate's Issuer DN, where x509 is a component of a X509 DN:
    C,CN,D,I,G,L,O,OU,S,ST,T,UID,Email
    TLS_CLIENT_V_START Start time of client certificate validity
    TLS_CLIENT_V_END End time of client certificate validity
    TLS_CLIENT_A_SIG Client certificate's signature algorithm
    TLS_CLIENT_A_KEY Client certificate's public key algorithm
    TLS_CLIENT_CERT Client certificate, PEM-encoded
    TLS_CLIENT_CERT_CHAINn PEM-encoded certificates in client certificate chain
    TLS_SERVER_M_VERSION Server certificate version
    TLS_SERVER_M_SERIAL Server certificate serial number
    TLS_SERVER_S_DN Subject DN of server certificate
    TLS_SERVER_S_DN_x509 Component of server certificate's Subject DN, where x509 is a component of a X509 DN:
    C,CN,D,I,G,L,O,OU,S,ST,T,UID,Email
    TLS_SERVER_I_DN Issuer DN of server certificate
    TLS_SERVER_I_DN_x509 Component of server certificate's Issuer DN, where x509 is a component of a X509 DN:
    C,CN,D,I,G,L,O,OU,S,ST,T,UID,Email
    TLS_SERVER_V_START Start time of server certificate validity
    TLS_SERVER_V_END End time of server certificate validity
    TLS_SERVER_A_SIG Server certificate's signature algorithm
    TLS_SERVER_A_KEY Server certificate's public key algorithm
    TLS_SERVER_CERT Server certificate, PEM-encoded

  • UseImplicitSSL

    This option will cause the mod_tls module to handle all connections as if they are SSL connections implicitly; the client does not need to send the AUTH TLS FTP command. This can cause issues for FTPS clients which are expecting explicit FTPS, not implicit FTPS.

    Thus if the UseImplicitSSL option is used, you will want to have a separate <VirtualHost> section with a different port number just for those clients which require/expect implicit FTPS. For example:

        <IfModule mod_tls.c>
          <VirtualHost a.b.c.d>
            TLSEngine on
            TLSOptions UseImplicitSSL
    
            # The "standard" implicit FTPS port is 990
            Port 990
            ...
          </VirtualHost>
        </IfModule>
    

  • dNSNameRequired

    This option will cause mod_tls to perform checks on a client's certificate once the SSL handshake has been completed: the client's certificate will be searched for the subjectAltName X509v3 extension, and, in that extension, the dNSName value will be looked up. Unless a dNSName value is present, and the value matches the DNS name to which the client's IP address resolves, the SSL session is closed. This check is only performed during SSL handshakes on the control channel. Note that if UseReverseDNS is off, this option is automatically disabled.

  • iPAddressRequired

    This option will cause mod_tls to perform checks on a client's certificate once the SSL handshake has been completed: the client's certificate will be searched for the subjectAltName X509v3 extension, and, in that extension, the iPAddress value will be looked up. Unless an iPAddress value is present, and the value matches the IP address of the client, the SSL session is closed. This check is only performed during SSL handshakes on the control channel.


TLSPKCS12File

Syntax: TLSPKCS12File file
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_tls
Compatibility: 1.3.3rc1 and later

The TLSPKCS12ile directive points to the PKCS#12 file containing the certificate file and its private key for the server.

If the PKCS#12 file is protected with a passphrase, the administrator will be prompted for the passphrase when the daemon starts up, and when the daemon is restarted. Alternatively, the TLSPassPhraseProvider directive can be used to supply a source for that passphrase.

Example:

  TLSPKCS12File /etc/ftpd/server-cert.p12


TLSPassPhraseProvider

Syntax: TLSPassPhraseProvider path
Default: None
Context: server config
Module: mod_tls
Compatibility: 1.3.1rc1 and later

The TLSPassPhraseProvider directive is used to specify an external program which will be called, when mod_tls starts up, for each encrypted certificate key file. The program will be invoked with two command-line arguments, passed on stdin to the program:

  servername:portnumber "RSA"|"DSA"
where servername:portnumber indicates the server using that encrypted certificate key, and "RSA" or "DSA" indicates the private key algorithm used for that key. The program then must print the corresponding passphrase for the key to stdout.

The intent is that this external program can perform any security checks necessary, to make sure that the system is not compromised by an attacker, and only when these checks pass successfully will the passphrase be provided. These security checks, and the way the passphrase is determined, can be as complex as you like.

Example:

  TLSPassPhraseProvider /etc/ftpd/tls/get-passphrase


TLSProtocol

Syntax: TLSProtocol protocol1 ... protocolN
Default: SSLv3 TLSv1
Context: server config, <VirtualHost>, <Global>
Module: mod_tls
Compatibility: 1.2.7rc1 and later

The TLSProtocol directive is used to configure the SSL/TLS protocol versions that mod_tls should use when establishing SSL/TLS sessions. Clients can then only connect using the configured protocol.

Since the protocol version used by mod_tls is set only once, when the daemon starts, the TLSProtocol directive is only allowed in the "server config" context.

The allowed protocols are:

SSLv3 Allow only SSLv3
TLSv1 Allow only TLSv1
TLSv1.1 Allow only TLSv1.1
TLSv1.2 Allow only TLSv1.2
To support both SSLv3 and TLSv1, simply list both parameters for the TLSProtocol directive, e.g.:

  TLSProtocol SSLv3 TLSv1

Note that the parameter "SSLv23" is supported as a legacy style for saying "all versions".

All use of SSLv2 is disabled. SSLv2 should not be used.


TLSRandomSeed

Syntax: TLSRandomSeed seed
Default: openssl-dir/.rnd
Context: server config, <VirtualHost>, <Global>
Module: mod_tls
Compatibility: 1.2.7rc1 and later

The TLSRandomSeed directive configures the file that mod_tls will use for seeding the PRNG. seed must be an absolute path.

When the daemon shuts down, any random data left will be written out to the random seed file, so that that data may be used for seeding when the daemon is started again.

Example:

  TLSRandomSeed /etc/ftpd/server.rnd

Note that the TLSRandomSeed directive is not used to seed the entropy required by the OpenSSL library; that configuration is OpenSSL-specific. Instead, the TLSRandomSeed file can be thought of a cache file for the unused entropy, to be used to help speed up entropy gathering when the daemon starts up again.


TLSRenegotiate

Syntax: TLSRenegotiate ["ctrl" secs] ["data" Kbytes] ["timeout" secs]|["required" on|off]|"none"
Default: ctrl 14400 data 25165824 required true (for OpenSSL 0.9.7 or greater)
Context: server config, <VirtualHost>, <Global>
Module: mod_tls
Compatibility: 1.2.7rc1 and later

The TLSRenegotiate directive is used to configure when SSL renegotiations are to occur. Renegotiations, and thus this directive, are only supported by mod_tls if the version of OpenSSL installed is 0.9.7 or greater.

If supported, renegotiations will occur on control channels that have been established for four hours by default, and on data channels that have transferred over one gigabyte of data by default. When renegotiations are requested, the client is given a timeout of 30 seconds, by default, to perform the renegotiation. To change the default control channel renegotiation timeout, use ctrl followed by a number, greater than zero, in seconds. Use data followed by a number, greater than zero, of kilobytes to change the default data channel renegotiation threshhold. The timeout parameter, followed by a positive number of seconds, is used to change the length of time given to a client to complete a requested renegotiation, after which the SSL session will be shutdown. By default, mod_tls will require that the client comply with the requested renegotiation within the TLSRenegotiate timeout. If, however, the client is unwilling or unable to do so, and the daemon needs to support these clients, set required to off. Doing so will cause renegotiations to be requested, but not required.

By default, mod_tls will perform renegotiations if supported, on the control channel after 4 hours, and on the data channel after one gigabyte of transferred data. The default timeout for a renegotiation is 30 seconds.

Use none to disable all renegotiation requirements.

Examples:

    # Change renegotiations to occur on control channels after 1 hour
    TLSRenegotiate ctrl 3600

    # Change renegotiations to occur on data channels after 500 MB
    TLSRenegotiate data 512000

    # Change renegotiations so that they are not required, only requested
    TLSRenegotiate required off

    # Change only the timeout for renegotiations to be 5 minutes
    TLSRenegotiate timeout 300

    # Change all of the above renegotiation threshholds using one directive
    TLSRenegotiate ctrl 3600 data 512000 required off timeout 300

    # To disable renegotiations entirely
    TLSRenegotiate none


TLSRequired

Syntax: TLSRequired on|off|ctrl|[!]data|auth|auth+[!]data
Default: off
Context: server config, <VirtualHost>, <Global>, <Anonymous>
Module: mod_tls
Compatibility: 1.2.7rc1 and later

The TLSRequired directive is used to define a basic security policy, one that dictates whether the control channel, or data channel, or both, of an FTP session must occur over SSL/TLS.

The on parameter enables SSL/TLS requirements on both control and data channels; off disables the requirements on both channels. Use ctrl and data to require SSL/TLS on either channel individually.

Example:

  # Require SSL/TLS on the control channel, so that passwords are not sent
  # in the clear.
  TLSRequired ctrl

  # Require SSL/TLS on both channels.
  TLSRequired on
The auth parameter requires that SSL/TLS be used on the control channel, but only for authentication. To use this setting and require SSL/TLS for data transfers, use the auth+data parameter, e.g.:
  # Allow the client to use the CCC command to remove SSL/TLS from the
  # control channel, but only after authentication has been performed.
  # Still enforce the policy of using SSL/TLS for data transfers.
  #
  # Note that if we did not need to protect data transfers, we would
  # set 'TLSRequired auth' instead of using 'TLSRequired auth+data'.
  TLSRequired auth+data
This auth+data parameter allows a very specific security policy: authentication via the USER/PASS commands must be protected via SSL/TLS, as must the data channel, but after authenticating, the client can request that protection be removed from the control channel. This policy allows clients to use the CCC (Clear Command Channel) command, which in turn enables SSL/TLS protected data transfers that are operate better with firewalls that monitor the FTP control channel.

It is also possible to configure a policy which rejects use of SSL/TLS for protecting the data channel. Some sites may wish to use such a policy in order to protect the control channels of their clients, but to prevent the data transfers from consuming too much CPU. The TLSRequired directive can be set such that an FTPS client requesting protection of the data channel, using the PROT command, will have that command refused. To configure such a policy, use one of the following:

  # If the client wishes to protect the control channel, allow it; but reject
  # any attempt to protect the data channel
  TLSRequired !data

  # Require protection on the control channel, but reject protection of the
  # data channel
  TLSRequired ctrl+!data

  # Require protection on the control channel for authentication (but not
  # after), and reject protection of the data channel
  TLSRequired auth+!data


TLSRSACertificateFile

Syntax: TLSRSACertificateFile file
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_tls
Compatibility: 1.2.7rc1 and later

The TLSRSACertificateFile directive points to the PEM-encoded file containing the RSA certificate file for the server and optionally also the corresponding RSA private key file.

If the contained private key is encrypted, the administrator will be prompted for the passphrase when the daemon starts up, and when the daemon is restarted. Alternatively, the TLSPassPhraseProvider directive can be used to supply a source for that passphrase.

Example:

  TLSRSACertificateFile /etc/ftpd/server-rsa-cert.pem


TLSRSACertificateKeyFile

Syntax: TLSRSACertificateKeyFile file
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_tls
Compatibility: 1.2.7rc1 and later

The TLSRSACertificateKeyFile directive points to the PEM-encoded private key file for the server. If the private key is not combined with the certificate in the TLSRSACertificateFile, use this additional directive to point to the file with the standalone private key. When TLSRSACertificateFile is used and the file contains both the certificate and the private key, this directive need not be used. However, this practice is strongly discouraged. Instead we recommend you to separate the certificate and the private key.

If the contained private key is encrypted, the administrator will be prompted for the passphrase when the daemon starts up, and when the daemon is restarted.

Example:

  TLSRSACertificateKeyFile /etc/ftpd/server-rsa-key.pem


TLSServerCipherPreference

Syntax: TLSServerCipherPreference on|off
Default: Off
Context: server config, <VirtualHost>, <Global>
Module: mod_tls
Compatibility: 1.3.5rc1 and later

When choosing a cipher during an SSLv3 or TLSv1 handshake, normally the client's ciphersuite preference is used. If the TLSServerCipherPreference directive is enabled, then the server's ciphersuite preference will be used instead.

For example:

  TLSServerCipherPreference on


TLSSessionCache

Syntax: TLSSessionCache "off"|type:/info [timeout]
Default: None
Context: server config
Module: mod_tls
Compatibility: 1.3.3rc1 and later

The TLSSessionCache directive configures an external SSL session cache, which can be used for storing and shared SSL sessions across multiple processes. An external SSL session cache is an optional facility which speeds up parallel FTPS session connections.

Modern FTP clients often create multiple simultaneous connections to an FTP server, for downloading different chunks of data in parallel. Each FTP connection will be handled by a different server process, and each one will be required to perform a full SSL/TLS handshake. By using an external SSL session cache, a cached SSL session can be "resumed" by the client, which avoids the expensive portions of the handshake. FTPS clients which cache the SSL session locally can also attempt to resume that cached session at a later date; if the server still has that same session cached, the FTPS client can again avoid the expensive portions of the handshake and resume its previous SSL session.

If the TLSSessionCache directive is not used, then OpenSSL's default internal SSL session caching will be used. Thus multiple SSL sessions to the same server process (e.g. for FTP data transfers) will benefit from the speedup, but parallel simultaneous FTP connections from the same FTPS client will each need to perform the full SSL/TLS handshake. By default, OpenSSL caches SSL sessions for 300 seconds (5 minutes). If your FTP sessions last longer than this (e.g. for downloading large files), you may need to configure a longer cache lifetime using:

  # Configure OpenSSL's internal caching to be 1800 seconds (30 minutes)
  TLSSessionCache internal: 1800

The type and info parameters all depend on the module implementing the external SSL session cache being configured. For example, for using a shared memory external SSL session cache, see the mod_tls_shmcache documentation.

The optional timeout parameters sets the time-to-live, in seconds, for the SSL session datal stored in the external SSL session cache. It can be set as low as 15 for testing, but should be set to higher values like 600 in real life. The default timeout is 1800 seconds (30 minutes).

Use of SSL session caching can be disabled entirely by using:

  TLSSessionCache off


TLSTimeoutHandshake

Syntax: TLSTimeoutHandshake seconds
Default: 300
Context: server config, <VirtualHost>, <Global>
Module: mod_tls
Compatibility: 1.2.9rc1 and later

The TLSTimeoutHandshake directive configures the maximum number of seconds for mod_tls to accept an SSL/TLS handshake. If set to zero, mod_tls will wait forever for a handshake to complete. The default is 300 seconds (five minutes).


TLSUserName

Syntax: TLSUserName attribute
Default: off
Context: server config, <VirtualHost>, <Global>
Module: mod_tls
Compatibility: 1.3.5rc2 and later

The TLSUserName directive configures which attribute of a client certificate to match against the name provided by the FTPS client in its USER command. If the certificate attribute value matches the USER name, the user is considered to be authenticated without requiring that password be sent over the network.

The attribute can either be "CommonName" (to match the CN of the client certificate to the requested USER name), "EmailSubjAltName" (to match any Email Subject Alternative Names (SANs) to the requested USER name), or a custom OID.

Examples:

  # Match the CN
  TLSUserName CommonName 

  # Match any Email SANs
  TLSUserName EmailSubjAltName

  # Match specific (custom) OID
  TLSUserName 1.2.3.4.5 

Note that for the TLSUserName directive to be effective, mod_tls has to be configured to request that clients provide certificates, i.e.:

  # Verify clients
  TLSVerifyClient on

  # and possibly verify the user based on the client certs
  TLSUserName CommonName

See also: TLSVerifyClient


TLSVerifyClient

Syntax: TLSVerifyClient on|off
Default: off
Context: server config, <VirtualHost>, <Global>
Module: mod_tls
Compatibility: 1.2.7rc1 and later

The TLSVerifyClient directive configures how mod_tls handles certificates presented by clients. If off, the module will accept the certificate and establish an SSL/TLS session, but will not verify the certificate. If on, the module will verify a client's certificate and, furthermore, will fail all SSL handshake attempts unless the client presents a certificate when the server requests one. Note that the server can be configured to not request a client certificate via the TLSOptions directive's "NoCertRequest" parameter.

See also: TLSOptions


TLSVerifyDepth

Syntax: TLSVerifyDepth depth
Default: 9
Context: server config, <VirtualHost>, <Global>
Module: mod_tls
Compatibility: 1.2.7rc1 and later

The TLSVerifyDepth directive sets how deeply mod_tls should verify before deciding that the client does not have a valid certificate. The depth actually is the maximum number of intermediate certificate issuers, i.e. the number of CA certificates which are allowed to be followed while verifying the client certificate. A depth of 0 means that only self-signed client certificates are accepted, a depth of 1 means the client certificate can be self-signed or has to be signed by a CA which is directly known to the server (i.e. the CA's certificate is under TLSCACertificatePath), etc.

Example:

  TLSVerifyDepth 10


TLSVerifyOrder

Syntax: TLSVerifyOrder crl|ocsp
Default: crl
Context: server config, <VirtualHost>, <Global>
Module: mod_tls
Compatibility: 1.3.2rc1 and later

The TLSVerifyOrder directive configures how the mod_tls will verify the certificates presented by clients, if at all. Unless TLSVerifyClient is on, the TLSVerifyOrder directive is not needed.

By default, the mod_tls module will include any CRLs (Certificate Revocation List) that may have been configured via the TLSCARevocationFile and/or TLSCARevocationPath directives. This default behavior is the equivalent of configuring the TLSVerifyOrder to use CRLs, e.g.:

  TLSVerifyOrder crl

Another way of checking the validity of the client certificate is to use the Online Certificate Status Protocol (OCSP), defined in RFC 2560. To configure the mod_tls module to use OCSP when verifying, use:

  TLSVerifyOrder ocsp
Note that at is possible for mod_tls to use both CRLs and OCSP when verifying certificates. Simply use TLSVerifyOrder to configure the order in which mod_tls should use the various verification mechanisms:
  TLSVerifyOrder ocsp crl
Verification ends when a mechanism can successfully verify the certificate.

See also: TLSCARevocationFile, TLSCARevocationPath


Control Actions


tls sesscache clear

Syntax: ftpdctl tls sesscache clear
Purpose: Clears all cached sessions from the SSL session cache

The tls sesscache clear action is used to clear all cached sessions, whether they have expired or not, from the configured external SSL session cache. For example:

  # ftpdctl tls sesscache clear   
  ftpdctl: tls sesscache: cleared 1 session from 'shm' session cache

See also: TLSSessionCache


tls sesscache info

Syntax: ftpdctl tls sesscache info [-v]
Purpose: Displays status of session cache

The tls sesscache info action is used to display information about the configured external SSL session cache. If the optional -v command-line option is used, then information about each cached session will also be displayed.

For example:

  # ftpdctl tls sesscache info -v
  ftpdctl: Shared memory (shm) SSL session cache provided by mod_tls_shmcache/0.1
  ftpdctl:
  ftpdctl: Shared memory segment ID: 589824
  ftpdctl: Shared memory segment size: 1576960 bytes
  ftpdctl: Shared memory cache created on: Mon Mar  9 21:18:05 2009
  ftpdctl: Shared memory attach count: 1
  ftpdctl: 
  ftpdctl: Max session cache size: 153
  ftpdctl: Current session cache size: 1
  ftpdctl: 
  ftpdctl: Cache lifetime hits: 0
  ftpdctl: Cache lifetime misses: 0
  ftpdctl: 
  ftpdctl: Cache lifetime sessions stored: 1
  ftpdctl: Cache lifetime sessions deleted: 0
  ftpdctl: Cache lifetime sessions expired: 0
  ftpdctl: 
  ftpdctl: Cache lifetime errors handling sessions in cache: 0
  ftpdctl: Cache lifetime sessions exceeding max entry size: 0
  ftpdctl: 
  ftpdctl: Cached sessions:
  ftpdctl:   -----BEGIN SSL SESSION PARAMETERS-----
  ftpdctl:     Session ID: A9BB647E236BAB0EF128FE9EAD2ABEC6F8E65C9EB8F050A07D1F0F66EC3019DC
  ftpdctl:     Session ID Context: 00000000
  ftpdctl:     Protocol: TLSv1
  ftpdctl:     Started: Mon Mar  9 21:19:20 2009
  ftpdctl:     Expires: Tue Mar 10 21:19:20 2009 (86400 secs)
  ftpdctl:   -----END SSL SESSION PARAMETERS-----

See also: TLSSessionCache


tls sesscache remove

Syntax: ftpdctl tls sesscache remove
Purpose: Removes the external SSL session cache

The tls sesscache remove action is used to remove the external SSL session cache entirely. Depending on the actual module providing the session cache, this may or may not be implemented.

For example:

  # ftpdctl tls sesscache remove
  ftpdctl: tls sesscache: removed 'shm' session cache

See also: TLSSessionCache


Usage

Much of the documentation for Apache's mod_ssl, concerning certificates, OpenSSL usage, etc applies to this module as well:
  http://www.modssl.org/docs/2.7/
The OpenSSL documentation, and its FAQ, are recommended as well:
  http://www.openssl.org/docs/

There is also a script, cert-tool, that can help in the creation of certificates. See cert-tool --help for usage information:

  http://www.castaglia.org/openssl/contrib/cert-tool

A copy of the Draft describing FTP over SSL/TLS is included with the source code for this module.


Installation

The mod_tls module is distributed with ProFTPD. Simply follow the normal steps for using third-party modules in proftpd:
  ./configure --with-modules=mod_tls
  make
  make install
Alternatively, mod_tls can be built as a DSO module:
  ./configure --enable-dso --with-shared=mod_tls ...
Then follow the usual steps:
  make
  make install

You may need to specify the location of the OpenSSL header and library files in your configure command, e.g.:

 ./configure --with-modules=mod_tls \
    --with-includes=/usr/local/openssl \
    --with-libraries=/usr/local/openssl



Author: $Author: castaglia $
Last Updated: $Date: 2013/03/06 17:45:08 $

© Copyright 2002-2013 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_wrap2.html0000644000175000017500000006116711564656447021567 0ustar frankiefrankie ProFTPD module mod_wrap2

ProFTPD module mod_wrap2


The mod_wrap2 package allows the proftpd daemon to provide tcpwrapper-like access control rules while running in standalone mode. It also allows for those access rules to be stored in various formats, such as files (e.g. /etc/hosts.allow and /etc/hosts.deny) or in SQL tables. Note that the mod_wrap2 module does not require or use the standard tcpwrappers libwrap library, and instead implements the same functionality internally (in order to support SQL-based access rules). Please read the usage documentation for more details.

This module is contained in mod_wrap2.c, mod_wrap2.h, and in the submodules source files, for ProFTPD 1.3.x. These modules are not enabled by default. Installation notes follow the directive documentation.

The most current version of mod_wrap2's submodules supports storage of access table information in various formats:

The most current version of mod_wrap2 is distributed with the ProFTPD source code.

Author

Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.

Thanks

Many, many thanks to Wietse Venema for writing the tcpwrappers package and its libwrap library, from which this module drew much of its code.

2002-12-12: Thanks to Steve Grubb for pointing out a few cases where interrupted functions were not being properly handled, and for reviewing the module code.

Directives


WrapAllowMsg

Syntax: WrapAllowMsg mesg
Default: None
Context: server config, <VirtualHost, <Global>, <Anonymous>
Module: mod_wrap2
Compatibility: 1.3.1rc1 and later

The WrapAllowMsg directive configures a message that will be added to proftpd's response to the connecting client when that client is allowed by mod_wrap2's access check. In the mesg parameter, the magic cookie '%u' is replaced with the username specified by the client during login.

Example:

  WrapAllowMsg "User '%u' allowed by access rules"


WrapDenyMsg

Syntax: WrapDenyMsg mesg
Default: None
Context: server config, <VirtualHost, <Global>, <Anonymous>
Module: mod_wrap2
Compatibility: 1.3.1rc1 and later

The WrapDenyMsg directive configures a message that will be sent to the connecting client when that client is denied by mod_wrap2's access check, and disconnected. In the mesg parameter, the magic cookie '%u' is replaced with the username specified by the client during login.

Example:

  WrapDenyMsg "User '%u' denied by access rules"


WrapEngine

Syntax: WrapEngine on|off
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_wrap2
Compatibility: 1.3.1rc1 and later

The WrapEngine directive enables or disables the module's runtime access control engine. If it is set to off this module does no runtime processing at all. Use this directive to disable the module instead of commenting out all mod_wrap2 directives.


WrapGroupTables

Syntax: WrapGroupTables group-AND-expression source-type:allow-source-info source-type:deny-source-info [source-type:options-source-info]
Default: None
Context: server config, <VirtualHost, <Global>, <Anonymous>
Module: mod_wrap2
Compatibility: 1.3.1rc1 and later

The WrapGroupTables directive configures the information necessary for mod_wrap2 to locate and use the tables containing the access rules for specific groups.

The group-AND-expression parameter is a logical AND expression, which means that the connecting user must be a member of all the groups listed for this directive to apply. Group names may be negated with a ! prefix.

The next two parameters specify two tables, an allow and a deny table, each of which contain the IP addresses, networks or host/network masks to be allowed or denied.

Please consult the relevant submodule documentation for details on that module's syntax for specifying tables. The service name for which mod_wrap2 will look in the indicated access tables is "proftpd" by default; this can be configured via the WrapServiceName directive.

See also: WrapServiceName, WrapTables, WrapUserTables


WrapLog

Syntax: WrapLog file|"none"
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_wrap2
Compatibility: 1.3.1rc1 and later

The WrapLog directive is used to a specify a log file for mod_wrap2 reporting, and can be done a per-server basis. The file parameter must be the full path to the file to use for logging. Note that this path must not be to a world-writeable directory and, unless AllowLogSymlinks is explicitly set to on (generally a bad idea), the path must not be a symbolic link.

If file is "none", no logging will be done at all; this setting can be used to override a WrapLog setting inherited from a <Global> context.


WrapOptions

Syntax: WrapOptions opt1 ...
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_wrap2
Compatibility: 1.3.4rc1 and later

The WrapOptions directive is used to configure various optional behavior of mod_wrap2. Note: all of the configured WrapOptions parameters must appear on the same line in the configuration; only the first WrapOptions directive that appears in the configuration is used.

Example:

  WrapOptions CheckOnConnect

The currently implemented options are:

  • CheckAllNames

    This causes mod_wrap2 to check all of the known DNS names for the client IP address against the DNS names/patterns in the access rules, rather than just checking the first DNS name returned for the client IP address.

  • CheckOnConnect

    This causes mod_wrap2 to check the allow/deny tables when the client first connects, rather than waiting until the client has authenticated before checking the access rules. This means that per-user/group allow/deny tables, and the use of the tilde (~) notation in table paths, is not supported when this option is used.

    In addition, if mod_wrap2_sql is used, the order in which that module is loaded is very important. The mod_sql module must appear after the mod_wrap2 module in the --with-modules configure option, e.g.:

        --with-modules=mod_wrap2:mod_wrap2_sql:mod_sql:mod_sql_mysql
    
    You will also need to ensure that mod_sql creates a database connection at connect time, using the PERCONNECTION connection policy; see SQLConnectInfo for more details. Without this, the database connection will not be created at connect time, and the mod_wrap2 module will be unable to check any allow/deny rules stored in SQL tables when the client connects.


WrapServiceName

Syntax: WrapServiceName name
Default: WrapServiceName proftpd
Context: server config, <VirtualHost>, <Global>
Module: mod_wrap2
Compatibility: 1.3.1rc1 and later

WrapServiceName is used to configure the name of the service under which mod_wrap2 will check the allow/deny tables. By default, this is the name of the program started, i.e. "proftpd". However, some administrators may want to use a different, more generic service name, such as "ftpd"; use this directive for such needs. The lookup using the configured name is case-sensitive.


WrapTables

Syntax: WrapTables source-type:allow-source-info source-info:deny-source-info
Default: None
Context: server config, <VirtualHost, <Global>, <Anonymous>
Module: mod_wrap2
Compatibility: 1.3.1rc1 and later

The WrapTables directive configures the information necessary for mod_wrap2 to locate and use the tables containing the access rules for all clients.

The two parameters specify two tables, an allow and a deny table, each of which contain the IP addresses, networks or host/network masks to be allowed or denied.

Please consult the relevant submodule documentation for details on that module's syntax for specifying tables. The service name for which mod_wrap2 will look in the indicated access tables is "proftpd" by default; this can be configured via the WrapGroupTables, WrapServiceName, WrapUserTables


WrapUserTables

Syntax: WrapUserTables user-OR-expression source-type:allow-source-info source-type:deny-source-info [source-type:option-source-info]
Default: None
Context: server config, <VirtualHost, <Global>, <Anonymous>
Module: mod_wrap2
Compatibility: 1.3.1rc1 and later

The WrapUserTables directive configures the information necessary for mod_wrap2 to locate and use the tables containing the access rules for specific users.

The user-OR-expression parameter is a logical OR expression, which means that the connecting user can be any the users listed for this directive to apply. User names may be negated with a ! prefix.

The next two parameters specify two tables, an allow and a deny table, each of which contain the IP addresses, networks or host/network masks to be allowed or denied.

Please consult the relevant submodule documentation for details on that module's syntax for specifying tables. The service name for which mod_wrap2 will look in the indicated access tables is "proftpd" by default; this can be configured via the WrapGroupTables, WrapServiceName, WrapTables


Usage

To use mod_wrap2's functionality, you must first define the tables that together contain the access rules. Access rules are composed of daemon lists, client lists, and optional options lists. daemon lists are used so that the access rules can be configured for mulitple daemons; mod_wrap2 ignores all daemons except that configured for proftpd. client lists are the heart of the access rules, specifying the host names, IP addresses, etc to be allowed or denied. The handling of options lists is done only if mod_wrap2 is configured with the --enable-wrapper-options option.

There is a built-in precedence to the WrapUserTables, WrapGroupTables, and WrapTables directives, if all are used. mod_wrap2 will look for applicable WrapUserTables for the connecting user first. If no applicable WrapUserTables are found, mod_wrap2 will search for WrapGroupTables which pertain to the connecting user. If not found, mod_wrap2 will then look for the server-wide WrapTables directive. This allows for access control to be set on a per-server basis, and allow for per-user or per-group access control to be handled without interfering with the overall server access rules.

When checking the tables, mod_wrap2 always checks the allow table first. If the client has been explicitly allowed by the rules in that table, processing stops and mod_wrap2 allows the client to continue the session. If not explicitly allowed, mod_wrap2 will then check the deny table's access rules. If the client has been explicity denied by rules in that table, mod_wrap2 will disconnect the client. By default, if neither explicitly allowed or explicitly denied, mod_wrap2 will allow the client to continue.

In addition to the various formats supported by the submodules, there is a special source type: "builtin". This is used in the situations where the administrator wishes to configure "mostly closed" access rules, the most common situation. For example, if all clients are to be denied by mod_wrap2 by default, unless that client is granted access via an allow table entry, then the administrator can use:

  builtin:all
as the deny table parameter (e.g. in a WrapUserTables, WrapGroupTables, or WrapTables directive), rather than configuring a static deny table that always says ALL.

Access Rules

When checking access rules, the check terminates when the first match is found. A client list is a list of one or more host names, host addresses, patterns or wildcards (see below) that will be matched against the client host name or address. The more complex daemon@host and user@host forms are explained in the sections on server endpoint patterns and on client username lookups, respectively. With the exception of NIS/YP netgroup lookups, all access control checks are case insensitive.

Patterns
The access control language implements the following patterns:

  • A string that begins with a `.' character. A host name is matched if the last components of its name match the specified pattern. For example, the pattern .castaglia.org matches the host name golem.devlan.castaglia.org.

  • A string that ends with a `.' character. A host address is matched if its first numeric fields match the given string. For example, the pattern 131.155. matches the address of (almost) every host on the Eindhoven University network (131.155.x.x).

  • A string that begins with an `@' character is treated as an NIS (formerly YP) netgroup name. A host name is matched if it is a host member of the specified netgroup. Netgroup matches are not supported for client user names. Note that mod_wrap2 must be configured for NIS support for netgroup lookups to occur.

  • An expression of the form n.n.n.n/m.m.m.m is interpreted as an IPv4 net/mask pair. An IPv4 address is matched if the net portion is equal to the bitwise AND of the address and the mask portion. For example, the net/mask pattern 131.155.72.0/255.255.254.0 matches every address in the range 131.155.72.0 through 131.155.73.255.

  • An expression of the form [address]/number is interpreted as an IPv6 net/mask pair. An IPv6 address is matched if the first number bits match the rule address. For example, [3ffe:505:2:1::]/64 matches every address in the range 3ffe:505:2:1:: through 3ffe:505:2:1:ffff:ffff:ffff:ffff:.

  • Wildcards `*' and `?' can be used to match hostnames or IP addresses. This method of matching cannot be used in conjunction with net/mask matching, hostname matching beginning with `.' or IP address matching ending with `.'.

Wildcards
The access control language supports explicit wildcards:

  • ALL
    The universal wildcard, always matches.

  • LOCAL
    Matches any host whose name does not contain a dot character.

  • UNKNOWN
    Matches any user whose name is unknown, and matches any host whose name or address are unknown. This pattern should be used with care: host names may be unavailable due to temporary name server problems.

  • KNOWN
    Matches any user whose name is known, and matches any host whose name and address are known. This pattern should be used with care: host names may be unavailable due to temporary name server problems.

  • PARANOID
    Matches any host whose name does not match its address, before looking at the access control tables.

Operators

  • EXCEPT
    Intended use is of the form:
      list1 EXCEPT list2
    
    This construct matches anything that matches list1 unless it matches list2. The EXCEPT operator can be used in daemon lists and client lists. The EXCEPT operator can be nested: if the control language would permit the use of parentheses:
      a EXCEPT b EXCEPT c
    
    would parse as
      (a EXCEPT (b EXCEPT c))
    

Server Endpoint Patterns
In order to distinguish clients by the network address that they connect to, use patterns of the form:

  process-name@host-pattern : client-list ...
Patterns like these can be used when the machine has different Internet addresses with different Internet hostnames. Service providers can use this facility to offer FTP, GOPHER or WWW archives with Internet names that may even belong to different organizations. Some systems can have more than one Internet address on one physical interface.

The host-pattern obeys the same syntax rules as host names and addresses in client lists.

Client Username Lookup
When the client host supports the RFC 931 protocol, the proftpd daemon can retrieve additional information about the owner of a connection. Client username information, when available (i.e. when IdentLookups are not disabled), is logged together with the client host name, and can be used to match patterns like:

  daemon-list : ... user-pattern@host-pattern ...

A user-pattern has the same syntax as a daemon pattern, so the same wildcards apply (netgroup membership is not supported). One should not get carried away with username lookups, though:

  • The client username information cannot be trusted when it is needed most, i.e. when the client system has been compromised. In general, ALL and (UN)KNOWN are the only user name patterns that make sense.

  • Username lookups are possible only when the client host runs a suitable daemon; in all other cases the result is "unknown".

Access Options

This section describes optional options list portion the access control language described above. The options list syntax uses the following format:
  opt1 : opt2 ...
Any `:' characters within options should be protected with a backslash.

An option is of the form "keyword" or "keyword value". Options are processed in the specified order. For the sake of backwards compatibility with earlier versions, a `=' is permitted between keyword and value.

  • ALLOW
    Grant service. This option must appear at the end of a rule.
  • DENY
    Deny service. This option must appear at the end of a rule.

The allow and deny keywords make it possible to keep all access control rules within a single file, for example in the hosts.allow file. To permit access from specific hosts only:

    ALL: .friendly.domain: ALLOW
    ALL: ALL: DENY
To permit access from all hosts except a few trouble makers:
    ALL: .bad.domain: DENY
    ALL: ALL: ALLOW
Notice the leading dot on the domain name patterns.

  • nice [number]
    Change the nice value of the process (default 10). Specify a positive value to spend more CPU resources on other processes.

  • setenv name=value
    Place a name=value pair into the process environment. The value may contain whitespace (but leading and trailing blanks are stripped off).

Diagnostics
When a syntax error is found in an options list, the error is reported in the WrapLog and the access option will be ignored.


Installation

After unpacking the latest proftpd-1.3.x source code, follow the usual steps for using third-party modules in proftpd:
  ./configure --with-modules=wrap-modules
  make
  make install
where wrap-modules will depend on the types of access tables you wish to support.

For file-based access tables, include the mod_wrap2_file submodule, e.g.:

  mod_wrap2:mod_wrap2_file
For SQL-based access tables, include the mod_wrap2_sql submodule, e.g.:
  mod_wrap2:mod_wrap2_sql
And, if you wish to support both file- and SQL-based access tables, use:
  mod_wrap2:mod_wrap2_file:mod_wrap2_sql
Note that SQL tables require that a correct installation of mod_sql (and any of its backend modules) also be used. Consult the mod_sql documentation for installation instructions for that module.


Author: $Author: castaglia $
Last Updated: $Date: 2011/05/18 05:46:15 $

© Copyright 2000-2011 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_sql.html0000644000175000017500000017072712156641361021321 0ustar frankiefrankie ProFTPD module mod_sql

ProFTPD module mod_sql



This module is contained in the contrib/mod_sql.c, contrib/mod_sql.h, contrib/mod_sql_mysql.c, and contrib/mod_sql_postgres.c files for ProFTPD 1.3.x, and is not compiled by default. Installation instructions are discussed here.

The mod_sql module is an authentication and logging module for ProFTPD. It is comprised of a front end module (mod_sql) and backend database-specific modules (mod_sql_mysql, mod_sql_postgres, mod_sql_sqlite, etc). The front end module leaves the specifics of handling database connections to the backend modules.

This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/).

This product includes cryptographic software written by Eric Young (eay@cryptsoft.com).

The most current version of mod_sql is distributed with ProFTPD.

Thanks

  • Johnie Ingram <johnie at netgod.net> for the original mod_sqlpw.
  • TJ Saunders and Jesse Sipprell for dealing with my inane questions.
  • John Morrissey for mod_ldap, which lit the way, here and there.
  • Zeev Suraski <bourbon at bourbon.netvision.net.il> for the Apache mod_auth_mysql module, which informed the SQLAuthTypes directive.
  • Avalon from IRC for doc-fixes and suggestions.
  • and many others who've suggested various enhancements or security fixes.

Directives


SQLAuthenticate

Syntax: SQLAuthenticate on|off or
Syntax: SQLAuthenticate [users] [groups] [userset[fast]] [groupset[fast]]
Default: on
Context: server config, <VirtualHost>, <Global>
Module: mod_sql
Compatibility: 1.2.5rc1 and later

The SQLAuthenticate directive configures mod_sql's authentication behavior, controlling whether to provide user and/or group information during authentication, and how that provisioning is performed. The parameters may appear in any order.

The available parameter values are:

  • on
    Shorthand for SQLAuthenticate users groups userset groupset.

  • off
    Disables all mod_sql authentication functions.

  • users
    If present, mod_sql will do user lookups. If not present, mod_sql will do no user lookups at all, including the {set|get|end}pwent() calls (see below).

  • groups
    If present, mod_sql will do group lookups. If not present, mod_sql will do no group lookups at all, including the {set|get|end}grent() calls (see below).

  • userset[fast]
    If present, mod_sql will process the potentially expensive {set|get|end}pwent() calls. If not present, mod_sql will not process these calls. Adding the suffix "fast" tells mod_sql to process the users as a single large query, rather than making a query per user. This may significantly reduce the number of queries against the database at the expense of increased memory use. This parameter will have no effect if "users" is not specified.

  • groupset[fast]
    If present, mod_sql will process the potentially expensive {set|get|end}grent() calls. If not present, mod_sql will not process these calls. Adding the suffix "fast" tells mod_sql to process the groups as a single large query, rather than making a query per group. This may significantly reduce the number of queries against the database at the expense of increased memory use. This parameter will have no effect if "groups" is not specified.

The SQLLog and SQLShowInfo directives will always be processed by mod_sql. The SQLAuthenticate directive only affects the user and group lookup/authentication portions of the module.

Turning off (i.e. by not including) the userset or groupset parameters affects the functionality of mod_sql. Not allowing these lookups may remove the ability to control access or control functionality by group membership, depending on your other authentication handlers and the data available to them. At the same time, choosing not to do these lookups may dramatically speed login for many large sites.

The "fast" suffix is not appropriate for every site. Normally, mod_sql will retrieve a list of users and groups, and get information from the database on a per-user or per-group basis. This is query intensive: it requires (nn + 1) queries, where n is the number of users or groups to lookup. By choosing "fast" lookups, mod_sql will make a single SELECT query to get information from the database.

In exchange for the radical reduction in the number of queries, the single query will increase the memory consumption of the process; all group or user information will be read at once rather than in discrete chunks.

Group Table Structure
Normally mod_sql allows multiple group members per row, and multiple rows per group. If you use the "fast" option for groupset, you must use only one row per group. For example, normally mod_sql treats the following three tables in exactly the same way:

|--------------------------------------------------|
|  GROUPNAME  |  GID  |  MEMBERS                   |
|--------------------------------------------------|
| group1      | 1000  | naomi                      |
| group1      | 1000  | priscilla                  |
| group1      | 1000  | gertrude                   |
|--------------------------------------------------|

|--------------------------------------------------|
|  GROUPNAME  |  GID  |  MEMBERS                   |
|--------------------------------------------------|
| group1      | 1000  | naomi, priscilla           |
| group1      | 1000  | gertrude                   |
|--------------------------------------------------|

|--------------------------------------------------|
|  GROUPNAME  |  GID  |  MEMBERS                   |
|--------------------------------------------------|
| group1      | 1000  | naomi, priscilla, gertrude |
|--------------------------------------------------|
If you use the "fast" option, mod_sql assumes that all entries are structured like the last example.


SQLAuthTypes

Syntax: SQLAuthTypes ["Backend" | "Crypt" | "Empty" | "OpenSSL" | "Plaintext"] ...
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_sql
Compatibility: 1.2.0 and later

The SQLAuthTypes directive specifies which authentication method are to be allowed, and their order of use. You must specify at least one authentication method.

The current supported authentication methods are:

  • Backend
    Allows database-specific backend passwords. Not all backend databases support this option. For example, MySQL datatabases use this option to authenticate MySQL 'PASSWORD()' encrypted passwords. The Postgres backend, however, does nothing. Caveat: if your MySQL activity log is world-readable, the user password will be visible. You have been warned.

  • Crypt
    Allows passwords in the database to be of Unix crypt(3) form. Note that the traditional Unix crypt(3) function only uses the first 8 characters of a password. If you have passwords longer than 8 characters, and some of those passwords have the same first 8 characters, then those users may be able to log into each others accounts.

  • Empty
    Allows empty passwords in the database, which match against any password the user may give. The database field must be a truly empty string; NULL values are not acceptable as empty passwords. Be very careful if using this authentication method.

  • OpenSSL
    Allows passwords in the database to be of the form '{digest-name}hashed-value', where hashed-value is the base64-encoded digest of the passsword. Only available if you define HAVE_OPENSSL when you compile proftpd and you link with OpenSSL's libcrypto library; the easiest way to handle this is to use the --enable-openssl configure option.

  • Plaintext
    Allows passwords in the database to be in plaintext.

For example:

  SQLAuthTypes Crypt Empty
configures mod_sql to first attempt to verify the password using the Unix crypt(3) function, then, if that fails, determine if the password in the database is empty (thus matching any given password). If all of the configured authentication methods fail, mod_sql will fail to authenticate the user.

Note that the mod_sql_passwd module also provides other SQLAuthTypes values.


SQLBackend

Syntax: SQLBackend backend
Default: Depends
Context: server config, <VirtualHost>, <Global>
Module: mod_sql
Compatibility: 1.3.0rc1 and later

In 1.3.0rc1, the mod_sql module gained the ability to be compiled with multiple backend modules supported, e.g. to have both mod_sql_mysql and mod_sql_postgres usable in the same proftpd daemon. The SQLBackend directive configures which of these different database backends should be used.

If there is only one backend module compiled in, the SQLBackend directive is not needed. If there are multiple backend modules compiled and no SQLBackend directive is specified, then mod_sql will default to using the first backend module listed. For instance, if you configured proftpd using a configure command such as:

  ./configure --with-modules=mod_sql:mod_sql_postgres:mod_sql_mysql ...
then mod_sql would default to using mod_sql_postgres as the backend module to use.

You might have multiple <VirtualHost> sections which use different SQL backends, e.g.:

  <VirtualHost 1.2.3.4>
    SQLBackend mysql
    ...
  </VirtualHost>

  <VirtualHost 5.6.7.8>
    SQLBackend postgres
    ...
  </VirtualHost>
Use "mysql" for the mod_sql_mysql module, and "postgres" for the mod_sql_postgres module.


SQLConnectInfo

Syntax: SQLConnectInfo connection-info [username] [password] [policy]
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_sql
Compatibility: 1.2.0 and later

The SQLConnectInfo directive configures the information necessary to connect to the backend database. The connection-info parameter specifies the database, host, port, and other backend-specific information. The optional username and password parameters specify a username and password to use when connecting to the database. Both default to NULL, which the backend will treat in some backend-specific manner. If you specify a password, you must specify a username. If no SQLConnectInfo directive is specified, mod_sql will disable itself.

Any given database backend has the opportunity, though not necessarily the responsibility, to check for syntax errors in the connection-info field at server startup, but you should not expect semantic errors (i.e., cannot connect to the database) to be caught until mod_sql attempts to connect for a given host.

A given database connection is governed by a connection policy that specifies when a connection should be opened and when it should be closed. There are three options:

  • PERCONNECTION
    Open a database connection when the client connects to the server, and close the database connection when the client disconnects.

  • PERSESSION
    Open a database connection on first use (e.g. during authentication) and close the database connection at the end of the session.

  • number ("timed")
    Timed database connections that close themselves after number seconds of inactivity.

If a connection policy is not specified, if the policy is not a number or is a number less than 1, or if the policy is the string "PERSESSION", the PERSESSION policy will be used.

If the connection policy is any number greater than 0, it specifies the number of seconds that a connection will be held open without activity. After that many seconds of database inactivity, the connection to the database will be closed. As soon as database activity starts again, the connection will be opened and the timer will restart.

The MySQL and Postgres backends' connection-info is expected to be of the form:

  database[@hostname][:port]
hostname will default to a backend-specific hostname (which happens to be 'localhost' for both the MySQL and Postgres backends), and port will default to a backend-specific default port (3306 for the MySQL backend, 5432 for the Postgres backend).

From the MySQL documentation:

the value of host may be either a hostname or an IP address. If host is NULL or the string "localhost", a connection to the local host is assumed. If the OS supports sockets (Unix) or named pipes (Windows), they are used instead of TCP/IP to connect to the server.
(Note: In proftpd-1.3.1rc1, if hostname starts with a slash, it is interpreted as the Unix domain socket path by mod_sql_mysql, similar to how mod_sql_postgres handles the parameter.) From the PostgreSQL documentation:
If [the hostname] begins with a slash, it specifies Unix domain communication rather than TCP/IP communication; the value is the name of the directory in which the socket file is stored. The default is to connect to a Unix-domain socket in /tmp.

If you plan to use the "timed" connection policy, consider the effect of directives such as DefaultRoot on local socket communication: once a user has been chroot()ed, the local socket file will probably not be available within the chroot directory tree, and attempts to reopen communication will fail. One way around this may be to use hardlinks within the user's directory tree; another is to use network (e.g. TCP sockets, not Unix domain sockets) connections to connect to the database. PERSESSION connections are not affected by this because the database will be opened prior to the chroot() call, and held open for the life of the session. Network communications are not affected by this chroot() problem. For example, while localhost would not work for MySQL since the MySQL client library will try to use Unix domain socket communications for that host, 127.0.0.1 will work (as long as your database is setup to accept these connections).

Examples:

  # Connect to the database 'ftpusers' via the default port at host
  # 'foo.com'.  Use a NULL username and NULL password when connecting.
  # A connection policy of PERSESSION is used.
  SQLConnectInfo ftpusers@foo.com

  # Connect to the database 'ftpusers' via port 3000 at host 'localhost'.
  # Use the username 'admin' and a NULL password when connecting.
  # A connection policy of PERSESSION is used.
  SQLConnectInfo ftpusers:3000 admin

  # Connect to the database 'ftpusers' via port 3000 at host 'foo.com'.
  # Use the username 'admin' and password 'mypassword' when connecting.
  # A connection policy of PERSESSION is used.
  SQLConnectInfo ftpusers@foo.com:3000 admin mypassword

  # Connect to the database 'ftpusers' via port 3000 at host 'foo.com'.
  # Use a username of 'admin' and a password of 'mypassword' when
  # connecting.  A 30 second timer of connection inactivity is activated.
  SQLConnectInfo ftpusers@foo.com:3000 admin mypassword 30
Backends may require different information in the connection-info field; check your backend module for more detailed information.


SQLDefaultGID

Syntax: SQLDefaultGID default-gid
Default: 65533
Context: server config, <VirtualHost>, <Global>
Module: mod_sql
Compatibility: 1.2.0 and later

The SQLDefaultGID directive configures the default GID for users. This value must be greater than any configured SQLMinUserGID.

See also: SQLMinUserGID


SQLDefaultHomedir

Syntax: SQLDefaultHomedir path
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_sql
Compatibility: 1.2.5rc1 and later

The SQLDefaultHomedir directive configures a default home directory for all users authenticated with this module. If no home directory is set with either directive, authentication fails. This directive does not change the data retrieved from the database: if you specify a home directory field to SQLUserInfo, that field's data will be returned as the user's home directory, whether that data is a legal directory, or an empty string, or NULL.

See also: SQLUserInfo


SQLDefaultUID

Syntax: SQLDefaultUID default-uid
Default: 65533
Context: server config, <VirtualHost>, <Global>
Module: mod_sql
Compatibility: 1.2.0 and later

The SQLDefaultUID directive configures the default UID for users. This value must be greater than any configured SQLMinUserUID.

See also: SQLMinUserUID


SQLEngine

Syntax: SQLEngine on|off|auth|log
Default: SQLEngine on
Context: server config, <VirtualHost>, <Global>, <Anonymous>
Module: mod_sql
Compatibility: 1.3.0rc1 and later

The SQLEngine directive is used to specify how mod_sql will operate. By default, SQLEngine is on, and mod_sql will operate as normal. Setting SQLEngine to off will effectively disable the module.

In addition to on and off, SQLEngine accepts two other values: auth and log. If you wish to use mod_sql for authentication and not for logging (via SQLLog), use auth. Conversely, to do only SQLLog-type logging, and no authentication, use log.

This directive can be used to have <Anonymous> sections that do not use mod_sql, e.g.:

  <Anonymous ~ftp>
    ...
    SQLEngine off
    ...
  </Anonymous>


SQLGroupInfo

Syntax: SQLGroupInfo group-table group-name gid members
Default: "groups groupname gid members"
Context: server config, <VirtualHost>, <Global>
Module: mod_sql
Compatibility: 1.2.5rc1 and later

The SQLGroupInfo directive configures the group table and fields that hold group information. The parameters for this directive are described below:

  • grouptable
    Specifies the name of the table that holds group information.

  • groupname
    Specifies the field in the group table that holds the group name.

  • gid
    Specifies the field in the group table that holds the group's GID.

  • members
    Specifies the field in the group table that holds the group members.

If you need to change any of these field names from the default, you need to specify all of them.

Custom Queries
As of 1.3.3rc1, the SQLGroupInfo directive accepts an alternate syntax:

  SQLGroupInfo custom:/get-group-by-name/get-group-by-id/get-group-by-member
where get-group-by-name refers to a configured SELECT SQLNamedQuery. This named query must return one row, and return the following columns, in this order: groupname, gid, members. The configured query may make use of the variables mentioned in the SQLLog description. The %{0} variable will be populated with the group name for which info is being retrieved. The get-group-by-id here refers to a SQLNamedQuery which is just like the lookup given a group name, only the get-group-by-id query needs to return group information given a GID. For the get-group-by-id query, the %{0} variable is populated with the GID in question. Last, the get-group-by-member query returns group information given a user member; again, the %{0} will contain the member/user name by which to look up the group information.

If your custom get-group-by-name query references a table other than the default groups table, then you must also supply a custom get-group-by-id query as well. Otherwise, mod_sql will fail with a "Table not found" error, and disconnect the client, whenever the client asks for a directory listing.

Note, however, that if you use the groupset or groupsetfast SQLAuthenticate options, you will need to supply some additional SQLNamedQuery names in your custom SQLGroupInfo directive. The SQLGroupInfo directive supports:

  SQLGroupInfo custom:/lookup-by-name/lookup-by-id/lookup-by-member/[/groupset-lookup[/groupsetfast-lookup]]
where groupset-lookup is the name of a SELECT SQLNamedQuery that returns the names (and only the names) of all groups, and the groupsetfast-lookup refers to a SELECT SQLNamedQuery that returns all the fields (i.e. groupname, gid, members in that order) for all groups.

To provide a concrete example:

  SQLAuthenticate users groups groupsetfast
  SQLGroupInfo custom:/get-group-by-name/get-group-by-id/get-group-by-member/get-all-groupnames/get-all-groups
  SQLNamedQuery get-group-by-name SELECT "groupname, gid, members FROM ftpgroups WHERE groupname = '%{0}'"
  SQLNamedQuery get-group-by-id SELECT "groupname, gid, members FROM ftpgroups WHERE gid = %{0}"
  SQLNamedQuery get-group-by-member SELECT "groupname, gid, members FROM ftpgroups WHERE (members LIKE '%%,%{0},%%' OR members LIKE '%{0},%%' OR members LIKE '%%,%{0}')"
  SQLNamedQuery get-all-groupnames SELECT "groupname FROM ftpgroups"
  SQLNamedQuery get-all-groups SELECT "groupname, gid, members FROM ftpgroups"
With a configuration similar to these, using either of the groupset or groupsetfast in your SQLAuthenticate directive will work as expected.

Another consideration when using custom SQLGroupInfo queries is their relationship to the "useNormalizedGroupSchema" SQLOption. I.e. does using the "useNormalizedGroupSchema" option affect how the results of custom SQLGroupInfo queries are handled? No. If custom SQLGroupInfo queries are used, mod_sql automatically assumes that the custom group members query will return N rows, where each row contains 3 columns: group name, group ID, and member name. That is, the custom SQLGroupInfo queries act as if "useNormalizedGroupSchema" is always in effect. (When support for custom SQLGroupInfo queries was added, there was no good reason for supporting the old, inefficient comma-delimited format for the members column.)

See Also: SQLAuthenticate, SQLLog, SQLNamedQuery, SQLUserInfo


SQLGroupPrimaryKey

Syntax: SQLGroupPrimaryKey column | "custom:/"named-query
Default: gid
Context: server config, <VirtualHost>, <Global>
Module: mod_sql
Compatibility: 1.3.5rc3 and later

The SQLGroupPrimaryKey directive configures the column name that is used as the "primary key" for group data; this primary key can then be used in other SQL tables via foreign key constraints. The SQL howto covers using this directive in more details.

See also: SQLUserPrimaryKey


SQLGroupWhereClause

Syntax: SQLGroupWhereClause where-clause
Default: off
Context: server config, <VirtualHost>, <Global>
Module: mod_sql
Compatibility: 1.2.5rc1 and later

The directive is used to configure a WHERE clause that is added to every group query. The WHERE clause must contain all relevant punctuation, and must not contain a leading "and".

As an example of a possible use for this directive, imagine if your group table included a "LoginAllowed" field:

  SQLGroupWhereClause "LoginAllowed = 'true'"
would be appended to every group-related query as the string:
  " WHERE (LoginAllowed = 'true')"

Note that if custom group SQLNamedQuery are configured, those custom queries will be used as is; any configured SQLGroupWhereClause will not be appended. Custom queries can be of any format/syntax, and thus simply appending a SQLGroupWhereClause to a custom query may be syntactically invalid.

As of ProFTPD 1.3.1rc2, the configured SQLGroupWhereClause parameter can use the same set of variables as supported by the SQLNamedQuery directive.


SQLLog

Syntax: SQLLog cmd-set query-name ["IGNORE_ERRORS"]
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_sql
Compatibility: 1.2.1 and later

This directive is used to log information to a database table. Multiple SQLLog directives can be in effect for any command; for example, a user changing directories can trigger multiple logging statements.

The first parameter to SQLLog, the cmd-set, is a comma-separated (no spaces) list of FTP commands for which this log command will trigger. The list of commands is too long to list in entirety; commands include CWD, DELE, HELP, LIST, MKD, MODE, NLST, PASS, PASV, PORT and many more. For the complete list check the FTP RFCs. Normally mod_sql will log events after they have completed successfully; in the case of the QUIT command, mod_sql logs prior to the server's processing of the command. (Note, however, that the client may not issue a QUIT before logging out; in this case, use a command of EXIT rather than QUIT. EXIT is not a real FTP command, but it is used here to provide a means for having SQLLog work whenever a session ends.)

FTP commands in the command set will only be logged if they complete successfully. Prefixing any command with "ERR_" will cause logging to occur only if there was an error in the command's processing. To log both errors and successful completion of a given command X, therefore, you'll need both "X" and "ERR_X" in your cmd-set.

The special command "*" matches all FTP commands, while "ERR_*" matches all errors.

The second parameter is the name of a query defined by a SQLNamedQuery directive. The query must be an UPDATE, INSERT, or FREEFORM type query; explicit SELECT queries will not be processed.

The third parameter is optional. If you add "IGNORE_ERRORS" as the third parameter, SQLLog will not check for errors in the processing of the named query. Any value for this parameter other than the string "IGNORE_ERRORS" (case-insensitive) will not cause errors to be ignored.

Normally, SQLLog directives are considered important enough that errors in their processing will cause mod_sql to abort the client session. References to non-existent named queries will not abort the client session, but may result in database corruption (in the sense that the expected database UPDATE or INSERT will not occur). Check your directives carefully.

Examples:

  SQLLog PASS updatecount
  SQLNamedQuery updatecount UPDATE "count=count+1 WHERE userid='%u'" users
If the current user was "joe", this would translate into the query "UPDATE users SET count=count+1 WHERE userid='joe'". This query would run whenever a user was first authenticated.
  SQLLog CWD updatedir
  SQLNamedQuery updatedir UPDATE "cwd='%d' where userid='%u'" users
If the current user was "joe" and the current working directory were /tmp, this would translate into the query "UPDATE users SET cwd='/tmp' WHERE userid='joe'". This query would run whenever a user changed directories.
  SQLLog RETR,STOR insertfileinfo
  SQLNamedQuery insertfileinfo INSERT "'%f', %b, '%u@%v', now()" filehistory
would log the name of any file stored or retrieved, the number of bytes transferred, the user and host doing the transfer, and the time of transfer (at least in MySQL). This would translate into a query like: "INSERT INTO filehistory VALUES ('somefile', 12345, 'joe@joe.org', '21-05-2001 20:01:00')"


SQLLogFile

Syntax: SQLLogFile file
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_sql
Compatibility: 1.2.8rc2 and later

The SQLLogFile directive is used to a specify a log file for mod_sql reporting and debugging, and can be done a per-server basis. The file parameter must be the full path to the file to use for logging. Note that this path must not be to a world-writeable directory and, unless AllowLogSymlinks is explicitly set to on (generally a bad idea), the path must not be a symbolic link.

If file is "none", no logging will be done at all; this setting can be used to override a SQLLogFile setting inherited from a <Global> context.


SQLMinID

Syntax: SQLMinID minimum-id
Default: 999
Context: server config, <VirtualHost>, <Global>
Module: mod_sql
Compatibility: 1.2.0 and later

SQLMinID is a quick way of setting both SQLMinUserGID and SQLMinUserUID. These values are checked whenever retrieving a user's GID or UID.

See also: SQLMinUserGID, SQLMinUserUID


SQLMinUserGID

Syntax: SQLMinUserGID minimum-gid
Default: 999
Context: server config, <VirtualHost>, <Global>
Module: mod_sql
Compatibility: 1.2.0 and later

SQLMinUserGID is checked whenever retrieving a user's GID. If the retrieved value for GID is less than the value of SQLMinUserGID, it is reported as the value of SQLDefaultGID.

See also: SQLDefaultGID


SQLMinUserUID

Syntax: SQLMinUserUID minimum-uid
Default: 999
Context: server config, <VirtualHost>, <Global>
Module: mod_sql
Compatibility: 1.2.0 and later

SQLMinUserUID is checked whenever retrieving a user's UID. If the retrieved value for UID is less than the value of SQLMinUserUID, it is reported as the value of SQLDefaultUID.

See also: SQLDefaultUID


SQLNamedConnectInfo

Syntax: SQLConnectInfo connection-name sql-backend connection-info [username] [password] [policy]
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_sql
Compatibility: 1.3.4rc2 and later

The SQLNamedConnectInfo directive configures the information necessary to connect to the backend database. This connection will be given the name connection-name; this named connection can then be referenced by that name in e.g. a SQLNamedQuery. The sql-backend name configures the backend SQL module to use for this connection; see SQLBackend. The connection-info parameter specifies the database, host, port, and other backend-specific information. The optional username and password parameters specify a username and password to use when connecting to the database. Both default to NULL, which the backend will treat in some backend-specific manner. If you specify a password, you must specify a username. Multiple SQLNamedConnectInfo directives can be configured.

Note that SQLNamedConnectInfo directives will only be honored if a SQLConnectInfo directive is configured.

See also: SQLBackend, SQLConnectInfo


SQLNamedQuery

Syntax: SQLNamedQuery name type query-string [table] [connection-name]
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_sql
Compatibility: 1.2.4 and later

SQLNamedQuery specifies a query and an identifier (name) for later use by SQLShowInfo and SQLLog.

It is strongly recommended that you read documentation on the LogFormat and ExtendedLog directives, as the meta-sequences available to SQLNamedQuery are largely equivalent.

The first parameter, name, should be unique across all named queries and must not contain spaces. The result of re-using a name is undefined.

The second parameter, type, is the type of query, either "SELECT", "UPDATE", "INSERT", or "FREEFORM". See the note below for information on FREEFORM type queries.

The third parameter is the substance of the database query itself; this should match the form of the second parameter. The meta-sequences accepted are exactly equivalent to the LogFormat directive except the following are not accepted:

  • %{FOOBAR}e
    For LogFormat, this logs the content of environment variable "FOOBAR". In a SQLNamedQuery SQL statement, however, environment variables can be referenced using %{env:FOOBAR}.

  • %{format}t and %t
    These two meta-sequences logged the local server time; they are not available in mod_sql. Your database undoubtedly provides another way to get the time; for example, MySQL provides the now() function.

    However, a %{time:format} meta-sequence is supported. This sequence allows for formatting time strings according to the rules of the strftime(3) function.


and the following is in addition to the LogFormat meta-sequences:
  • %d
    The current working directory or "-" if none.

  • %{n}
    This meta-sequence is used internally by mod_sql and other third-party modules and patches to pass information to the database. Using this meta-sequence in anything other than an INSERT or UPDATE query is an error, and using this meta-sequence unless directed to by a third-party module or patch is also an error.

The correct form of a query will be built from the directive arguments, except in the case of FREEFORM queries which will be sent directly to the database. The examples below show the way queries are built from the arguments.

The fourth parameter, table, is only necessary for UPDATE or INSERT type queries, but is required for those types.

The last parameter, connection-name, is only necessary for telling mod_sql to use the specified connection name (from SQLNamedConnectInfo), rather than the default connection, for executing the query/statement.

Note: FREEFORM queries are a necessary evil; the simplistic query semantics of the UPDATE, INSERT, and SELECT type queries do not sufficiently expose the capabilities of most backend databases. At the same time, using a FREEFORM query makes it impossible for mod_sql to check whether the query type is appropriate, making sure that a SELECT query is not used in a SQLLog directive, for instance. Wherever possible, it is recommended that a specific query type be used.

Examples:

  SQLNamedQuery count SELECT "count from users where userid='%u'"
creates a query named "count" which could be used by SQLShowInfo to inform a user of their login count. The actual query would look something like "SELECT count FROM users WHERE userid='matilda'" for user "matilda".
  SQLNamedQuery updatecount UPDATE "count=count+1 WHERE userid='%u'" users
creates a query named "updatecount" which could be used by SQLLog to update a user login counter in the table users. The actual query would look something like "UPDATE users SET count=count+1 WHERE userid='persephone'" for user "persephone".
  SQLNamedQuery accesslog INSERT "now(), '%u'" accesslog
creates a query named "accesslog" which could be used by SQLLog to track access times by clients. The actual query would look something like "INSERT INTO accesslog VALUES (now(), 'pandora')" for user "pandora". Note that this may be too simplistic for your table structure, since most databases require data for all columns to be provided in an INSERT statement of this form. See the following FREEFORM query for an example of something which may suit your needs better.
  SQLNamedQuery accesslog FREEFORM "INSERT INTO accesslog(date, user) VALUES (now(), '%u')"
creates a query named "accesslog" which could be used by SQLLog to track access times by clients. The actual query would look something like "INSERT INTO accesslog(date, user) VALUES (now(), 'tilda')" for user "tilda".


SQLNegativeCache

Syntax: SQLNegativeCache on|off
Default: off
Context: server config, <VirtualHost>, <Global>
Module: mod_sql
Compatibility: 1.2.7rc1 and later

SQLNegativeCache specifies whether or not to cache negative responses from SQL lookups when using SQL for UID/GID lookups. Depending on your SQL tables, there can be a significant delay when a directory listing is performed as the UIDs not in the SQL database are repeatedly looked up in an attempt to present usernames instead of UIDs in directory listings. With SQLNegativeCache set to on, negative ("not found") responses from SQL queries will be cached and speed will improve on directory listings that contain many users not present in the SQL database.


SQLOptions

Syntax: SQLOptions opt1 ...
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_sql
Compatibility: 1.3.1rc1 and later

The SQLOptions directive is used to tweak various optional behavior of mod_sql.

Example:

  SQLOptions noDisconnectOnError

The currently implemented options are:

  • noDisconnectOnError

    By default, mod_sql will automatically disconnect the client whenever there is a database error. If this option is enabled, mod_sql will attempt to continue functioning despite database errors.

  • noReconnect

    If supported by the database client library, mod_sql will try to automatically reconnect once, if it determines that the connection to the database server was lost. Use "noReconnect" to disable this auto-reconnection attempt.

  • useNormalizedGroupSchema

    If this option is enabled, then mod_sql, when retrieving all of the groups for a user, will use a SQL statement like:

      SELECT groupname, groupid, member FROM grouptable WHERE member = $userName
    
    rather than the statement it uses by default, which is:
      SELECT groupname, groupid, member FROM grouptable WHERE member = $userName OR
        member LIKE '%,$userName' OR member LIKE '$username,%' OR
        member LIKE '%,$userName,%'
    
    To put it another way, when this SQLOption is used, mod_sql will not treat the member column of the group table as a comma-delimited list of user names, but rather as a single user name. Thus, to have a user belong in multiple groups with this normalized schema, the group table would have individual rows for each user/group pair.


SQLRatios

Syntax:
Default: None
Context:
Module: mod_sql
Compatibility:


SQLRatioStats

Syntax:
Default: None
Context:
Module: mod_sql
Compatibility:


SQLShowInfo

Syntax: SQLShowInfo cmd-set numeric query-string
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_sql
Compatibility: 1.2.5rc1 and later

This directive creates a message to be sent to the user after any successful command.

The first parameter, the cmd-set, is a comma separated (no spaces) list of FTP commands for which this log command will trigger. The list of commands is too long to list in entirety; commands include: CWD, DELE, HELP, LIST, MKD, MODE, NLST, PASS, PASV, PORT and many more. For the complete list check the FTP RFCs.

FTP commands in the command set will only be triggered if they complete successfully. Prefixing any command with "ERR_" will show information only if there was an error in command processing. To send a message on both errors and successfull completion of a given command X, therefore, you'll need both "X" and "ERR_X" in your cmd-set.

The special command "*" matches all FTP commands, while "ERR_*" matches all errors.

The second parameter, numeric, specifies the numeric value of the message returned to the FTP client. Do not choose a number blindly: message numbers may be parsed by clients. In most cases you will want to use 214, the "Help message" numeric. It specifies that the information is only meant to be human readable. Note that FTP clients can be very picky about these response codes; choosing the wrong code can cause clients not to work. Section 5.4 of RFC959 defines the acceptable response codes for each FTP command.

The third parameter, query-string, is exactly equivalent to the query-string parameter to the SQLLog directive, with one addition:

  • %{name}
    The first return value from the SQLNamedQuery identified by "name". There is currently no way to retrieve more than one value from the database at a time.

Any references to non-existent named queries, non-SELECT or -FREEFORM type queries, or references to queries which return a NULL first value, will be replaced with the string "{null}". For example:
  SQLNamedQuery count SELECT "count from users where userid='%u'"
  SQLShowInfo PASS 230 "You've logged on %{count} times, %u"
As long as the information is in the database, these two directives specify that the user will be greeted with their login count each time they successfully login. Note the use of the "230" numeric, which means "User logged in, proceed". "230" is appropriate in this case because the message will be sent immediately after their password has been accepted and the session has started.


SQLUserInfo

Syntax: SQLUserInfo user-table user-name passwd uid gid home-dir shell
Default: "users userid passwd uid gid homedir shell"
Context: server config, <VirtualHost>, <Global>
Module: mod_sql
Compatibility: 1.2.5rc1 and later

The SQLUserInfo directive configures the user table and fields that hold user information. If you need to change any of these field names from the default, you must specify all of them, whether NULL or not. The parameters are described below:

  • usertable
    Specifies the name of the table that holds user information.

  • username
    Specifies the field in the user table that holds the username.

  • passwd
    Specifies the field in the user table that holds the user's password.

  • uid
    Specifies the field in the user table that holds the user's UID. When a UID is retrieved from the database it is checked against the value of SQLMinUserUID. If the field name is specified as "NULL" the database will not be queried for this value and the user's UID will be set to the value of SQLDefaultUID.

  • gid
    Specifies the field in the user table that holds the user's GID. When a GID is retrieved from the database it is checked against the value of SQLMinUserGID. If the field name is specified as "NULL" the database will not be queried for this value and the user's GID will be set to the value of SQLDefaultGID.

  • homedir
    Specifies the field in the user table that holds the user's home directory. If the fieldname is specified as "NULL" the database will not be queried for this value and the user's home directory will be set to the value of SQLDefaultHomedir. If no home directory is set with either directive, user authentication will be automatically turned off.

  • shell
    Specifies the field in the user table that holds the user's shell. If the fieldname is specified as "NULL" the database will not be queried and the shell will be reported as an empty string ("").

Custom Queries
As of 1.2.9rc1, the SQLUserInfo directive accepts an alternate syntax:

  SQLUserInfo custom:/name
where name refers to a configured SELECT SQLNamedQuery. This named query must return one row, and return the following columns, in this order: username, passwd, uid, gid, homedir, shell. The configured query may make use of the variables mentioned in the SQLLog description. This syntax allows the administrator a flexible way of constructing queries as needed. Note that if you want use the given USER name, you should use the %U variable, not %u; the latter requires the locally authenticated user name, which is exactly what SQLUserInfo is meant to provide.

Starting with 1.3.3rc1, you can supply other queries as well. You can supply a SELECT SQLNamedQuery for returning the same information as above, only this query is given a UID instead of a user name. For example:

  SQLNamedQuery get-user-by-name SELECT "userid, passwd, uid, gid, homedir, shell FROM ftpusers WHERE userid = '%U'"
  SQLNamedQuery get-user-by-id SELECT "userid, passwd, uid, gid, homedir, shell FROM ftpusers WHERE uid = %{0}"

  SQLUserInfo custom:/get-user-by-name/get-user-by-id
If your custom get-user-by-name query references a table other than the default users table, then you must also supply a custom get-user-by-id query as well. Otherwise, mod_sql will fail with a "Table not found" error, and disconnect the client, whenever the client asks for a directory listing.

Note, however, that if you use the userset or usersetfast SQLAuthenticate options, you will need to supply some additional SQLNamedQuery names in your custom SQLUserInfo directive. The SQLUserInfo directive supports:

  SQLUserInfo custom:/lookup-by-name[/lookup-by-id[/userset-lookup[/usersetfast-lookup]]]
where userset-lookup is the name of a SELECT SQLNamedQuery that returns the names (and only the names) of all users, and the usersetfast-lookup refers to a SELECT SQLNamedQuery that returns all the fields (i.e. username, passwd, uid, gid, homedir, shell in that order) for all users.

To provide a concrete example:

  SQLAuthenticate users groups usersetfast
  SQLUserInfo custom:/get-user-by-name/get-user-by-id/get-user-names/get-all-users
  SQLNamedQuery get-user-by-name SELECT "userid, passwd, uid, gid, homedir, shell FROM users WHERE userid = '%U'"
  SQLNamedQuery get-user-by-id SELECT "userid, passwd, uid, gid, homedir, shell FROM users WHERE uid = %{0}"
  SQLNamedQuery get-user-names SELECT "userid FROM users"
  SQLNamedQuery get-all-users SELECT "userid, passwd, uid, gid, homedir, shell FROM users"
With a configuration similar to these, using either of the userset or usersetfast in your SQLAuthenticate directive will work as expected.

See Also: SQLAuthenticate, SQLGroupInfo, SQLLog, SQLNamedQuery


SQLUserPrimaryKey

Syntax: SQLUserPrimaryKey column | "custom:/"named-query
Default: uid
Context: server config, <VirtualHost>, <Global>
Module: mod_sql
Compatibility: 1.3.5rc3 and later

The SQLUserPrimaryKey directive configures the column name that is used as the "primary key" for user data; this primary key can then be used in other SQL tables via foreign key constraints. The SQL howto covers using this directive in more details.

See also: SQLGroupPrimaryKey


SQLUserWhereClause

Syntax: SQLUserWhereClause where-clause
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_sql
Compatibility: 1.2.5rc1 and later

The directive is used to configure a WHERE clause that is added to every user query. The WHERE clause must contain all relevant punctuation, and must not contain a leading "and".

As an example of a possible use for this directive, imagine if your user table included a "LoginAllowed" field:

  SQLUserWhereClause "LoginAllowed = 'true'"
would be appended to every user-related query as the string:
  " WHERE (LoginAllowed = 'true')"

Note that if custom user SQLNamedQuery are configured, those custom queries will be used as is; any configured SQLUserWhereClause will not be appended. Custom queries can be of any format/syntax, and thus simply appending a SQLUserWhereClause to a custom query may be syntactically invalid.

As of ProFTPD 1.3.1rc2, the configured SQLUserWhereClause parameter can use the same set of variables as supported by the SQLNamedQuery directive.


Installation

The mod_sql module is distributed with ProFTPD. Simply follow the normal steps for using third-party modules in proftpd:
  ./configure --with-modules=sql-module-opts
where the specific sql-module-opts depend on your database needs. For example, if using MySQL, sql-module-opts would be "mod_sql:mod_sql_mysql". mod_sql is the main SQL-processing engine, and mod_sql_mysql is the backend sub-module that handles MySQL-specific details. If Postgres is your database of choice, sql-module-opts would be "mod_sql:mod_sql_postgres".

You will also need to tell configure how to find the database-specific libraries and header files:

  ./configure --with-modules=sql-module-opts \
    --with-includes=/path/to/db/header/file/dir \
    --with-libraries=/path/to/db/library/file/dir

Complete the build with the following standard commands:

  make
  make install



Author: $Author: castaglia $
Last Updated: $Date: 2013/06/14 16:21:05 $


© Copyright 2000-2013 The ProFTPD Project
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_sftp_pam.html0000644000175000017500000001273112113241145022306 0ustar frankiefrankie ProFTPD module mod_sftp_pam

ProFTPD module mod_sftp_pam



The mod_sftp_pam module provides support for the "SSH Keyboard-Interactive Authentication" RFC (RFC4256). How is mod_sftp_pam different from ProFTPD's existing PAM support, in the form of mod_auth_pam? The difference is that the mod_auth_pam module does not echo the prompt, provided by the underlying PAM library/modules, back to the FTP client; this mod_sftp_pam module will echo any prompt back to the connecting SSH2 client. This makes using onetime-password PAM modules, for example, work very easily for authenticating SSH2 logins.

This module is contained in the mod_sftp_pam.c file for ProFTPD 1.3.x, and is not compiled by default. Installation instructions are discussed here; a discussion on usage is also available.

The most current version of mod_sftp is distributed with the ProFTPD source code.

Author

Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.

Directives


SFTPPAMEngine

Syntax: SFTPPAMEngine on|off
Default: On
Context: "server config", <VirtualHost>, <Global>
Module: mod_sftp_pam
Compatibility: 1.3.2rc2 and later

The SFTPPAMEngine directive toggles the use of the PAM library for supporting a keyboard-interactive authentication mechanism for SSH2 logins. By default mod_sftp_pam is enabled.


SFTPPAMOptions

Syntax: SFTPPAMOptions opt1 opt2 ... optN
Default: None
Context: "server config", <VirtualHost>, <Global>
Module: mod_sftp_pam
Compatibility: 1.3.2rc2 and later

The SFTPPAMOptions directive is used to configure various optional behaviors of mod_sftp_pam; it is directly analogous to mod_auth_pam's AuthPAMOptions directive.

The currently supported options are:

  • NoTTY
  • NoInfoMsgs

    Disables the sending of information messages from PAM to the connecting SSH client. This option is usually used for compatibility with OpenSSH's behavior.

  • NoRadioMsgs

    Disables the sending of Linux-specific information messages from PAM (usually from the pam_winbind PAM module) to the connecting SSH client. This option is usually used for compatibility with OpenSSH's behavior.


SFTPPAMServiceName

Syntax: SFTPPAMServiceName service
Default: SFTPPAMServiceName sshd
Context: "server config", <VirtualHost>, <Global>
Module: mod_sftp_pam
Compatibility: 1.3.2rc2 and later

The SFTPPAMConfig directive is used to specify the name of the service used when performing the PAM check; PAM configurations can vary depending on the service. By default, the "sshd" service is used.

Here's an example of changing the service used:

  <IfModule mod_sftp_pam.c>
    SFTPPAMEngine on
    SFTPPAMServiceName ftpd
  </IfModule>

The SFTPPAMServiceName directive is directly analogous to mod_auth_pam's AuthPAMConfig directive.


Installation

To install mod_sftp_pam, copy the mod_sftp_pam.c file into:
  proftpd-dir/contrib/
after unpacking the latest proftpd-1.3.x source code. Then follow the usual steps for using third-party modules in proftpd, making sure to include the mod_sftp module, which mod_sftp_pam requires:
  ./configure --with-modules=mod_sftp:mod_sftp_pam ...
  make
  make install



Usage

To use mod_sftp_pam, simply configure it to use the correct PAM service name, e.g.:
  <IfModule mod_sftp_pam.c>
    SFTPPAMEngine on
    SFTPPAMServiceName sftp
  </IfModule>
There is no requirement that mod_sftp_pam use the same PAM service name as the mod_auth_pam module; this allows you to have different PAM configurations for FTP versus SSH2 logins.



Author: $Author: castaglia $
Last Updated: $Date: 2013/02/26 23:16:53 $


© Copyright 2008-2013 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_wrap2_file.html0000644000175000017500000001126011122043317022523 0ustar frankiefrankie ProFTPD module mod_wrap2_file

ProFTPD module mod_wrap2_file



This mod_wrap2 submodule is contained in the mod_wrap2_file.c, and is not compiled by default. See the mod_wrap2 installation instructions.

This submodule provides the file-specific "driver" for storing IP/DNS-based access control information in files.

Many programs will automatically add entries in the common hosts.allow/hosts.deny files, and use of this module will allow a proftpd daemon running in standalone mode to adapt as these entries are added. The portsentry program does this, for example: when illegal access is attempted, it will add hosts to the /etc/hosts.deny file.

Author

Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.


File Access Tables

Using file-based access tables (source-type of "file") the data will be stored in the familiar hosts.allow, hosts.deny file format.

The mod_wrap2_file module supports the "file" string for the source-type parameter of the WrapUserTables, WrapGroupTables, and WrapTables, configuration directives. If the "file" source-type is used, then the source-info parameter must be the full path to the file table.

Both file names are required. Also, the paths to both files must be the full path, with two exceptions: if the path starts with ~/, the check of that path will be delayed until a user requests a connection, at which time the path will be resolved to that user's home directory; or if the path starts with ~user/, where user is some system user. In this latter case, mod2_wrap will attempt to resolve and verify the given user's home directory on start-up.

The format for the files used by mod_wrap2_file is described in the host_access(5) man page.

Examples:

  # Server-wide access files
  WrapTables file:/etc/hosts.allow file:/etc/hosts.deny

  # FTP server-specific access files
  WrapTables file:/etc/ftpd.allow file:/etc/ftpd.deny

  # Per-user access files, which are to be found in the user's home directory
  WrapUserTables file:~/my.allow file:~/my.deny


Example File Tables

The following examples are taken from the hosts_access(5) man page:

Mostly Closed
In this case, access is denied by default. Only explicitly authorized hosts are permitted access.

The default policy (no access) is implemented with a trivial deny file:

  /etc/hosts.deny:
    ALL: ALL
This denies all service to all hosts, unless they are permitted access by entries in the allow file.

The explicitly authorized hosts are listed in the allow file. For example:

  /etc/hosts.allow:
    ALL: LOCAL @some_netgroup
    ALL: .foobar.edu EXCEPT terminalserver.foobar.edu
The first rule permits access from hosts in the local domain (no `.' in the host name) and from members of the some_netgroup netgroup. The second rule permits access from all hosts in the .foobar.edu domain (notice the leading dot), with the exception of terminalserver.foobar.edu.

Mostly Open
Here, access is granted by default; only explicitly specified hosts are refused service.

The default policy (access granted) makes the allow file redundant so that it can be omitted. The explicitly non-authorized hosts are listed in the deny file. For example:

  /etc/hosts.deny:
    ALL: some.host.name, .some.domain
    ALL EXCEPT in.fingerd: other.host.name, .other.domain
The first rule denies some hosts and domains all services; the second rule still permits finger requests from other hosts and domains.



Author: $Author: castaglia $
Last Updated: $Date: 2008/12/17 00:24:47 $


© Copyright 2000-2008 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_readme.html0000644000175000017500000000542311531130626021736 0ustar frankiefrankie ProFTPD module mod_readme

ProFTPD module mod_readme



This module is contained in the mod_readme.c file for ProFTPD 1.3.x, and is not compiled by default. Installation instructions are discussed here.

The most current version of mod_readme is distributed with the ProFTPD source code.

Directives


DisplayReadme

Syntax: DisplayReadme path|pattern
Default: None
Context: server config, <VirtualHost>, <Global>, <Anonymous>
Module: mod_readme
Compatibility: 1.2.0pre8 and later

The DisplayReadme directive configures the server to notify the client of the last modified date of the specified path or pattern. These notifications happen whenever a client logs in, or whenever the client changes directory.

For example:

  DisplayReadme README
will result in the following being displayed to connecting client, assuming there is a file called "README" in the current directory:
Please read the file README it was last modified on Sun Oct 17 10:36:14 2011 - 0 days ago

As another example, assume there are two files named "README" and "README.first" in the directory into which the client changed. Then using

  DisplayReadme README*
might result in the following being sent to the client:
Please read the file README it was last modified on Tue Jan 25 04:47:48 2011 - 0 days ago Please read the file README.first it was last modified on Tue Jan 25 04:48:04 2011 - 0 days ago


Installation

To install mod_readme, follow the usual steps for using third-party modules in proftpd:
  ./configure --with-modules=mod_readme ...
  make
  make install

Alternatively, if your proftpd was compiled with DSO support, you can use the prxs tool to build mod_readme as a shared module:

  prxs -c -i -d mod_readme.c



Author: $Author: castaglia $
Last Updated: $Date: 2011/02/23 07:04:54 $


© Copyright 2011 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_dynmasq.html0000644000175000017500000000617710703447453022175 0ustar frankiefrankie ProFTPD module mod_dynmasq

ProFTPD module mod_dynmasq



The mod_dynmasq module is designed for those sites that use the MasqueradeAddress directive in conjunction with DNS names whose addresses periodically change, e.g. "dyndns" addresses. The proftpd daemon is not aware of any changes to the IP address for a MasqueradeAddress that happen after the daemon has started up. The mod_dynmasq module periodically checks all configured MasqueradeAddress directives and resolves their IP addresses, updating the stored addresses as needed.

This module is contained in the mod_dynmasq.c file for ProFTPD 1.2.10 and later, and is not compiled by default. Installation instructions are discussed here.

The most current version of mod_dynmasq is distributed with the proftpd source distribution.

Author

Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.

Directives


DynMasqRefresh

Syntax: DynMasqRefresh secs
Default: None
Context: "server config"
Module: mod_dynmasq
Compatibility: 1.2.10

The DynMasqRefresh directive configures the amount of time, in seconds, between mod_dynmasq's checking and updating of all MasqueradeAddress directives. If no DynMasqRefresh directive is configured, then the module will do no checking.

The process of resolving a DNS name to its IP address can, depending on the DNS configuration, take a noticeable amount of time. This, combined with the number of MasqueradeAddress directives in your proftpd.conf, can cause mod_dynmasq to make the daemon unavailable while it resolves all addresses. Therefore it is highly recommended that the configured interval be as long as possible, for example for 8 hours.

Example:

  <IfModule mod_dynmasq.c>
    # Refresh any configured MasqueradeAddress directives every 8 hours
    DynMasqRefresh 28800
  </IfModule>

See also:


Installation

To install the mod_dynmasq module, follow the usual steps for using third-party modules in proftpd:
  ./configure --with-modules=mod_dynmasq
  make
  make install



Author: $Author: castaglia $
Last Updated: $Date: 2007/10/11 16:28:27 $


© Copyright 2004-2007 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/index.html0000644000175000017500000002023712144724010020746 0ustar frankiefrankie ProFTPD Contrib Module Documentation

ProFTPD Contrib Module Documentation


The following is a collection of HTML documentation for modules and tools in the contrib/ directory of the ProFTPD source distribution.

    The ftpasswd script
    Used to easily create and manage AuthUserFiles and AuthGroupFiles

    The ftpquota script
    Used for creating and managing file-based tables for the mod_quotatab module

    The ftpmail script
    Used for automatically sending emails whenever a file is uploaded

    The mod_ban module
    For supporting automatic bans based on configurable thresholds

    The mod_ctrls_admin module
    Adds administrative controls actions for the ftpdctl program. Controls are covered in more detail in the Controls mini-HOWTO

    The mod_deflate module
    For suppporting MODE Z compression of data transfers

    The mod_dynmasq module
    For automatically refreshing IP addresses of dynamic DNS names

    The mod_exec module
    For executing external commands based on configurable criteria

    The mod_geoip module
    For looking up geographic information based on client IP address

    The mod_ifsession module
    For adding per-user/group/Class sections to your proftpd.conf file

    The mod_ifversion module
    For adding version-specific sections to your proftpd.conf file

    The mod_load module
    For configuring server availability based on system load

    The mod_log_forensic module
    For writing log messages only when configurable criteria are met

    The mod_qos module
    For configuring site-specific Quality of Service (QOS) packet values

    The mod_quotatab module
    Adds quota support for proftpd

    The mod_quotatab_file module
    This is one of the supporting modules for mod_quotatab which handles quota tables that are stored in specially formatted files on disk

    The mod_quotatab_ldap module
    This one of the supporting modules for mod_quotatab which handles reading quota limits from LDAP directories

    The mod_quotatab_sql module
    This is one of the supporting modules for mod_quotatab which handles quota tables that are stored in SQL databases

    The mod_radius module
    Provides support for authenticating users using the RADIUS protocol

    The mod_readme module
    Displays messages reminding users to read README files

    The mod_rewrite module
    Adds the ability to rewrite FTP commands sent by clients on-the-fly, using regular expression matching and substitution

    The mod_sftp module
    Supports SSH2 authentication, SFTP and SCP transfers

    The mod_sftp_pam module
    Supports SSH2 authentication via PAM

    The mod_sftp_sql module
    Supports storage/retrieval of authorized SSH keys using SQL databases

    The mod_shaper module
    Adds dynamic traffic shaping based on number of concurrent sessions and transfers

    The mod_site_misc module
    Adds support for miscellaneous SITE commands such as SITE MKDIR, SITE SYMLINK, and SITE UTIME

    The mod_snmp module

    Provides SNMPv2 monitoring capabilities.

    The mod_sql module
    Provides support for authenticating users using user information stored in SQL databases. Logging of various data into SQL tables is also supported.

    The mod_sql_passwd module
    Supports MD5, SHA1, SHA256, SHA512 encoded passwords in SQL databases

    The mod_tls module
    Adds the ability to encrypt the control and data connections using SSL/TLS

    The mod_tls_memcache module
    Provides SSL session caching, for faster SSL session negotiation, using a memcached servers for the shared cache

    The mod_tls_shmcache module
    Provides SSL session caching, for faster SSL session negotiation, using a shared memory cache

    The mod_unique_id module
    For generating a unique ID for every FTP session

    The mod_wrap module
    Supports using the /etc/hosts.allow and /etc/hosts.deny files, or other allow/deny files, for IP-based access control.

    The mod_wrap2 module
    Supports using the /etc/hosts.allow and /etc/hosts.deny files, or other allow/deny files, as well as SQL-based access rules, for IP-based access control.

    The mod_wrap2_file module
    This is one of the supporting modules for mod_wrap2 which handles access rules that are stored in specially formatted files on disk

    The mod_wrap2_sql module
    This is one of the supporting modules for mod_wrap2 which handles access rules that are stored in SQL database tables
If your question or issue is not covered by any of these pages, please send a request to the ProFTPD documentation list. Directions for subscribing to the docs list, as well as the other ProFTPD mailing lists, are at:
  http://www.proftpd.org/lists.html
If you are looking to see if ProFTPD supports a particular feature, the first place to look as the complete list of configuration directives:
  http://www.proftpd.org/docs/directives/linked/by-name.html
The list may be intimidatingly long, but it is well worth scanning through all of the directives to see everything that ProFTPD is capable of supporting.


Last Updated: $Date: 2013/05/15 15:21:44 $

proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_quotatab_ldap.html0000644000175000017500000000551210546556151023332 0ustar frankiefrankie ProFTPD module mod_quotatab_ldap

ProFTPD module mod_quotatab_ldap



This mod_quotatab submodule is contained in the mod_quotatab_ldap.c, and is found in the contrib/ area of the ProFTPD source distribution. See the mod_quotatab installation instructions.

This submodule provides the LDAP-specific "driver" for retrieving quota limit table information from an LDAP server.

Author

Please contact John Morrissey <jwm at horde.net> with any questions, concerns, or suggestions regarding this module.


LDAP Limit Quota Tables

LDAP-based quota tables (source-type of "ldap") can only be used for limit tables, not for tally tables. The frequent updates needed for maintaining tally tables mean that LDAP is not well-suited to handle tally table storage.

The mod_quotatab_ldap module supports the "ldap" string for the source-type parameter of the QuotaLimitTable configuration directive.

To enable LDAP-provisioned limit tables, you need to configure mod_ldap to lookup the proper attribute using the LDAPDoQuotaLookups configuration directive.

The LDAP attribute to be looked up (named ftpQuota by default) should contain a comma-separated list of 8 values, in the following order:

  per_session, limit_type, bytes_in_avail, bytes_out_avail, bytes_xfer_avail,
    files_in_avail, files_out_avail, files_xfer_avail
For example:
  "false,hard,100,100,100,100,100,100"

An example proftpd.conf configuration might look like:

  <IfModule mod_quotatab.c>
    <IfModule mod_quotatab_ldap.c>
      # Enable LDAP quota lookups
      LDAPDoQuotaLookups on

      # Use an LDAP-based limit table.  Note that there is no additional
      # information supplied after the source-type: this is intentional. 
      # mod_ldap handles the rest.
      QuotaLimitTable ldap:
    </IfModule>

    # Use a file-based tally table
    QuotaTallyTable file:/usr/local/proftpd/ftpquota.tallytab
  </IfModule>


© Copyright 2003 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_radius.html0000644000175000017500000004452111616617166022007 0ustar frankiefrankie ProFTPD module mod_radius

ProFTPD module mod_radius



This module is contained in the mod_radius.c file for ProFTPD 1.2.x/1.3.x, and is not compiled by default. Installation instructions are discussed here.

This module is used to authenticate users using the RADIUS protocol. It can also be used to do logging via RADIUS accounting packets. A more in-depth discussion of the usage of this module follows the configuration directive documentation.

The most current version of mod_radius is distributed with the ProFTPD source code.

Author

Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.

Thanks

2002-06-26: Thanks to Josh Wilsdon <josh at wizard.ca> for correcting a bad assumption in the code that caused data corruption under some circumstances.

2002-12-18: Many thanks to Steffen Clausjuergens <stcl at clausjuergens.de> for helping to track down several bugs with accounting packets.

2003-03-20: Many thanks to Boris Kovalenko <boris at tagnet.ru > for testing many versions of the VSA code.

Directives


RadiusAcctServer

Syntax: RadiusAcctServer server[:port] shared-secret [timeout]
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_radius
Compatibility: 1.2.5rc2 and later

The RadiusAcctServer is used to specify a RADIUS server to be used for accounting. The server parameter may be either an IP address or a DNS hostname. If not specified, the port used will be the IANA-registered 1813. The optional timeout parameter is used to tell mod_radius how long to wait for a response from the server; it defaults to 30 seconds.

Multiple RadiusAcctServers may be configured; each will be tried, in order of appearance in the configuration file, until that server times out or mod_radius receives a response.

If no RadiusAcctServers are configured, mod_radius will not use RADIUS for accounting.

See also: RadiusAuthServer


RadiusAuthServer

Syntax: RadiusAuthServer server[:port] shared-secret [timeout]
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_radius
Compatibility: 1.2.5rc2 and later

The RadiusAuthServer is used to specify a RADIUS server to be used for authentication. The server parameter may be either an IP address or a DNS hostname. If not specified, the port used will be the IANA-registered 1812. The optional timeout parameter is used to tell mod_radius how long to wait for a response from the server; it defaults to 30 seconds.

Multiple RadiusAuthServers may be configured; each will be tried, in order of appearance in the configuration file, until that server times out or mod_radius receives a response.

If no RadiusAuthServers are configured, mod_radius will not use RADIUS for authentication.

See also: RadiusAcctServer


RadiusEngine

Syntax: RadiusEngine on|off
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_radius
Compatibility: 1.2.5rc2 and later

The RadiusEngine directive enables or disables the module's runtime RADIUS engine. If it is set to off this module does no RADIUS authentication or accounting at all. Use this directive to disable the module instead of commenting out all mod_radius directives.


RadiusGroupInfo

Syntax: RadiusGroupInfo primary-group-name suppl-group-names suppl-group-ids
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_radius
Compatibility: 1.2.9rc1 and later

The RadiusGroupInfo directive is used to configure group membership information used for every user authenticated via RADIUS. The primary-group-name parameter is used to configure the name that matches the user's GID (which can be configured via the RadiusUserInfo directive). The suppl-group-names and suppl-group-ids parameters are used to specify supplemental group membership for each user; the number of names and IDs must match if these parameters, each a comma-delimited list, are used. As many of ProFTPD's directives can operate based on group names, these textual group names may be important.

In order to support RADIUS servers that may use custom attributes in their Access-Accept response packets to supply user information back to the RADIUS client (mod_radius in this case), this directive allows the following syntax for some of its parameters:

  $(attribute-id:default-value)
where the enclosing $() signals that the parameter is to be supplied by the RADIUS server, attribute-id is the Vendor Specific Attribute (VSA) ID for which to search in the response packet, and default-value is the value to use in case the requested attribute is not present in the response packet. See the RadiusVendor directive description for more information about VSAs.

See Also: RadiusUserInfo, RadiusVendor


RadiusLog

Syntax: RadiusLog file|"none"
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_radius
Compatibility: 1.2.5rc2 and later

The RadiusLog directive is used to a specify a log file for mod_radius reporting and debugging, and can be done a per-server basis. The file parameter must be the full path to the file to use for logging. Note that this path must not be to a world-writeable directory and, unless AllowLogSymlinks is explicitly set to on (generally a bad idea), the path must not be a symbolic link.

If file is "none", no logging will be done at all; this setting can be used to override a RadiusLog setting inherited from a <Global> context.


RadiusNASIdentifier

Syntax: RadiusNASIdentifier id
Default: RadiusNASIdentifier ftp
Context: server config, <VirtualHost>, <Global>
Module: mod_radius
Compatibility: 1.3.1rc2 and later

The RadiusNASIdentifier directive configures an NAS identifier string that will be in the constructed RADIUS packets. By default, the NAS identifier is "ftp" for FTP sessions, and "ssh2" for SFTP/SCP sessions (via the mod_sftp module).

Example:

  RadiusNASIdentifier customID


RadiusQuotaInfo

Syntax: RadiusQuotaInfo per-sess limit-type bytes-in bytes-out bytes-xfer files-in files-out files-xfer
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_radius
Compatibility: 1.3.0rc1 and later QuotaLimitTable radius: QuotaTallyTable file:/home/tj/proftpd/devel/build/cvs/etc/ftpquota.tallytab RadiusEngine on RadiusAuthServer localhost:1812 testing123 5 RadiusLog /home/tj/proftpd/devel/build/cvs/etc/radius.log RadiusQuotaInfo false soft 3.0 2.0 1.0 7 8 9

The RadiusQuotaInfo directive is used to configure quota information used for every user. This information will be used, in conjunction with the mod_quotatab_radius module, for provisioning per-user quota information via RADIUS.

In order to support RADIUS servers that may use custom attributes in their Access-Accept response packets to supply user information back to the RADIUS client (mod_radius in this case), this directive allows the following syntax for some of its parameters:

  $(attribute-id:default-value)
where the enclosing $() signals that the parameter is to be supplied by the RADIUS server, attribute-id is the Vendor Specific Attribute (VSA) ID for which to search in the response packet, and default-value is the value to use in case the requested attribute is not present in the response packet. See the RadiusVendor directive description for more information about VSAs.

The RadiusQuotaInfo directive can be used to configure unchanging numbers, rather than custom attributes, if need be.

An example configuration might look like:

  <IfModule mod_quotatab_radius.c>
    QuotaLimitTable radius:
    QuotaTallyTable file:/home/tj/proftpd/devel/build/cvs/etc/ftpquota.tallytab

    # mod_radius attributes
    RadiusEngine on
    RadiusAuthServer localhost:1812 testing123 5
    RadiusLog /var/ftpd/log/radius.log

    # This sets unchanging quota limit values, rather than using custom attributes 
    # from a RADIUS server
    RadiusQuotaInfo false soft 3.0 2.0 1.0 7 8 9

  </IfModule>

See Also: RadiusVendor


RadiusRealm

Syntax: RadiusRealm realm
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_radius
Compatibility: 1.2.5rc2 and later

The RadiusRealm directive configures a realm string that will be added to the username in the constructed RADIUS packets.

Example:

  RadiusRealm .castaglia.org


RadiusUserInfo

Syntax: RadiusUserInfo uid gid home shell
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_radius
Compatibility: 1.2.5rc2 and later

The RadiusUserInfo directive is used to configure login information used for every user authenticated via RADIUS. Group membership information can be configured by using the RadiusGroupInfo directive.

In order to support RADIUS servers that may use custom attributes in their Access-Accept response packets to supply user information back to the RADIUS client (mod_radius in this case), this directive allows the following syntax for some of its parameters:

  $(attribute-id:default-value)
where the enclosing $() signals that the parameter is to be supplied by the RADIUS server, attribute-id is the Vendor Specific Attribute (VSA) ID for which to search in the response packet, and default-value is the value to use in case the requested attribute is not present in the response packet. See the RadiusVendor directive description for more information about VSAs.

If RadiusUserInfo is not used, mod_radius will perform pure "yes/no" authentication only, in the style of PAM. The information that would have been configured via this directive will be pulled from other sources (e.g. /etc/passwd, AuthUserFiles, MySQL tables, etc).

See Also: RadiusGroupInfo, RadiusVendor


RadiusVendor

Syntax: RadiusVendor name id
Default: RadiusVendor Unix 4
Context: server config, <VirtualHost>, <Global>
Module: mod_radius
Compatibility: 1.2.9rc1 and later

The RadiusVendor directive is used to configure the vendor name and ID for which mod_radius will search when it looks for vendor-specific attributes in RADIUS response packets.

Earlier versions of mod_radius could be configured to look up custom RADIUS attributes by normal RADIUS attribute type IDs. However, those normal IDs can only be from 0 to 255, putting a limit on the number of such custom attributes. Fortunately, the RADIUS RFCs define a specific attribute ID, 26, for vendor-specific attributes. The values for such attributes contains an ID for the specific vendor, and then the vendor-specific attribute. The vendor IDs come from the IANA's enterprise numbers hierarchy:

  http://www.iana.org/assignments/enterprise-numbers

By default, mod_radius will look for a vendor ID of 4 (Unix); this configuration directive is used to tell mod_radius to expect a different vendor.


Usage

Strong authentication is in demand for Internet services. For many, this means using the RADIUS (Remote Authentication Dial-In User Service) protocol.

However, there are caveats to using RADIUS for authentication. RADIUS packets are sent in the clear, which means that they can easily be sniffed. First, do not have your authenticating RADIUS servers exposed to the Internet; keep them protected within your LAN. Second, it is highly recommended to use separate RADIUS servers for each of your services.

RADIUS Authentication
The RADIUS protocol can be used for answering the question "Should this user be allowed to login?" However, the "yes/no" answer is not everything that proftpd needs to log a user in; the server also requires the UID and GID to use for the authenticated user, home directory, and shell. This information is usually not available from the RADIUS servers, which means that using RADIUS to provide all the necessary login information can be problematic. The RadiusUserInfo directive is meant to be used to address this issue, to provide the missing information.

In those cases where the RADIUS servers can provide that additional login information, via custom attributes, the RadiusUserInfo directive can also be used obtain that information as well.

RADIUS Accounting
While RADIUS is primarily used for authentication, the protocol also allows for accounting of user activities. The mod_radius module makes use of this ability, using RADIUS accounting packets to transmit the following data:

  • Acct-Authentic: How the user was authenticated (e.g. locally, or via RADIUS)

  • Acct-Session-Id: The process ID of the FTP session

  • Acct-Session-Time: The duration of the FTP session, in seconds

  • Acct-Input-Octets: The number of bytes uploaded (includes appending to files)

  • Acct-Output-Octets: The number of bytes downloaded

Merely configuring a RadiusAcctServer enables the module's accounting capabilities.

Common Attributes
The following RADIUS attributes are sent with every RADIUS packet generated by mod_radius:

  • User-Name: The name of the logging-in user

  • NAS-Identifier: "ftp" (or "ssh2" for SFTP/SCP sessions)

  • NAS-IP-Address or NAS-IPv6-Address: IP address of server

  • NAS-Port: Port of server

  • NAS-Port-Type: Always Virtual.

  • Calling-Station-Id: IP address of connecting client


Installation

The mod_radius module is distributed with ProFTPD. Simply follow the normal steps for using third-party modules in proftpd:
  ./configure --with-modules=mod_radius
  make
  make install



Author: $Author: castaglia $
Last Updated: $Date: 2011/08/04 22:34:30 $


© Copyright 2000-2011 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_tls_shmcache.html0000644000175000017500000001046311503772411023141 0ustar frankiefrankie ProFTPD module mod_tls_shmcache

ProFTPD module mod_tls_shmcache


The mod_tls_shmcache submodule is contained in the mod_tls_shmcache.c file, and is not compiled by default. Installation instructions are discussed here.

This submodule provides a SysV shared memory-based implementation of an external SSL session cache for use by the mod_tls module's TLSSessionCache directive.

This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/).

This product includes cryptographic software written by Eric Young (eay@cryptsoft.com).

Author

Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.

The mod_tls_shmcache module supports the "shm" string for the type parameter of the TLSSessionCache configuration directive. The info parameter for mod_tls_shmcache must be formatted like:

  /file=/path/to/cache/file[&size=bytes]
The configured path is used for synchronizing access to the shared memory segment among the various server processes. The default shared memory segment size allocated is 1.5MB; use the optional size key to configure a different size, in bytes. Note that the configured size must be able to hold at least one cached session; if a too-small size is configured, that size will be ignored and the default size will be used.

Examples

Use the default shared memory segment size and timeout:

  <IfModule mod_tls.c>
    ...

    <IfModule mod_tls_shmcache.c>
      TLSSessionCache shm:/file=/var/ftpd/sesscache
    </IfModule>
  </IfModule>

Use a larger shared memory segment size:

  <IfModule mod_tls.c>
    ...

    <IfModule mod_tls_shmcache.c>
      TLSSessionCache shm:/file=/var/ftpd/sesscache&size=2097152
    </IfModule>
  </IfModule>

Use a smaller shared memory size, and a shorter timeout:

  <IfModule mod_tls.c>
    ...

    <IfModule mod_tls_shmcache.c>
      TLSSessionCache shm:/file=/var/ftpd/sesscache&size=512000 600
    </IfModule>
  </IfModule>


Installation

The mod_tls_shmcache module is distributed with the ProFTPD source code. Simply follow the normal steps for using third-party modules in proftpd, being sure to include the mod_tls module (on which mod_tls_shmcache depends):
  ./configure --with-modules=mod_tls:mod_tls_shmcache
  make
  make install

Alternatively, if your proftpd was compiled with DSO support, you can use the prxs tool to build mod_tls_shmcache as a shared module:

  prxs -c -i -d mod_tls_shmcache.c


Usage

Frequently Asked Questions

Question: I configured a TLSSessionCache file, but it is empty. Is mod_tls_shmcache not working properly?
Answer: Yes, mod_tls_shmcache is working properly. The actual cache of SSL/TLS session data is stored in shared memory, not on the filesystem. Storing data in system shared memory requires a unique key; the mod_tls_shmcache uses the configured file to create this unique key. The module also uses the configured TLSSessionCache file for locking, as when handling a ftpdctl request to clear the cache.


Author: $Author: castaglia $
Last Updated: $Date: 2010/12/21 00:30:01 $

© Copyright 2009-2010 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_quotatab_file.html0000644000175000017500000000502612107217354023323 0ustar frankiefrankie ProFTPD module mod_quotatab_file

ProFTPD module mod_quotatab_file



This mod_quotatab submodule is contained in the mod_quotatab_file.c, and is found in the contrib/ area of the ProFTPD source distribution. See the mod_quotatab
installation instructions.

This submodule provides the file-specific "driver" for storing quota table information in files.

Author

Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.


File Quota Tables

Using file-based quota tables (source-type of "file") the data will be stored in binary fixed-record format. This module is accompanied by a tool, ftpquota, to help in creating and managing these file-based tables.

The mod_quotatab_file module supports the "file" string for the source-type parameter of the QuotaLimitTable and QuotaTallyTable configuration directives. If the "file" source-type is used, then the source-info parameter must be the full path to the file table.

mod_quotatab_file treats any number zero or less for a bytes limit as "unlimited". Similarly, it treats a value of zero for any of the files limits as "unlimited". "Unlimited" values are ignored, in that any limit that is "unlimited" is not used in any of mod_quotatab's calculations.

Examples:

  # Using a file-based limit table
  QuotaLimitTable file:/usr/local/proftpd/ftpquota.limittab

  # Using a file-based tally table
  QuotaTallyTable file:/usr/local/proftpd/ftpquota.tallytab



Author: $Author: castaglia $
Last Updated: $Date: 2013/02/14 17:29:16 $


© Copyright 2000-2013 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/ftpasswd.html0000644000175000017500000003470512062467733021516 0ustar frankiefrankie ftpasswd: tool for ProFTPD's AuthUserFile, AuthGroupFile, UserPassword

ftpasswd: tool for ProFTPD's AuthUserFile, AuthGroupFile, UserPassword



This program is used to create and manage files, correctly formatted, suitable for use with ProFTPD's AuthUserFile and AuthGroupFile configuration directives. It can also generate password hashes for ProFTPD's UserPassword directive.

The most current version of ftpasswd can be found at:

  http://www.castaglia.org/proftpd/

Author

Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this program.



Usage

The following describes the common usage of the ftpasswd tool. The options supported are described in more detail later.

This script is intended to replace the genuser.pl script that is currently distributed with proftpd. That script can generate DES-hashed passwords, suitable for use with the UserPassword configuration directive, but it is not quite right for AuthUserFiles. Another common mistake is to use the htpasswd program from Apache to create files for proftpd. Apache and ProFTPD both have the same AuthUserFile and AuthGroupFile directives; the format of the files used by each server is different.

Creating Files
The ftpasswd program can create and update files for both AuthUserFile and AuthGroupFile. When it is used for the first time, the program will create the necessary file. If that file already exists, ftpasswd will update it with the new information.

ftpasswd must first know what type of file to create. Use either the --passwd option (for handling AuthUserFiles), or the --group option (for handling AuthGroupFiles); this is required.

When creating an AuthUserFile, the following options are also required: --name, --uid, --home, and --shell. This information is required by proftpd to authenticate a user. The optional parameters for an AuthUserFile include --gid (defaults to the given --uid argument when not provided) and --gecos (not used by proftpd at all). For example:

  ftpasswd --passwd --name=bob --uid=1001 --home=/home/bob --shell=/bin/false
creates an account for user bob. To create a file with a name or location other than the default (which, for --passwd mode is ftpd.passwd), use the --file option. For example, to create the alternate password file in /usr/local/etc/ftpd/passwd:
  ftpasswd --passwd --file=/usr/local/etc/ftpd/passwd --name=bob --uid=1001 --home=/home/bob \
    --shell=/bin/false

For AuthGroupFiles, use --group:

  ftpasswd --group --name=group-name --gid=group-id --member=user-member1  \
    --member=user-member2 ... --member=user-memberN

The most common change to these files is made to AuthUserFiles, to change a user's password. The --change-password option was provided just for this scenario:

  ftpasswd --passwd --name=user --change-password

Creating Hashes
A less common need is to generate a password hash for some user, to be used in a UserPassword directive in the proftpd.conf. One could generate a file using --passwd and then extract the password hash from the file. Easier, though, is to use ftpasswd's --hash option:

  ftpasswd --hash
The password will either be prompted for, or it can be given on standard in using --stdin.

Automated Use
The ftpasswd provides a useful command-line interface to interacting with the authentication files. Many sites would like to be able to remotely manipulate these files, just as ftpasswd does, only using a web-based mechanism, perhaps even providing a page to users to change their passwords, instead of requiring use of a shell. Wrapping a shell or Perl script around ftpasswd is the logical solution.

To aid such automated wrapper scripts, ftpasswd has two features: its return value, and a specific option. The program returns 0 if the requested change was successful, and 1 if there was an error (no such user/group, password matched system password and the --not-system-password option was used, etc.). The specific option is --stdin: this allows scripts to provide a password to ftpasswd without prompting for a password. For example:

  echo passwd-variable | ftpasswd opts --stdin
Note that the --stdin option does not allow passwords to be passed to the script on the command line, but on stdin. This is done as a security measure: the standard Unix ps command can be used to show all the processes running on a system including their command line parameters. This means that any user could use ps to watch passwords given to ftpasswd, if those passwords were to be passed on the command line. Some operating systems (e.g. FreeBSD) allow the sysadmin to prevent users from seeing all processes in this manner; consult your operating system documentation for more information.

There are other issues that arise when using AuthUserFiles. This document discusses these issues in greater detail.



Options

The following is the output from running ftpasswd --help:
usage: ftpasswd [--help] [--hash|--group|--passwd]

  REQUIRED: --passwd, --group, or --hash.  These specify whether ftpasswd is to
  operate on a passwd(5) format file, on a group(5) format file, or simply
  to generate a password hash, respectively.

  If used with --passwd, ftpasswd creates a file in the passwd(5) format,
  suitable for use with proftpd's AuthUserFile configuration directive.
  You will be prompted for the password to use of the user, which will be
  encrypted, and written out as the encrypted string.  New entries are
  appended to the file by default.
 
  By default, using --passwd will write output to "./ftpd.passwd".

  Error exit values:

  To make it easier for wrapper scripts to interact with ftpasswd, ftpasswd
  will exit with the following error values for the reasons described:

    1       no such user
    2       password matches current password
    4       password matches system password
    8       relative path given for home directory

  Options:

    --file      Write output to specified file, rather than "./ftpd.passwd"

    -F          If the file to be used already exists, delete it and write a
    --force     new one.  By default, new entries will be appended to the file.

    --gecos     Descriptive string for the given user (usually the user's
                full name).

    --gid       Primary group ID for this user (optional, will default to
                given --uid value if absent)

    -h          Displays this message
    --help

    --home      Home directory for the user (required)

    --des       Use the DES algorithm for encrypting passwords.  The default
                is the MD5 algorithm.

    --md5       Use the MD5 algorithm for encrypting passwords.  This is the
                default.

    --name      Name of the user account (required).  If the name does not
                exist in the specified output-file, an entry will be created
                for her.  Otherwise, the given fields will be updated.

    --shell     Shell for the user (required).  Recommended: /bin/false

    --uid       Numerical user ID (required)

    --change-password

                Update only the password field for a user.  This option
                requires that the --name and --passwd options be used, but no
                others.  This also double-checks the given password against
                the user's current password in the existing passwd file, and
                requests that a new password be given if the entered password
                is the same as the current password.

    --delete-user
 
                Remove the entry for the given user name from the file.

    --not-previous-password

                Double-checks the given password against the previous password
                for the user, and requests that a new password be given if
                the entered password is the same as the previous password.

    --not-system-password

                Double-checks the given password against the system password
                for the user, and requests that a new password be given if
                the entered password is the same as the system password.  This
                helps to enforce different passwords for different types of
                access.

    --sha256    Use the SHA-256 algorithm for encrypting passwords.

    --sha512    Use the SHA-512 algorithm for encrypting passwords.

    --stdin
                Read the password directly from standard in rather than
                prompting for it.  This is useful for writing scripts that
                automate use of ftpasswd.

    --use-cracklib
                Causes ftpasswd to use Alec Muffet's cracklib routines in
                order to determine and prevent the use of bad or weak
                passwords.  The optional path to this option specifies
                the path to the dictionary files to use -- default path
                is "/usr/lib/cracklib_dict".  This requires the Perl
                Crypt::Cracklib module to be installed on your system.

    --version
                Displays the version of ftpasswd.

  If used with --group, ftpasswd creates a file in the group(5) format,
  suitable for use with proftpd's AuthGroupFile configuration directive.

  By default, using --group will write output to "./ftpd.group".

  Options:

    --delete-group

                Remove the entry for the given group name from the file.

    --enable-group-passwd

                Prompt for a group password.  This is disabled by default,
                as group passwords are not usually a good idea at all.

    --file      Write output to specified file, rather than "./ftpd.group"

    -F          If the file be used already exists, delete it and write a new
    --force     one.  By default, new entries will be appended to the file.

    --gid       Numerical group ID (required)

    -h
    --help      Displays this message

    -m
    --member    User to be a member of the group.  This argument may be used
                multiple times to specify the full list of users to be members
                of this group.

    --des       Use the DES algorithm for encrypting passwords.  The default
                is the MD5 algorithm.

    --md5       Use the MD5 algorithm for encrypting passwords.  This is the
                default.

    --name      Name of the group (required).  If the name does not exist in
                the specified output-file, an entry will be created for them.
                Otherwise, the given fields will be updated.

    --sha256    Use the SHA-256 algorithm for encrypting passwords.

    --sha512    Use the SHA-512 algorithm for encrypting passwords.

    --stdin
                Read the password directly from standard in rather than
                prompting for it.  This is useful for writing scripts that
                automate use of ftpasswd.

    --use-cracklib
                Causes ftpasswd to use Alec Muffet's cracklib routines in
                order to determine and prevent the use of bad or weak
                passwords.  The optional path to this option specifies
                the path to the dictionary files to use -- default path
                is "/usr/lib/cracklib_dict".  This requires the Perl
                Crypt::Cracklib module to be installed on your system.

    --version
                Displays the version of ftpasswd.

  If used with --hash, ftpasswd generates a hash of a password, as would
  appear in an AuthUserFile.  The hash is written to standard out.
  This hash is suitable for use with proftpd's UserPassword directive.

  Options:

    --des       Use the DES algorithm for encrypting passwords.  The default
                is the MD5 algorithm.

    --md5       Use the MD5 algorithm for encrypting passwords.  This is the
                default.

    --sha256    Use the SHA-256 algorithm for encrypting passwords.

    --sha512    Use the SHA-512 algorithm for encrypting passwords.

    --stdin
                Read the password directly from standard in rather than
                prompting for it.  This is useful for writing scripts that
                automate use of ftpasswd.

    --use-cracklib
                Causes ftpasswd to use Alec Muffet's cracklib routines in
                order to determine and prevent the use of bad or weak
                passwords.  The optional path to this option specifies
                the path to the dictionary files to use -- default path
                is "/usr/lib/cracklib_dict".  This requires the Perl
                Crypt::Cracklib module to be installed on your system.



Author: $Author: castaglia $
Last Updated: $Date: 2012/12/14 00:16:27 $


© Copyright 2000-2012 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_sftp_sql.html0000644000175000017500000001341011343260433022330 0ustar frankiefrankie ProFTPD module mod_sftp_sql

ProFTPD module mod_sftp_sql



The mod_sftp module for ProFTPD can support different storage formats for its user- and host-based authorized keys. By default, the mod_sftp module supports storing authorized keys in flats. This mod_sftp_sql module allows for authorized SSH keys to be stored in SQL tables.

This module is contained in the mod_sftp_sql.c file for ProFTPD 1.3.x, and is not compiled by default. Installation instructions are discussed here. Examples of how to use the mod_sftp_sql module are available here.

The most current version of mod_sftp_sql is distributed with the ProFTPD source code.

This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/). This product includes cryptographic software written by Eric Young (eay@cryptsoft.com).

Author

Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.


Installation

To install mod_sftp_sql, copy the mod_sftp_sql.c file into:
  proftpd-dir/contrib/
after unpacking the latest proftpd-1.3.x source code. Then follow the usual steps for using third-party modules in proftpd, making sure to include the mod_sftp and mod_sql modules, which mod_sftp_sql requires. For example, if you use MySQL as your SQL database, then you might use:
  ./configure --with-modules=mod_sql:mod_sql_mysql:mod_sftp:mod_sftp_sql ...
  make
  make install



Usage

The mod_sftp_sql module works by using mod_sql's SQLNamedQuery ability to define a SQL SELECT statement which returns the requested key. Thus the mod_sftp_sql module has no configuration directives of its own.

To help demonstrate, see the example configuration below:

  <IfModule mod_sql.c>
    # Other mod_sql configuration here

    # Define a SELECT statement to retrieve users' authorized SSH keys
    SQLNamedQuery get-user-authorized-keys SELECT "key FROM sftpuserkeys WHERE name='%U'"

    # Define a SELECT statement to retrieve hosts' authorized SSH keys
    SQLNamedQuery get-host-authorized-keys SELECT "key FROM sftphostkeys WHERE host='%{0}'"
  </IfModule>

  <IfModule mod_sftp.c>
    SFTPEngine on
    SFTPLog /path/to/sftp.log

    # Host keys, for server host authentication
    SFTPHostKey /etc/ssh_host_dsa_key
    SFTPHostKey /etc/ssh_host_rsa_key

    <IfModule mod_sftp_sql.c> 
      # Instead of using a file-based key store, we tell mod_sftp to use
      # the SQL-based key store provided by mod_sftp_sql
      SFTPAuthorizedUserKeys sql:/get-user-authorized-keys
      SFTPAuthorizedHostKeys sql:/get-host-authorized-keys
    </IfModule>
  </IfModule>

What should the schema be, for the table which holds these authorized keys? The required columns are one for the key (as a single base64-encoded string) and one for the name of the entity owning that key, e.g. the user name or FQDN (or IP address) of the host. These columns can be added to existing tables you might have, or be part of a new table.

For example, using SQLite, you could do:

  # sqlite3 sftp.db
  sqlite> CREATE TABLE sftpuserkeys (
  sqlite>  name TEXT NOT NULL,
  sqlite>  key BLOB NOT NULL
  sqlite> );
  sqlite> CREATE INDEX sftpuserkeys_idx ON sftpuserkeys (name);

  sqlite> CREATE TABLE sftphostkeys (
  sqlite>  host TEXT NOT NULL,
  sqlite>  key BLOB NOT NULL
  sqlite> );
  sqlite> CREATE INDEX sftphostkeys_idx ON sftphostkeys (host);
and then configure mod_sql to use that sftp.db database file. The indices are a very good idea, especially if you have many rows and/or users. And for good data hygiene, adding a foreign key constraint on the sftpuserkeys.name column to your normal users table is recommended.

An example MySQL schema looks like:

  CREATE TABLE sftpuserkeys (
    name VARCHAR(255) NOT NULL,
    key VARCHAR(255) NOT NULL
  );
  CREATE INDEX sftpuserkeys_idx ON sftpuserkeys (name);

  CREATE TABLE sftphostkeys (
    host VARCHAR(255) NOT NULL,
    key VARCHAR(255) NOT NULL
  );
  CREATE INDEX sftphostkeys_idx ON sftphostkeys (host);

Which leads to the next question: how can I transfer existing authorized SSH keys from their current flat files into the SQL tables? First, you need to make sure that the key is in the RFC4716 format, using:

  # ssh-keygen -e -f /path/to/key.pub
Then simply add the output data to your SQL table (e.g. to the sftpuserkeys.key column in the above example schema).

Other databases (e.g. MySQL, Postgres, Oracle, etc) have bulk data loading tools which can also be used to load a CSV file containing keys into your SQL tables, for use via mod_sftp_sql.



Author: $Author: castaglia $
Last Updated: $Date: 2010/03/02 19:03:55 $


© Copyright 2009-2010 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_log_forensic.html0000644000175000017500000002411012111516713023144 0ustar frankiefrankie ProFTPD module mod_log_forensic

ProFTPD module mod_log_forensic



The mod_log_forensic module "captures" log messages generated by proftpd, for all sorts of log destinations, even if those log messages would otherwise not be written out, and buffers them in memory. When certain criteria are met (e.g. failed logins, segfaults, etc), the mod_log_forensic module will flush the buffered log messages out to a file. Installation instructions are discussed here.

The most current version of mod_log_forensic can be found at:

  http://www.castaglia.org/proftpd/

Author

Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.

Directives


ForensicLogBufferSize

Syntax: ForensicLogBufferSize count
Default: 1024
Context: server config, <VirtualHost>, <Global>
Module: mod_log_forensic
Compatibility: 1.3.4rc3 and later

The ForensicLogBufferSize directives configures the count of log messages that mod_log_forensic will buffer. It is effectively the count of the last count log messages you wish to see logged, when one of the ForensicLogCriteria are met.


ForensicLogCapture

Syntax: ForensicLogCapture log-type1 ...
Default: Unspec TransferLog syslog SystemLog ExtendedLog TraceLog
Context: server config, <VirtualHost>, <Global>
Module: mod_log_forensic
Compatibility: 1.3.4rc3 and later

The ForensicLogCapture directive configures which log types the mod_log_forensic module "captures" for later writing. By default, mod_log_forensic captures messages for all log types.

The supported log types are:

  • Unspec

    This "type" covers any unspecified/unknown log, e.g. module-specific log files such as SFTPLog, SQLLogFile, TLSLog, etc.

  • TransferLog
  • syslog
  • SystemLog
  • ExtendedLog
  • TraceLog


ForensicLogCriteria

Syntax: ForensicLogCriteria criterion1 ...
Default: FailedLogin UntimelyDeath
Context: server config, <VirtualHost>, <Global>
Module: mod_log_forensic
Compatibility: 1.3.4rc3 and later

The ForensicLogCriteria directive configures the criteria which determine when mod_log_forensic will flush its buffered log messages out to the configured ForensicLogFile. Multiple criteria can be specified.

The currently supported criteria are:

  • FailedLogin

    The buffered log messages will be written to the ForensicLogFile if the login fails for any reason.

  • UntimelyDeath

    If a session dies prematurely, e.g. due to a segfault or other internal error, the buffered log messages will be written to the ForensicLogFile.

  • ModuleConfig

    If a session dies due to a module-specific policy, the buffered log messages will be written to the ForensicLogFile.


ForensicLogEngine

Syntax: ForensicLogEngine on|off
Default: off
Context: server config, <VirtualHost>, <Global>
Module: mod_log_forensic
Compatibility: 1.3.4rc3 and later

The ForensicLogEngine directive enables or disables the mod_log_forensic module.


ForensicLogFile

Syntax: ForensicLogFile file
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_log_forensic
Compatibility: 1.3.4rc3 and later

The ForensicLogFile directive configures a file used for logging by mod_log_forensic. The configured file must be an absolute path.

Note that this directive is required for mod_log_forensic to function properly.


Installation

To install mod_log_forensic, copy the mod_log_forensic.c into the third-party module directory in the proftpd source code:
  # cp mod_log_forensic.c proftpd-dir/contrib/
after unpacking the latest proftpd-1.3.x source code. For including mod_log_forensic as a staticly linked module:
  ./configure --with-modules=mod_log_forensic ...
Alternatively, mod_log_forensic can be built as a DSO module:
  ./configure --enable-dso --with-shared=mod_log_forensic ...
Then follow the usual steps:
  make
  make install


Usage

Example mod_log_forensic configuration:

  <IfModule mod_log_forensic.c>
    ForensicLogEngine on
    ForensicLogFile /path/to/forensic.log
  </IfModule>

For a failed login, the configured ForensicLogFile will contain a block of log lines, e.g.:

  -----BEGIN FAILED LOGIN FORENSICS-----
  Client-Address: 127.0.0.1
  Server-Address: ::ffff:127.0.0.1:5376
  Elapsed: 1245
  Protocol: ftp
  User: tj
  UID: 501
  GID: 501
  Raw-Bytes-In: 46
  Raw-Bytes-Out: 158
  Total-Bytes-In: 0
  Total-Bytes-Out: 0
  Total-Files-In: 0
  Total-Files-Out: 0

  ...
  [syslog:7, PID 16044] dispatching CMD command 'PASS (hidden)' to mod_auth
  [syslog:7, PID 16044] retrieved UID 1000 for user 'tj'
  [syslog:7, PID 16044] retrieved group IDs: 1000, 0, 4, 20, 24, 46, 108, 109, 110
  [syslog:7, PID 16044] retrieved group names: tj, root, adm, dialout, cdrom, plugdev, lpadmin, sambashare, admin
  [syslog:7, PID 16044] ROOT PRIVS at mod_auth_pam.c:312
  [syslog:7, PID 16044] RELINQUISH PRIVS at mod_auth_pam.c:482
  [syslog:7, PID 16044] ROOT PRIVS at mod_auth_unix.c:467
  [syslog:7, PID 16044] RELINQUISH PRIVS at mod_auth_unix.c:548
  [SystemLog:5] familiar proftpd[15509] localhost (localhost[127.0.0.1]): USER tj (Login failed): Incorrect password.
  [syslog:7, PID 16044] dispatching POST_CMD_ERR command 'PASS (hidden)' to mod_delay
  [syslog:7, PID 16044] dispatching LOG_CMD_ERR command 'PASS (hidden)' to mod_log
  -----END FAILED LOGIN FORENSICS-----
For sessions which suffer an "untimely death", the begin/end markers in the ForensicLogFile are:
  -----BEGIN UNTIMELY DEATH FORENSICS-----
  Client-Address: 127.0.0.1
  Server-Address: ::ffff:127.0.0.1:5376
  Elapsed: 1245
  Protocol: ftp
  User: tj
  UID: 501
  GID: 501
  Raw-Bytes-In: 46
  Raw-Bytes-Out: 158
  Total-Bytes-In: 0
  Total-Bytes-Out: 0
  Total-Files-In: 0
  Total-Files-Out: 0

  ...
  -----END UNTIMELY DEATH FORENSICS-----

Advantages
What's the big deal with this module? What advantage does it provide over the normal proftpd logging? The advantage is that with mod_log_forensic, you do not have to configure ProFTPD to use verbose logging (i.e. high DebugLevel and/or Trace levels). If ProFTPD generated a log message internally but that log message was filtered, then that log message would not normally be written to disk -- but mod_log_forensic buffers that log message anyway.

To see this, simply use the following in your proftpd.conf:

  TraceLog /path/to/ftpd/trace.log
  Trace DEFAULT:0

  <IfModule mod_log_forensic.c>
    ForensicLogEngine on
    ForensicLogFile /path/to/ftpd/forensic.log
  </IfModule>
This configured proftpd for trace logging, but turns the trace logging levels down to zero so that normally, nothing would be written in the configured TraceLog file.

Now attempt to log into proftpd, deliberately using a wrong/bad password (or unknown user). The mod_log_forensic module will write out all of the trace logging messages (and the other SystemLog/syslog messages) to the ForensicLogFile, even though the debug level is at the default level of zero, and the trace levels are all zero. Thus you get the verbose logging needed to help diagnose failed logins and such, without having the verbose logging enabled all of the time.



Author: $Author: castaglia $
Last Updated: $Date: 2013/02/21 22:20:59 $


© Copyright 2011-2013 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_copy.html0000644000175000017500000000641111345770413021460 0ustar frankiefrankie ProFTPD module mod_copy

ProFTPD module mod_copy



The mod_copy module implements SITE CPFR and SITE CPTO commands (analogous to RNFR and RNTO), which can be used to copy files/directories from one place to another on the server without having to transfer the data to the client and back.

This module is contained in the mod_copy.c file for ProFTPD 1.3.x, and is not compiled by default. Installation instructions are discussed here.

The most current version of mod_copy can be found at:

  http://www.castaglia.org/proftpd/

Author

Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.

SITE Commands


SITE CPFR

This SITE command specifies the source file/directory to use for copying from one place to another directly on the server.

The syntax for SITE CPFR is:

  SITE CPFR source-path

See also: SITE CPTO


SITE CPTO

This SITE command specifies the destination file/directory to use for copying from one place to another directly on the server.

The syntax for SITE CPTO is:

  SITE CPTO destination-path 

A client wishing to copy a file/directory first sends a SITE CPFR command, then a SITE CPTO; this is similar to how renames are handled using RNFR and RNTO.

Use of these SITE command can be controlled via <Limit> sections, e.g.:

  <Limit SITE_COPY>
    AllowUser alex
    DenyAll
  </Limit>

See also: SITE CPFR


Installation

To install mod_copy, copy the mod_copy.c file into:
  proftpd-dir/contrib/
after unpacking the latest proftpd-1.3.x source code. For including mod_copy as a staticly linked module:
  ./configure --with-modules=mod_copy
To build mod_copy as a DSO module:
  ./configure --enable-dso --with-shared=mod_copy
Then follow the usual steps:
  make
  make install

For those with an existing ProFTPD installation, you can use the prxs tool to add mod_copy, as a DSO module, to your existing server:

  # prxs -c -i -d mod_copy.c



Author: $Author: castaglia $
Last Updated: $Date: 2010/03/10 19:20:43 $


© Copyright 2009-2010 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_sql_sqlite.html0000644000175000017500000000626111222172576022671 0ustar frankiefrankie ProFTPD module mod_sql_sqlite

ProFTPD module mod_sql_sqlite



SQLite is a lightweight embeddable database system that is gaining in popularity. More details can be found here:

  http://www.sqlite.org

The mod_sql_sqlite module is designed to let ProFTPD's mod_sql module connect to and use a SQLite database. This module is contained in the mod_sql_sqlite.c file for ProFTPD 1.3.x, and is not compiled by default. Installation instructions are discussed here.

The most current version of mod_sql_sqlite is distributed with ProFTPD.

Author

Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.


Installation

The mod_sql_sqlite modules requires that SQLite be installed.

After installing SQLite, follow the usual steps for using contrib modules in proftpd, making sure to list mod_sql:

  ./configure --with-modules=mod_sql:mod_sql_sqlite
  make
  make install
You may need to specify the location of the SQLite header and library files in your configure command, e.g.:
  ./configure --with-modules=mod_sql:mod_sql_sqlite \
    --with-includes=/usr/local/sqlite/include \
    --with-libraries=/usr/local/sqlite/lib

Alternatively, if your proftpd was compiled with DSO support, you can use the prxs tool to build mod_sql_sqlite as a shared module:

  prxs -c -i -d mod_sql_sqlite.c


Usage

For the most part, mod_sql_sqlite requires little configuration. In the SQLConnectInfo directive, simply use the full path to the SQLite database file; no username or password are required. The SQLBackend provided by mod_sql_sqlite is "sqlite3".

For example:

  <IfModule mod_sql_sqlite.c>
    SQLBackend sqlite3
    SQLConnectInfo /path/to/ftpd.db
  </IfModule>

Note that due to the way that mod_sql_sqlite implements database transactions (e.g. INSERT and UPDATE SQL statements for SQLLog directives), SQLite-3.6.5 or later is required in order for mod_sql_sqlite to support SQLLog directives if DefaultRoot or <Anonymous> are used. (SQLite-3.6.5 and later support the MEMORY journal mode, which is needed for supporting the SQLLog directives in a chrooted process.)



Author: $Author: castaglia $
Last Updated: $Date: 2009/06/29 17:10:22 $


© Copyright 2004-2009 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_wrap2_sql.html0000644000175000017500000001630512144021047022411 0ustar frankiefrankie ProFTPD module mod_wrap2_sql

ProFTPD module mod_wrap2_sql


This mod_wrap2 submodule is contained in the mod_wrap2_sql.c file, and is not compiled by default. See the mod_wrap2 installation instructions.

This submodule provides the SQL database "driver" for storing IP/DNS-based access control information in SQL tables.

Author

Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.


SQL Access Tables

The mod_wrap2_sql module supports the "sql" string for the source-type parameter of the WrapUserTables, WrapGroupTables, and WrapTables, configuration directives. If the "sql" source-type is used, then the source-info parameter must be as described below. Note that support for SQL-based access tables requires the use of mod_sql.

mod_wrap2_sql requires two to four SQL-related configuration directives: SQLConnectInfo, and two, possibly four, SQLNamedQuery directives. The SQLConnectInfo is necessary to allow the module to connect to the SQL database. The other directives define the SQL queries that will be used by mod_wrap2 for its retrieval operations involving access data.

When using SQL tables and mod_sql, the access tables should appear in the database named by the SQLConnectInfo directive, which will probably also contain the authentication information tables. This way your proftpd-specific tables are kept together. Also, it is probably better to use a connection policy of PERSESSION, otherwise there will be more overhead associated with each new connection made to the database for each transaction.

One SQLNamedQuery is needed to SELECT access information from the allow table, and one to SELECT access information from the deny table. These queries should return a list of words, where each word is a host name, host address, pattern, or wildcard (see here for how these things are defined). Failure to define either of these SQLNamedQuery directives will cause an error during mod_wrap2_sql's operation.

Optionally, other SQLNamedQuery directives can be defined to look up access options from the allow and deny tables.

For SQL tables, the format for the WrapUserTables, WrapGroupTables, and WrapTables directives is:

  WrapTables sql:/allow-SQLNamedQuery[/allow-options-SQLNamedQuery] \
    sql:deny-SQLNamedQuery[/deny-options-SQLNamedQuery]
where the allow-options-SQLNamedQuery and deny-options-SQLNamedQuery portions of the string are optional.

SQL Access Tables Example
Here are example SQLNamedQuery directives to help demonstrate how the mod_sql hooks are used by mod_wrap2. These example SQL statements assume the existence of two tables: a wrapallow table that defines allowed clients, and a wrapdeny table that defines the denied clients.

  SQLNamedQuery get-allowed-clients SELECT "allowed FROM wrapallow WHERE name = '%{0}'"
  SQLNamedQuery get-denied-clients SELECT "denied FROM wrapdeny WHERE name = '%{0}'"
These define the SQL statements to return the required list of words. The %{0} meta sequence will be substituted with the name being looked up (e.g. user name for WrapUserTables, primary group name for WrapGroupTables, or the empty string for WrapTables). If the administrator wants to make use of access options, then queries for those options would need to be similarly defined:
  SQLNamedQuery get-allowed-options SELECT "options FROM wrapallow WHERE name = '%{0}'"
  SQLNamedQuery get-denied-options SELECT "options FROM wrapdeny WHERE name = '%{0}'"

Now, using the above defined queries, the table configuration directives would be:

  # Access tables for users (with options)
  WrapUserTables user1,user2 sql:/get-allowed-clients/get-allowed-options \
    sql:/get-denied-clients/get-denied-options

  # Access tables for groups (with options).  Note that this directive
  # uses the same SELECT queries used for looking up users.  If group
  # access information is in a different table, then separate group-specific
  # SQLNamedQuery directives will need to be used.
  WrapGroupTables group1,group2 sql:/get-allowed-clients/get-allowed-options \
    sql:/get-denied-clients/get-denied-options

  # Access tables for everyone else (without options)
  WrapTables sql:/get-allowed-clients sql:/get-denied-clients
One thing to keep in mind, however, is that the %{0} part of an SQL query will only be expanded with the client's USER argument for WrapUserTables queries. For WrapGroupTables queries, that %{0} will be expanded to contain the primary group name of the connecting client's USER. For WrapTables queries, an empty string is used. This means that the same query cannot often be easily reused.

Example Schema
Here are some example table schema for SQL-based access tables:

  • Allow table
      CREATE TABLE wrapallow (
        name VARCHAR(30),
        allowed VARCHAR(255) NOT NULL,
        options VARCHAR(255)
      );
    
      CREATE INDEX idx_wrapallow_name ON wrapallow.name;
    

  • Deny table
      CREATE TABLE wrapdeny (
        name VARCHAR(30),
        denied VARCHAR(255) NOT NULL,
        options VARCHAR(255)
      );
    
      CREATE INDEX idx_wrapdeny_name ON wrapdeny.name;
    

When constructing the client and options lists to return to mod_wrap2's access control engine, mod_wrap2_sql will parse each returned row separately, handling both comma- and space-limited names in a row, into client list items. This means that the administrator can store multiple client and option tokens in multiple rows, as in the above schema, or the administrator can choose to store all of the clients and/or options in a single row, in an appropriately formatted string.


Author: $Author: castaglia $
Last Updated: $Date: 2013/05/12 23:13:43 $


© Copyright 2000-2013 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_snmp.html0000644000175000017500000012510112144724010021447 0ustar frankiefrankie ProFTPD module mod_snmp

ProFTPD module mod_snmp



The mod_snmp module implements SNMPv1 and SNMPv2, for monitoring of proftpd statistics via SNMP.

The mod_snmp module does not currently support:

  • SNMPv3
  • AgentX
  • SNMP Set requests

The mod_snmp module is contained in the mod_snmp/ directory, is intended for ProFTPD 1.3.4rc3 and later, and is not compiled by default. Installation instructions are discussed here.

The most current version of mod_snmp can be found at:

  https://github.com/Castaglia/proftpd-mod_snmp

Author

Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.

Thanks

2013-01-09: Thanks to <cliles at capario.com> for testing out most of the mod_snmp features, requesting additional useful functionality, and providing OpenNMS support/examples.

Directives


SNMPAgent

Syntax: SNMPAgent master|agentx address[:port]
Default: None
Context: "server config"
Module: mod_snmp
Compatibility: 1.3.4rc3 and later

The SNMPAgent directive configures the mod_snmp module to act as a "master" SNMP agent/entity, or as an AgentX sub-agent. (Note that the AgentX capability is not currently implemented.)

The address parameter can be an IP address or a DNS name; this parameter configures the address/port on which mod_snmp will listen for UDP SNMP packets. By default, a port of 161 is assumed, use address:port to specify an alternate port, e.g.:

  SNMPAgent master localhost:1161

Note that the SNMPAgent directive is required.


SNMPCommunity

Syntax: SNMPCommunity community
Default: None
Context: "server config"
Module: mod_snmp
Compatibility: 1.3.4rc3 and later

The SNMPCommunity directive configures the community string (effectively a passphrase) used for authenticating SNMPv1 and SNMPv2 messages.

Note that the SNMPCommunity directive is required.


SNMPEngine

Syntax: SNMPEngine on|off
Default: off
Context: "server config"
Module: mod_snmp
Compatibility: 1.3.4rc3 and later

The SNMPEngine directive controls whether the mod_snmp will run as an SNMP agent, and handle SNMP messages.


SNMPLog

Syntax: SNMPLog file|"none"
Default: None
Context: "server config"
Module: mod_snmp
Compatibility: 1.3.4rc3 and later

The SNMPLog directive is used to specify a log file for mod_snmp's reporting. The file parameter given must be the full path to the file to use for logging.

Note that this path must not be to a world-writable directory and, unless AllowLogSymlinks is explicitly set to on (generally a bad idea), the path must not be a symbolic link.


SNMPNotify

Syntax: SNMPNotify address[:port]
Default: None
Context: "server config", <VirtualHost>, <Global>
Module: mod_snmp
Compatibility: 1.3.4rc3 and later

The SNMPNotify directive is used to specify the address of any SNMP manager that should receive any notification (i.e. SNMPv2 trap) that mod_snmp can generated. Read here for more details on the types of notifications that mod_snmp supports.

The address parameter can be an IP address or DNS name. By default, a port number of 162 is assumed. To specify the port number, use:

  SNMPNotify address:port

Multiple SNMPNotify directives can be configured; mod_snmp will send notifications to all of them.


SNMPOptions

Syntax: SNMPOptions opt1 ...
Default: None
Context: "server config"
Module: mod_snmp
Compatibility: 1.3.4rc3 and later

The SNMPOptions directive is used to configure various optional behaviors of mod_snmp.

Example:

  SNMPOptions RestartClearsCounters

The currently implemented options are:

  • RestartClearsCounters

    This option will cause mod_snmp to clear/reset every counter (except for the daemon.restartCount counter) whenever proftpd is restarted via the SIGHUP signal.


SNMPTables

Syntax: SNMPTables path
Default: None
Context: "server config"
Module: mod_snmp
Compatibility: 1.3.4rc3 and later

The SNMPTables directive is used to specify a directory that mod_snmp will use for storing its database files; these files are used for tracking the various statistics reported via SNMP.


Installation

To install mod_snmp, go to the third-party module area in the proftpd source code and unpack the mod_snmp source tarball:
  cd proftpd-dir/contrib/
  tar zxvf /path/to/mod_snmp-version.tar.gz
after unpacking the latest proftpd-1.3.4 (or later) source code. For including mod_snmp as a staticly linked module:
  ./configure --with-modules=mod_snmp ...
Alternatively, mod_snmp can be built as a DSO module:
  ./configure --enable-dso --with-shared=mod_snmp ...
Then follow the usual steps:
  make
  make install


Usage

Important Security Considerations
Do not configure mod_snmp to listen on a public Internet address. The information provided via mod_snmp can be used by attackers to gain more information about your running proftpd, including being able to determine whether their logins fail due to a wrong password (in which case, they know that that user name is valid) or not. It is highly recommended that you configure mod_snmp to only listen on internal/LAN addresses. Furthermore, you should employ a firewall rule that rejects any UDP packets from the public Internet to your proftpd instance.

SNMP Listening Process
When proftpd starts up with mod_snmp enabled, the mod_snmp module will fork a new process that acts as the SNMP agent, receiving and responding to all SNMP requests. This SNMP listening process automatically switches to the privileges configured by the User and Group directives, and will also automatically chroot itself to a subdirectory of the SNMPTables directory, after which all root privileges are permanently dropped.

Example Configuration
The mod_snmp module uses a UDP socket for listening for SNMP requests. Thus it does not require any separate <VirtualHost> sections, and does not interfere with the normal FTP operations.

Here is an example configuration for mod_snmp:

  <IfModule mod_snmp.c>
    SNMPEngine on
    SNMPLog /etc/proftpd/snmp/snmp.log

    # Configure the agent to listen on 1.2.3.4, port 161
    SNMPAgent master 1.2.3.4 161

    # Configure the SNMP community string
    SNMPCommunity MySnmpCommunity

    # Configure the directory that mod_snmp will use for its database files
    SNMPTables /var/proftpd/snmp
  </IfModule>

Access Controls for SNMP Messages
Since the SNMPv1/SNMPv2 does not have authentication of "users" as such, the normal user/group-based ACLs that can be configured in proftpd have no effect on SNMP messages.

In order to provide IP-based access control, then, the mod_snmp module supports a <Limit SNMP> section, like the following:

Example:

  <Limit SNMP>
    # Allow SNMP packets from 10.x.x.x and 127.0.0.1 addresses
    Allow from 10., 127.0.0.1
    DenyAll
  </Limit>
It is easy to spoof the source address for UDP packets, however. So it is far better (and more secure) to use a firewall to restrict which UDP packets can reach the mod_snmp address/port.

Logging
The mod_snmp module supports different forms of logging. The main module logging is done via the SNMPLog directive. For debugging purposes, the module also uses trace logging, via the module-specific "snmp" and "snmp.db" log channels. Thus for trace logging, to aid in debugging, you would use the following in your proftpd.conf:

  TraceLog /path/to/snmp-trace.log
  Trace snmp:20
This trace logging can generate large files; it is intended for debugging use only, and should be removed from any production configuration.

mod_snmp OIDs
Note that all mod_snmp OIDs begin with 1.3.6.1.4.1.17852.2.2. The ProFTPD column in the table below contains the ProFTPD versions where the OID is present.

 OID   Name   Type   ProFTPD   Description 
 *.1.1.0   daemon.software   STRING   1.3.4rc3+   Always "proftpd" 
 *.1.2.0   daemon.version   STRING   1.3.4rc3+   Version of proftpd 
 *.1.3.0   daemon.admin   STRING   1.3.4rc3+   Administrative contact, i.e. the ServerAdmin 
 *.1.4.0   daemon.uptime   TimeTicks   1.3.4rc3+   Uptime of the proftpd daemon 
 *.1.5.0   daemon.vhostCount   INTEGER   1.3.4rc3+   Number of vhosts (including "server config") configured 
 *.1.6.0   daemon.connectionCount   Gauge32   1.3.4rc3+   Number of current connections 
 *.1.7.0   daemon.connectionTotal   Counter32   1.3.4rc3+   Total number of connections since daemon started 
 *.1.8.0   daemon.connectionRefusedTotal   Counter32   1.3.4rc3+   Total number of connections refused 
 *.1.9.0   daemon.restartCount   Counter32   1.3.4rc3+   Total number of times daemon has been restarted 
 *.1.10.0   daemon.segfaultCount   Counter32   1.3.4rc3+   Total number of SIGSEGV occurrences 
 *.1.11.0   daemon.maxInstancesLimitCount   Counter32   1.3.4rc3+   Total number of times MaxInstances reached 
 *.2.1.0   timeouts.idleTimeoutTotal   Counter32   1.3.4rc3+   Total number of times TimeoutIdle was reached 
 *.2.2.0   timeouts.loginTimeoutTotal   Counter32   1.3.4rc3+   Total number of times TimeoutLogin was reached 
 *.2.3.0   timeouts.noTransferTimeoutTotal   Counter32   1.3.4rc3+   Total number of times TimeoutNoTransfer was reached 
 *.2.4.0   timeouts.stalledTimeoutTotal   Counter32   1.3.4rc3+   Total number of times TimeoutStalled was reached 
 *.3.1.1.0   ftp.sessions.sessionCount   Gauge32   1.3.4rc3+   Number of current FTP sessions 
 *.3.1.2.0   ftp.sessions.sessionTotal   Counter32   1.3.4rc3+   Total number of FTP sessions handled 
 *.3.1.3.0   ftp.sessions.commandInvalidTotal   Counter32   1.3.4rc3+   Total number of invalid FTP commands received 
 *.3.2.1.0   ftp.logins.loginTotal   Counter32   1.3.4rc3+   Total number of successful FTP logins 
 *.3.2.2.0   ftp.logins.loginFailedTotal   Counter32   1.3.4rc3+   Total number of failed FTP logins 
 *.3.2.3.0   ftp.logins.loginBadUserTotal   Counter32   1.3.4rc3+   Total number of failed FTP logins due to bad/wrong user name 
 *.3.2.4.0   ftp.logins.loginBadPasswordTotal   Counter32   1.3.4rc3+   Total number of failed FTP logins due to bad password 
 *.3.2.5.0   ftp.logins.loginGeneralErrorTotal   Counter32   1.3.4rc3+   Total number of failed FTP logins due to config/other issues 
 *.3.2.6.0   ftp.logins.anonLoginCount   Gauge32   1.3.4rc3+   Number of current anonymous FTP logins 
 *.3.2.7.0   ftp.logins.anonLoginTotal   Counter32   1.3.4rc3+   Total number of anonymous FTP logins 
 *.3.3.1.0   ftp.dataTransfers.dirListCount   Gauge32   1.3.4rc3+   Number of directories currently being listed via FTP 
 *.3.3.2.0   ftp.dataTransfers.dirListTotal   Counter32   1.3.4rc3+   Total number of directories listed via FTP 
 *.3.3.3.0   ftp.dataTransfers.dirListFailedTotal   Counter32   1.3.4rc3+   Total number of directory list failures via FTP 
 *.3.3.4.0   ftp.dataTransfers.fileUploadCount   Gauge32   1.3.4rc3+   Number of files currently being uploaded via FTP 
 *.3.3.5.0   ftp.dataTransfers.fileUploadTotal   Counter32   1.3.4rc3+   Total number of files uploaded via FTP 
 *.3.3.6.0   ftp.dataTransfers.fileUploadFailedTotal   Counter32   1.3.4rc3+   Total number of file upload failures via FTP 
 *.3.3.7.0   ftp.dataTransfers.fileDownloadCount   Gauge32   1.3.4rc3+   Number of files currently being downloaded via FTP 
 *.3.3.8.0   ftp.dataTransfers.fileDownloadTotal   Counter32   1.3.4rc3+   Total number of files downloaded via FTP 
 *.3.3.9.0   ftp.dataTransfers.fileDownloadFailedTotal   Counter32   1.3.4rc3+   Total number of file download failures via FTP 
 *.3.3.10.0   ftp.dataTransfers.kbUploadTotal   Counter32   1.3.4rc3+   Total number of KB uploaded via FTP 
 *.3.3.11.0   ftp.dataTransfers.kbDownloadTotal   Counter32   1.3.4rc3+   Total number of KB downloaded via FTP 
 *.4.1.0   snmp.packetsReceivedTotal   Counter32   1.3.4rc3+   Total number of SNMP packets received 
 *.4.2.0   snmp.packetsSentTotal   Counter32   1.3.4rc3+   Total number of SNMP packets sent 
 *.4.3.0   snmp.trapsSentTotal   Counter32   1.3.4rc3+   Total number of SNMP traps/notifications sent 
 *.4.4.0   snmp.packetsAuthFailedTotal   Counter32   1.3.4rc3+   Total number of SNMP packets failing authentication check 
 *.4.5.0   snmp.packetsDroppedTotal   Counter32   1.3.4rc3+   Total number of SNMP packets dropped 
 *.5.1.1.0   ftps.tlsSessions.sessionCount   Gauge32   1.3.4rc3+   Number of current FTPS sessions 
 *.5.1.2.0   ftps.tlsSessions.sessionTotal   Counter32   1.3.4rc3+   Total number of FTPS sessions handled 
 *.5.1.3.0   ftps.tlsSessions.ctrlHandshakeFailedTotal   Counter32   1.3.5rc1+   Total number of failed control connection SSL/TLS handshakes 
 *.5.1.4.0   ftps.tlsSessions.dataHandshakeFailedTotal   Counter32   1.3.5rc1+   Total number of failed data connection SSL/TLS handshakes 
 *.5.1.5.0   ftps.tlsSessions.clearCommandChannelTotal   Counter32   1.3.4rc3+   Total number of successful CCC (Clear Command Channel) FTP commands 
 *.5.1.6.0   ftps.tlsSessions.clearCommandChannelFailedTotal   Counter32   1.3.4rc3+   Total number of failed CCC (Clear Command Channel) FTP commands 
 *.5.1.7.0   ftps.tlsSessions.verifyClientTotal   Counter32   1.3.5rc2+   Total number of successful client cert verifications 
 *.5.1.8.0   ftps.tlsSessions.verifyClientFailedTotal   Counter32   1.3.4rc3+   Total number of failed client cert verifications 
 *.5.2.1.0   ftps.tlsLogins.loginTotal   Counter32   1.3.4rc3+   Total number of successful FTPS logins 
 *.5.2.2.0   ftps.tlsLogins.loginFailedTotal   Counter32   1.3.4rc3+   Total number of failed FTPS logins 
 *.5.2.3.0   ftps.tlsLogins.loginBadUserTotal   Counter32   1.3.4rc3+   Total number of failed FTPS logins due to bad/wrong user name 
 *.5.2.4.0   ftps.tlsLogins.loginBadPasswordTotal   Counter32   1.3.4rc3+   Total number of failed FTPS logins due to bad password 
 *.5.2.5.0   ftps.tlsLogins.loginGeneralErrorTotal   Counter32   1.3.4rc3+   Total number of failed FTPS logins due to config/other issues 
 *.5.2.6.0   ftps.tlsLogins.loginCertTotal   Counter32   1.3.4rc3+   Total number of FTPS logins succeeding due to the client cert (e.g. AllowDotLogin TLSOption, TLSUserName, etc
 *.5.3.1.0   ftps.tlsDataTransfers.dirListCount   Gauge32   1.3.4rc3+   Number of directories currently being listed via FTPS 
 *.5.3.2.0   ftps.tlsDataTransfers.dirListTotal   Counter32   1.3.4rc3+   Total number of directories listed via FTPS 
 *.5.3.3.0   ftps.tlsDataTransfers.dirListFailedTotal   Counter32   1.3.4rc3+   Total number of directory list failures via FTPS 
 *.5.3.4.0   ftps.tlsDataTransfers.fileUploadCount   Gauge32   1.3.4rc3+   Number of files currently being uploaded via FTPS 
 *.5.3.5.0   ftps.tlsDataTransfers.fileUploadTotal   Counter32   1.3.4rc3+   Total number of files uploaded via FTPS 
 *.5.3.6.0   ftps.tlsDataTransfers.fileUploadFailedTotal   Counter32   1.3.4rc3+   Total number of file upload failures via FTPS 
 *.5.3.7.0   ftps.tlsDataTransfers.fileDownloadCount   Gauge32   1.3.4rc3+   Number of files currently being downloaded via FTPS 
 *.5.3.8.0   ftps.tlsDataTransfers.fileDownloadTotal   Counter32   1.3.4rc3+   Total number of files downloaded via FTPS 
 *.5.3.9.0   ftps.tlsDataTransfers.fileDownloadFailedTotal   Counter32   1.3.4rc3+   Total number of file download failures via FTPS 
 *.5.3.10.0   ftps.tlsDataTransfers.kbUploadTotal   Counter32   1.3.4rc3+   Total number of KB uploaded via FTPS 
 *.5.3.11.0   ftps.tlsDataTransfers.kbDownloadTotal   Counter32   1.3.4rc3+   Total number of KB downloaded via FTPS 
 *.6.1.1.0   ssh.sshSessions.keyExchangeFailedTotal   Counter32   1.3.4c+   Total number of SSH2 key exchange failures 
 *.6.1.2.0   ssh.sshSessions.clientCompressionTotal   Counter32   1.3.4c+   Total number of SSH2 sessions using client-to-server compression 
 *.6.1.3.0   ssh.sshSessions.serverCompressionTotal   Counter32   1.3.4c+   Total number of SSH2 sessions using server-to-client compression 
 *.6.2.1.0   ssh.sshLogins.hostbasedAuthTotal   Counter32   1.3.4c+   Total number of SSH2 hostbased authentications 
 *.6.2.2.0   ssh.sshLogins.hostbasedAuthFailedTotal   Counter32   1.3.4c+   Total number of failed SSH2 hostbased authentications 
 *.6.2.3.0   ssh.sshLogins.keyboardInteractiveAuthTotal   Counter32   1.3.4c+   Total number of SSH2 keyboard-interactive authentications 
 *.6.2.4.0   ssh.sshLogins.keyboardInteractiveAuthFailedTotal   Counter32   1.3.4c+   Total number of failed SSH2 keyboard-interactive authentications 
 *.6.2.5.0   ssh.sshLogins.passwordAuthTotal   Counter32   1.3.4c+   Total number of SSH2 password authentications 
 *.6.2.6.0   ssh.sshLogins.passwordAuthFailedTotal   Counter32   1.3.4c+   Total number of failed SSH2 password authentications 
 *.6.2.7.0   ssh.sshLogins.publickeyAuthTotal   Counter32   1.3.4c+   Total number of SSH2 publickey authentications 
 *.6.2.8.0   ssh.sshLogins.publickeyAuthFailedTotal   Counter32   1.3.4c+   Total number of failed SSH2 publickey authentications 
 *.7.1.1.0   sftp.sftpSessions.sessionCount   Gauge32   1.3.4c+   Number of current SFTP sessions 
 *.7.1.2.0   sftp.sftpSessions.sessionTotal   Counter32   1.3.4c+   Total number of SFTP sessions handled 
 *.7.2.1.0   sftp.sftpDataTransfers.dirListCount   Gauge32   1.3.4rc3+   Number of directories currently being listed via SFTP 
 *.7.2.2.0   sftp.sftpDataTransfers.dirListTotal   Counter32   1.3.4rc3+   Total number of directories listed via SFTP 
 *.7.2.3.0   sftp.sftpDataTransfers.dirListFailedTotal   Counter32   1.3.4rc3+   Total number of directory list failures via SFTP 
 *.7.2.4.0   sftp.sftpDataTransfers.fileUploadCount   Gauge32   1.3.4rc3+   Number of files currently being uploaded via SFTP 
 *.7.2.5.0   sftp.sftpDataTransfers.fileUploadTotal   Counter32   1.3.4rc3+   Total number of files uploaded via SFTP 
 *.7.2.6.0   sftp.sftpDataTransfers.fileUploadFailedTotal   Counter32   1.3.4rc3+   Total number of file upload failures via SFTP 
 *.7.2.7.0   sftp.sftpDataTransfers.fileDownloadCount   Gauge32   1.3.4rc3+   Number of files currently being downloaded via SFTP 
 *.7.2.8.0   sftp.sftpDataTransfers.fileDownloadTotal   Counter32   1.3.4rc3+   Total number of files downloaded via SFTP 
 *.7.2.9.0   sftp.sftpDataTransfers.fileDownloadFailedTotal   Counter32   1.3.4rc3+   Total number of file download failures via SFTP 
 *.7.2.10.0   sftp.sftpDataTransfers.kbUploadTotal   Counter32   1.3.4rc3+   Total number of KB uploaded via SFTP 
 *.7.2.11.0   sftp.sftpDataTransfers.kbDownloadTotal   Counter32   1.3.4rc3+   Total number of KB downloaded via SFTP 
 *.8.1.1.0   scp.scpSessions.sessionCount   Gauge32   1.3.4c+   Number of current SCP sessions 
 *.8.1.2.0   scp.scpSessions.sessionTotal   Counter32   1.3.4c+   Total number of SCP sessions handled 
 *.8.2.1.0   scp.scpDataTransfers.fileUploadCount   Gauge32   1.3.4rc3+   Number of files currently being uploaded via SCP 
 *.8.2.2.0   scp.scpDataTransfers.fileUploadTotal   Counter32   1.3.4rc3+   Total number of files uploaded via SCP 
 *.8.2.3.0   scp.scpDataTransfers.fileUploadFailedTotal   Counter32   1.3.4rc3+   Total number of file upload failures via SCP 
 *.8.2.4.0   scp.scpDataTransfers.fileDownloadCount   Gauge32   1.3.4rc3+   Number of files currently being downloaded via SCP 
 *.8.2.5.0   scp.scpDataTransfers.fileDownloadTotal   Counter32   1.3.4rc3+   Total number of files downloaded via SCP 
 *.8.2.6.0   scp.scpDataTransfers.fileDownloadFailedTotal   Counter32   1.3.4rc3+   Total number of file download failures via SCP 
 *.8.2.7.0   scp.scpDataTransfers.kbUploadTotal   Counter32   1.3.4rc3+   Total number of KB uploaded via SCP 
 *.8.2.8.0   scp.scpDataTransfers.kbDownloadTotal   Counter32   1.3.4rc3+   Total number of KB downloaded via SCP 
 *.9.1.1.0   ban.connections.connectionBannedTotal   Counter32   1.3.5rc2+   Total number of connections rejected by bans 
 *.9.1.2.0   ban.connections.userBannedTotal   Counter32   1.3.5rc2+   Total number of connections rejected by user-specific bans 
 *.9.1.3.0   ban.connections.hostBannedTotal   Counter32   1.3.5rc2+   Total number of connections rejected by host-specific bans 
 *.9.1.4.0   ban.connections.classBannedTotal   Counter32   1.3.5rc2+   Total number of connections rejected by class-specific bans 
 *.9.2.1.0   ban.bans.banCount   Gauge32   1.3.5rc2+   Total number of bans currently in effect 
 *.9.2.2.0   ban.bans.banTotal   Counter32   1.3.5rc2+   Total number of bans that were ever in effect 
 *.9.2.3.0   ban.bans.userBanCount   Gauge32   1.3.5rc2+   Total number of user-specific bans currently in effect 
 *.9.2.4.0   ban.bans.userBanTotal   Counter32   1.3.5rc2+   Total number of user-specific bans that were ever in effect 
 *.9.2.5.0   ban.bans.hostBanCount   Gauge32   1.3.5rc2+   Total number of host-specific bans currently in effect 
 *.9.2.6.0   ban.bans.hostBanTotal   Counter32   1.3.5rc2+   Total number of host-specific bans that were ever in effect 
 *.9.2.7.0   ban.bans.classBanCount   Gauge32   1.3.5rc2+   Total number of class-specific bans currently in effect 
 *.9.2.8.0   ban.bans.classBanTotal   Counter32   1.3.5rc2+   Total number of class-specific bans that were ever in effect 

SNMP MIB
The MIB provided for proftpd is distributed with the mod_snmp module source code, and will be installed by default. It is contained in the "PROFTPD-MIB.txt" file, and uses SMIv2.

Suggested Future Features
The following lists the features I hope to add to mod_snmp, according to need, demand, inclination, and time:

  • AgentX support
  • SNMPv3 support
  • Controls support (e.g. for "ftpdctl snmp" action)

Notifications
The mod_snmp module supports sending notifications (via SNMP traps) whenever certain events occur or conditions are met. Note that only SNMPv2 traps are generated; there is currently no support for SNMPv1 traps.

Currently supported notifications:

To enable notifications, simply configure the address of an SNMP manager that should be notified via the SNMPNotify directive.

Frequently Asked Questions
Question: How can I query the mod_snmp Agent process?
Answer: You can test if your proftpd supports SNMP with the snmpwalk program (snmpwalk is a part of the Net-SNMP
project). Note that you have to specify the SNMP port, which in mod_snmp is configured via the SNMPAgent directive.

For example, you might try:

  # snmpwalk -m /path/to/PROFTPD-MIB.txt -v2c -Cc -c communitystring hostname:161 .1.3.6.1.4.1.17852.2.2
If it gives output like:
  enterprises.proftpd.modules.snmp.daemon.software = proftpd
  enterprises.proftpd.modules.snmp.daemon.softwareVersion = ProFTPD Version 1.3.4rc4 (built at Sat Oct 22 2011 11:50:38 PDT)
  enterprises.proftpd.modules.snmp.daemon.admin = root@127.0.0.1
or
  PROFTPD-MIB::software.0 = String: proftpd
  PROFTPD-MIB::softwareVersion.0 = STRING: ProFTPD Version 1.3.4rc4 (built at Sat Oct 22 2011 11:50:38 PDT)
  PROFTPD-MIB::admin.0 = STRING: root@127.0.0.1
or
  SNMPv2-SMI::enterprises.17852.2.2.1.1.0 = STRING: "proftpd"
  SNMPv2-SMI::enterprises.17852.2.2.1.2.0 = STRING: "ProFTPD Version 1.3.4rc4 (built at Sat Oct 22 2011 11:50:38 PDT)"
  SNMPv2-SMI::enterprises.17852.2.2.1.3.0 = STRING: "root@127.0.0.1"
then your proftpd was compiled with the mod_snmp module and it is working properly; you should be able to make nice statistics out of it.

Question: Why doesn't the scp.scpDataTransfers arc have any directory listing counters/gauges, such as the ftp.dataTransfers and sftp.sftpDataTransfers arcs do?
Answer: The SCP protocol does not have the ability to get just a directory listing; the protocol only transfers files.



Author: $Author: castaglia $
Last Updated: $Date: 2013/05/15 15:21:44 $


© Copyright 2011-2013 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_wrap.html0000644000175000017500000003117411314525733021462 0ustar frankiefrankie ProFTPD module mod_wrap

ProFTPD module mod_wrap



This module is contained in the contrib/mod_wrap.c file for ProFTPD 1.2.x, and is not compiled by default. It enables the daemon to use the common tcpwrappers access control library while in standalone mode, and in a very configurable manner.

If not installed on your system, the TCP wrappers library, required by this module, can be found here, on Wietse Venema's site. Once installed, it highly recommended that the hosts_access(3) and hosts_access(5) man pages be read and understood. The installation of mod_wrap is fairly straightforward, with some caveats for Solaris and FreeBSD users.

Many programs will automatically add entries in the common allow/deny files, and use of this module will allow a ProFTPD daemon running in standalone mode to adapt as these entries are added. The portsentry program does this, for example: when illegal access is attempted, it will add hosts to the /etc/hosts.deny file.

The most current version of mod_wrap can be found at:

  http://www.castaglia.org/proftpd/

Author

Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.

Thanks

2000-05-29: Thanks to David Douthitt <ssrat at mailbag.com> for pointing out the usefulness of using mod_wrap in conjunction with portsentry

2001-03-01: Updated the configuration directives, as per lung at theuw.net's helpful suggestions.

2001-09-24: Thanks to Zenon Mousmoulas <cajoline at chaosengine.de > for helping determine that adding -lnsl would help in compiling mod_wrap with the stock RedHat libwrap.a, so that recompiling tcpwrappers without NIS/YP support should no longer be necessary.

2001-09-27: Thanks to Gabe Frost <gfrost at gostnet.com> for helping track down several mergedown bugs.

2001-12-19: Thanks to Mark Castillo <markc at webFreak.com> for pointing out the issue with passwords not being properly hidden

Directives


TCPAccessFiles

Syntax: TCPAccessFiles allow-filename deny-filename
Default: None
Context: server config, <VirtualHost, <Global>, <Anonymous>
Module: mod_wrap
Compatibility: 1.2.1 and later

TCPAccessFiles specifies two files, an allow and a deny file, each of which contain the IP addresses, networks or name-based masks to be allowed or denied connections to the server. The files have the same format as the standard tcpwrappers hosts.allow/deny files.

Both file names are required. Also, the paths to both files must be the full path, with two exceptions: if the path starts with ~/, the check of that path will be delayed until a user requests a connection, at which time the path will be resolved to that user's home directory; or if the path starts with ~user/, where user is some system user. In this latter case, mod_wrap will attempt to resolve and verify the given user's home directory on start-up.

The service name for which mod_wrap will look in the indicated access files is proftpd by default; this can be configured via the TCPServiceName directive.

There is a built-in precedence to the TCPAccessFiles, TCPGroupAccessFiles, and TCPUserAccessFiles directives, if all are used. mod_wrap will look for applicable TCPUserAccessFiles for the connecting user first. If no applicable TCPUserAccessFiles is found, mod_wrap will search for TCPGroupAccessFiles which pertain to the connecting user. If not found, mod_wrap will then look for the server-wide TCPAccessFiles directive. This allows for access control to be set on a per-server basis, and allow for per-user or per-group access control to be handled without interfering with the server access rules.

Example:

  # server-wide access files
  TCPAccessFiles /etc/ftpd.allow /etc/ftpd.deny

  # per-user access files, which are to be found in the user's home directory
  TCPAccessFiles ~/my.allow ~/my.deny

See also: TCPGroupAccessFiles, TCPServiceName, TCPUserAccessFiles


TCPAccessSyslogLevels

Syntax: TCPAccessSyslogLevels allow-level deny-level
Default: TCPAccessSyslogLevels info warn
Context: server config, <VirtualHost>, <Global>, <Anonymous>
Module: mod_wrap
Compatibility: 1.2.1 and later

ProFTPD can log when a connection is allowed, or denied, as the result of rules in the files specified in TCPAccessFiles, to the Unix syslog mechanism. A discussion on the syslog levels which can be used is given in the SyslogLevel directive.

The allow-level parameter sets the syslog level at which allowed connections are logged; the deny-level parameter sets the syslog level for denied connections.

Example:

  TCPAccessSyslogLevels debug warn


TCPGroupAccessFiles

Syntax: TCPGroupAccessFiles group-expression allow-filename deny-filename
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_wrap
Compatibility: 1.2.1 and later

TCPGroupAccessFiles allows for access control files, the same types of files required by TCPAccessFiles, to be applied to select groups. The given group-expression is a logical AND expression, which means that the connecting user must be a member of all the groups listed for this directive to apply. Group names may be negated with a ! prefix.

The rules for the filename paths are the same as for TCPAccessFiles settings.

Example:

  # every member of group wheel must connect from restricted locations
  TCPGroupAccessFiles wheel /etc/ftpd-strict.allow /etc/ftpd-strict.deny

  # everyone else gets the standard access rules
  TCPGroupAccessFiles !wheel /etc/hosts.allow /etc/hosts.deny

See Also: TCPAccessFiles


TCPServiceName

Syntax: TCPServiceName name
Default: TCPServiceName proftpd
Context: server config, <VirtualHost>, <Global>
Module: mod_wrap
Compatibility: 1.2.1 and later

TCPServiceName is used to configure the name of the service under which mod_wrap will check the allow/deny files. By default, this is the name of the program started, i.e. "proftpd". However, some administrators may want to use a different, more generic service name, such as "ftpd"; use this directive for such needs.


TCPUserAccessFiles

Syntax: TCPUserAccessFiles user-expression allow-filename deny-filename
Default: None
Context: server config, virtual host
Module: mod_wrap
Compatibility: 1.2.1 and later

TCPUserAccessFiles allows for access control files, the same types of files required by TCPAccessFiles, to be applied to select users. The given user-expression is a logical AND expression. Listing multiple users in a user-expression does not make much sense; however, this type of AND evaluation allows for expressions such as "everyone except this user" with the use of the ! negation prefix.

The rules for the filename paths are the same as for TCPAccessFiles settings.

Example:

  # user admin might be allowed to connect from anywhere
  TCPUserAccessFiles admin /etc/ftpd-anywhere.allow /etc/ftpd-anywhere.deny

  # while every other user has to connect from LAN addresses
  TCPUserAccessFiles !admin /etc/ftpd-lan.allow /etc/ftpd-lan.deny

See also: TCPAccessFiles


FAQ

Question: Using mod_wrap, connections from hosts that have broken reverse DNS mappings are refused. OpenSSH uses the same libwrap library, and this doesn't happen. Is it a bug in mod_wrap?
Answer: No, it is not, strictly speaking, a bug in mod_wrap.

Users who encounter this issue will usually find log messages that look like the any/all of the following in their syslog:

  proftpd: warning: can't verify hostname: gethostbyname(dns-name) failed
  proftpd: warning: can't verify hostname: getaddrinfo(anothername.net, AF_INET) failed
  proftpd: warning: host name/name mismatch: somedomain.com != vs-23.somename.com
These log messages do not, in fact, come from proftpd. Instead, they come from the libwrap library, which is used by the mod_wrap module. In particular, the libwrap library emits these log messages when it has been compiled with the -DPARANOID compile-time option (and most installations of the libwrap library are compiled this way).

OpenSSH allows such connections because the OpenSSH code, when using the libwrap library, does not check for paranoid/unknown results from the host_access() function of the libwrap library. The mod_wrap module for ProFTPD does check for these values, thus why those connections are refused by mod_wrap but not OpenSSH. This just demonstrates that not all applications use the libwrap library the same way.

The solution, in most cases, is to switch to using the newer mod_wrap2 module, which does not use the libwrap library (and thus does not encounter this issue).


Installation

Use of mod_wrap is straightforward, with some minor caveats. If you're using Solaris, you'll need to obtain and build the tcpwrappers library, as this library does not come installed on stock Solaris systems. If you're using FreeBSD or Mac OSX (and possibly other versions), you'll need to change the following line in the header of mod_wrap.c:
 * $Libraries: -lwrap -lnsl$
to be:
 * $Libraries: -lwrap$
This line is needed on Linux and Solaris machines, to properly link against the libnsl.a library, which implements the NIS/YP functions. In FreeBSD and Mac OSX, these functions are implemented in libc.

Then, you need simply follow the normal steps for using third-party modules in proftpd:

  ./configure --with-modules=mod_wrap
  make
  make install


Author: $Author: castaglia $
Last Updated: $Date: 2009/12/23 23:46:35 $


© Copyright 2000-2009 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_site_misc.html0000644000175000017500000001277211460101507022462 0ustar frankiefrankie ProFTPD module mod_site_misc

ProFTPD module mod_site_misc



The mod_site_misc module implements miscellaneous SITE commands, such as:

  • SITE MKDIR
  • SITE RMDIR
  • SITE SYMLINK
  • SITE UTIME

This module is contained in the contrib/mod_site_misc.c file for ProFTPD 1.2.x/1.3.x, and is not compiled by default. Installation instructions are discussed here.

Author

Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.

Directives

Thanks

2003-02-14: Thanks to Kamil Burzynski (K.Burzynski at adbglobal.com) for providing SITE MKDIR and SITE RMDIR code
2003-10-27: Thanks to Peter Hatch (pete at parcplace.net) for providing SITE SYMLINK code

SITE Commands


SiteMiscEngine

Syntax: SiteMiscEngine on|off
Default: on
Context: server config, <VirtualHost>, <Global>
Module: mod_site_misc
Compatibility: 1.3.3c and later

The SiteMiscEngine directive enables or disables the module's runtime support for the SITE commands. If set to off, this module will not support these SITE commands. Use this directive to disable the module.


SITE MKDIR

This SITE command allows the creation of a full directory path, similar to mkdir -p /path/to/dir. It is primarily for convenience, instead of having to use a loop of MKD and CWD commands; the normal MKD FTP command only creates a single directory at a time.

The syntax for SITE MKDIR is:

  SITE MKDIR path

Use of this SITE command can be controlled via <Limit> sections, e.g.:

  <Limit SITE_MKDIR>
    AllowUser alex
    DenyAll
  </Limit>


SITE RMDIR

This SITE command allows the deletion of a full directory path, similar to rm -fr /path/to/dir. It recursively deletes all of the files and directories under the given path. This command is primarily for convenience, instead of having to use a loop of NLST, DELE, and CWD commands; the normal DELE FTP command only deletes a single file at a time, and the normal RMD command does not handle removing directories that are not empty.

The syntax for SITE RMDIR is:

  SITE RMDIR path

Use of this SITE command can be controlled via <Limit> sections, e.g.:

  <Limit SITE_RMDIR>
    AllowUser alex
    DenyAll
  </Limit>


SITE SYMLINK

This SITE command allows the creation of symbolic links, similar to ln -s.

The syntax for SITE SYMLINK is:

  SITE SYMLINK source destination

Use of this SITE command can be controlled via <Limit> sections, e.g.:

  <Limit SITE_SYMLINK>
    AllowUser alex
    DenyAll
  </Limit>


SITE UTIME

This SITE command allows for setting the access and modification timestamps on files, similar to the touch /path/to/file command. This allows sites to have the often-requested ability to set the modification time on uploaded files.

The syntax for SITE UTIME is:

  SITE UTIME YYYYMMDDhhmm[ss] path
For example:
  SITE UTIME 200402240836 file.txt
  SITE UTIME 20040224083655 file.txt
would set the access and modification timestamps on file.txt to 8:36 AM, Febrary 24, 2004 (or 8:36:55 AM, Febrary 24, 2004, respectively).

The timestamp specified is treated as being in GMT/UTC, rather than in the local timezone.

Use of this SITE command can be controlled via <Limit> sections, e.g.:

  <Limit SITE_UTIME>
    AllowUser alex
    DenyAll
  </Limit>


Installation

The mod_site_misc module is distributed with ProFTPD. Simply follow the normal steps for using third-party modules in proftpd:
  ./configure --with-modules=mod_site_misc
  make
  make install



Author: $Author: castaglia $
Last Updated: $Date: 2010/10/21 18:15:35 $


© Copyright 2004-2010 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_quotatab_sql.html0000644000175000017500000002641510142231611023175 0ustar frankiefrankie ProFTPD module mod_quotatab_sql

ProFTPD module mod_quotatab_sql



This mod_quotatab submodule is contained in the mod_quotatab_sql.c, and is found in the contrib/ area of the ProFTPD source distribution. See the mod_quotatab installation instructions.

This submodule provides the SQL database "driver" for storing quota table information in SQL tables.

Author

Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.

Thanks

2002-04-01: Thanks to Tomasz Konefal <tomk at compt.com> for his great feedback and support in developing this module.

2002-04-03: Thanks to Noah <sitz at onastick.net> for suggesting the better form of the UPDATE query.

2004-01-20: Thanks to Alex Ursu <alex.ursu at wapda.com> for supplying SQL Server FREEFORM query syntax.


SQL Quota Tables

The mod_quotatab_sql module supports the "sql" string for the source-type parameter of the QuotaLimitTable and QuotaTallyTable configuration directives. If the "sql" source-type is used, then the source-info parameter must be as described below. Note that support for SQL-based quota tables requires the use of mod_sql.

mod_quotatab_sql requires five SQL-related configuration directives: SQLConnectInfo, and four SQLNamedQuery directives. The SQLConnectInfo is needed to allow the module to connect to the SQL database. The other four directives define the SQL queries that will be used by mod_quotatab for its storage/retrieval operations involving quota data.

When using SQL tables and mod_sql, the quota tables should appear in the database named by the SQLConnectInfo directive, which will probably also contain the authentication information tables. This way your proftpd-specific tables are kept together. Also, it is probably better to use a connection policy of PERSESSION, otherwise there will be more overhead associated with each new connection made to the database for each transaction; mod_quotatab makes a lot of reads and writes to its tables, each of which will require mod_quotatab_sql to use a database connection.

One SQLNamedQuery is needed to SELECT quota information from the limit table. The defined SQL statement for this must return ten values, in the following order:

  • name
  • quota type
  • quotas per session
  • quota limit type
  • upload limit in bytes
  • download limit in bytes
  • transfer limit in bytes
  • upload limit in files
  • download limit in files
  • transfer limit in files
A similar SQLNamedQuery is needed to SELECT quota information from the tally table; the SQL statement defined for this must return eight values, in the following order:
  • name
  • quota type
  • upload tally in bytes
  • download tally in bytes
  • transfer tally in bytes
  • upload tally in files
  • download tally in files
  • transfer tally in files
The remaing two SQLNamedQuery directives are used to define the necessary UPDATE and INSERT operations on the tally table. Failure to define any of the four required SQLNamedQuery directives will cause an error during mod_quotatab_sql's operation.

For SQL tables, the format for the QuotaLimitTable directive is:

  QuotaLimitTable sql:/SELECT-SQLNamedQuery
And, for the QuotaTallyTable directive:
  QuotaTallyTable sql:/SELECT-SQLNamedQuery/UPDATE-SQLNamedQuery/INSERT-SQLNamedQuery

Also note that SQL-based tally tables have an issue with proper synchronization of updates, especially when multiple sessions involving the same tally are ocurring. In order to prevent the tally table from becoming out of sync, you are strongly encouraged to define a QuotaLock file.

SQL Quota Tables Example
Here are example SQLNamedQuery directives to help demonstrate how the mod_sql hooks are used by mod_quotatab. These example SQL statements assume the existence of two tables: a quotalimits table that defines limit records, and a quotatallies table that holds the current tally records. Note that these queries would appear all on a single line in your proftpd.conf.

  SQLNamedQuery get-quota-limit SELECT "name, quota_type, per_session, limit_type, bytes_in_avail, \
    bytes_out_avail, bytes_xfer_avail, files_in_avail, files_out_avail, files_xfer_avail FROM quotalimits \
    WHERE name = '%{0}' AND quota_type = '%{1}'"
This defines the SQL statement to return the required limit column values, in the necessary order. The %{0} and %{1} meta sequences will be substituted with the name being looked up (e.g. user name, primary group name, class name (if in effect), or the empty string) and the corresponding quota type (e.g. "user", "group", "class", or "all"), respectively.
  SQLNamedQuery get-quota-tally SELECT "name, quota_type, bytes_in_used, bytes_out_used, \
    bytes_xfer_used, files_in_used, files_out_used, files_xfer_used FROM quotatallies \
    WHERE name = '%{0}' AND quota_type = '%{1}'"
Very similar to the above example, the SQL statement defined here is for the tally table, rather than the limit table. The meta sequences will be substituted with the same values as above.
  SQLNamedQuery update-quota-tally UPDATE "bytes_in_used = bytes_in_used + %{0}, \
    bytes_out_used = bytes_out_used + %{1}, bytes_xfer_used = bytes_xfer_used + %{2}, \
    files_in_used = files_in_used + %{3}, files_out_used = files_out_used + %{4}, \
    files_xfer_used = files_xfer_used + %{5} \
    WHERE name = '%{6}' AND quota_type = '%{7}'" quotatallies
This SQL statement is used to update the tally table with the current tally values for the session. The meta sequences will be substituted with the "deltas", the difference in the known versus current tallies. The reason for forming the UPDATE query this way is to provide as atomic an update operation as possible; this query will update the current values in the table at the time of the update, in order that any race condition between a SELECT and an UPDATE query on that information be reduced to as small a window as possible.
  SQLNamedQuery insert-quota-tally INSERT "%{0}, %{1}, %{2}, %{3}, %{4}, %{5}, %{6}, %{7}" quotatallies
This last SQL statement is used to create a new tally record, in the event that a limit record is found for the current session but no matching tally record is found. The meta sequences will be substituted with: name, quota type, upload tally in bytes, download tally in bytes, transfer tally in bytes, upload tally in files, download tally in files, and transfer tally in files, in that order. These values are initialized to zero for newly-created tally records by default.

Note: SQL Server uses a slightly different INSERT syntax. This means that if you are using mod_quotatab_sql in conjunction with the mod_sql_tds module to speak to a SQL Server, your INSERT query may need to look like:

  SQLNamedQuery insert-quota-tally FREEFORM \
    "INSERT INTO quotatallies VALUES ('%{0}','%{1}','%{2}','%{3}','%{4}','%{5}','%{6}','%{7}')"

Now, using the above defined queries, the table configuration directives would be:

  QuotaLock /var/run/ftpd/tally.lock
  QuotaLimitTable sql:/get-quota-limit
  QuotaTallyTable sql:/get-quota-tally/update-quota-tally/insert-quota-tally

Example Schema
Here are some example table schema for SQL-based quota tables:

  • Limit table
    MySQL example:
        CREATE TABLE quotalimits (
          name VARCHAR(30),
          quota_type ENUM("user", "group", "class", "all") NOT NULL,
          per_session ENUM("false", "true") NOT NULL,
          limit_type ENUM("soft", "hard") NOT NULL,
          bytes_in_avail FLOAT NOT NULL,
          bytes_out_avail FLOAT NOT NULL,
          bytes_xfer_avail FLOAT NOT NULL,
          files_in_avail INT UNSIGNED NOT NULL,
          files_out_avail INT UNSIGNED NOT NULL,
          files_xfer_avail INT UNSIGNED NOT NULL
        );
    
    Postgres example:
        CREATE TABLE quotalimits (
           name VARCHAR(32) NOT NULL,
           quota_type VARCHAR(8) NOT NULL
             CHECK (quota_type IN ('user', 'group', 'class', 'all')),
           per_session BOOLEAN NOT NULL,
           limit_type VARCHAR(4) NOT NULL
             CHECK (limit_type IN ('soft', 'hard')),
           bytes_in_avail FLOAT NOT NULL,
           bytes_out_avail FLOAT NOT NULL,
           bytes_xfer_avail FLOAT NOT NULL,
           files_in_avail INT8 NOT NULL,
           files_out_avail INT8 NOT NULL,
           files_xfer_avail INT8 NOT NULL
        );
    

  • Tally table
    MySQL example:
        CREATE TABLE quotatallies (
          name VARCHAR(30) NOT NULL,
          quota_type ENUM("user", "group", "class", "all") NOT NULL,
          bytes_in_used FLOAT NOT NULL,
          bytes_out_used FLOAT NOT NULL,
          bytes_xfer_used FLOAT NOT NULL,
          files_in_used INT UNSIGNED NOT NULL,
          files_out_used INT UNSIGNED NOT NULL,
          files_xfer_used INT UNSIGNED NOT NULL
        );
    
    Postgres example:
        CREATE TABLE quotatallies (
          name VARCHAR(32) NOT NULL,
          quota_type VARCHAR(8) NOT NULL
            CHECK (quota_type IN ('user','group','class','all')),
          bytes_in_used FLOAT NOT NULL,
          bytes_out_used FLOAT NOT NULL,
          bytes_xfer_used FLOAT NOT NULL,
          files_in_used INT8 NOT NULL,
          files_out_used INT8 NOT NULL,
          files_xfer_used INT8 NOT NULL
        );
    

mod_quotatab_sql treats any number zero or less for a bytes limit as "unlimited". Similarly, it treats a value of zero for any of the files limits as "unlimited". "Unlimited" values are ignored, in that any limit that is "unlimited" is not used in any of mod_quotatab's calculations. NULL values should be avoided whenever possible.



Author: $Author: castaglia $
Last Updated: $Date: 2004/11/03 19:37:45 $


© Copyright 2000-2003 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_ifsession.html0000644000175000017500000002364111670266062022515 0ustar frankiefrankie ProFTPD module mod_ifsession

ProFTPD module mod_ifsession



The purpose of mod_ifsession is to provide a flexible way of specifying that certain configuration directives only apply to certain sessions, based on credentials such as connection class, user, or group membership.

For class-based qualifications, mod_ifsession will apply configuration directives to the current session as soon as the client has connected to the server; for user- and group-based qualifications, mod_ifsession applies configuration directives to the current session, if applicable, only after the client has successfully authenticated. This means that mod_ifsession cannot change the effect of some user- and group-qualified configuration directives, particularly those that influence the session prior to authentication. These directives include:

  AccessDenyMsg
  AccessGrantMsg
  AnonRequirePassword
  <Anonymous>
  AuthGroupFile
  AuthUserFile
  CreateHome
  DefaultChdir
  DefaultRoot
  DefaultTransferMode
  DisplayConnect
  ExtendedLog
  MaxInstances
  RequireValidShell
  RootLogin
  ServerIdent
  ServerName
  ShowSymlinks
  TransferLog
  UseFtpUsers
  WtmpLog
and the directives from the mod_auth_pam module. All of these can set on based on class qualifications, however.

While the above list of configuration directives is daunting, there are still valid uses for this module, e.g. configuring <Directory> and/or <Limit> for certain sessions, Filter directives, transfer rates, maximum file sizes, etc. Plus, some of the above directives (e.g. DefaultChdir, DefaultRoot) already have their own configurable restrictions (group expressions in the case of DefaultChdir and DefaultRoot), so all is not entirely lost.

This module is contained in the contrib/mod_ifsession.c file for ProFTPD 1.2.x/1.3.x, and is not compiled by default. Installation instructions are discussed here.

The most current version of mod_ifsession is distributed with the ProFTPD source.

Author

Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.

Directives


<IfAuthenticated>

Syntax: <IfAuthenticated>
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_ifsession
Compatibility: 1.3.5rc1 and later

The <IfAuthenticated> context should contain any configuration directives that should be in effect for any sessions where the client has successfully authenticated.

Examples:

  # Only configure SQL logging for authenticated users, to avoid cluttering
  # database tables with fail login data
  <IfAuthenticated>
    SQLLog ...
  </IfAuthenticated>

See also: <IfGroup>, <IfUser>


<IfClass>

Syntax: <IfClass ["AND"|"OR"] class-expression|"regex" regexp>
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_ifsession
Compatibility: 1.2.8rc1 and later

The <IfClass> context should contain any configuration directives that should be in effect for any sessions that match the class-expression. Classes must be enabled for this context to work properly; the connecting client must be in any of the classes listed in the expression for the directives contained to be applied. Note that ! notation in front of a class name in the expression is supported.

The given class-expression may optionally be prefixed with either the "AND" or "OR" keywords, which affect how the expression is evaluated: if "AND" is used, then all portions of the expression must evaluate to TRUE for the configuration context to be applied to the current session; if "OR" is used, then any portion of the expression must be TRUE for the context to be applied. The default setting for <IfClass> is "OR".

If the "regex" keyword is used, the regexp should be a regular expression to match class names.

Examples:

  # Give friends, and local users, better transfer rates
  <IfClass local, friends>
    TransferRate RETR 8192
  </IfClass>

  TransferRate RETR 4096

See also: <IfGroup>, <IfUser>


<IfGroup>

Syntax: <IfGroup ["AND"|"OR"] group-expression|"regex" regexp>
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_ifsession
Compatibility: 1.2.8rc1 and later

The <IfGroup> context should contain any configuration directives that should be in effect for any sessions that match the group-AND-expression. The authenticated user must be in all of the groups listed in the expression for the directives contained to be applied. Note that ! notation in front of a group name in the expression is supported.

The given group-expression may optionally be prefixed with either the "AND" or "OR" keywords, which affect how the expression is evaluated: if "AND" is used, then all portions of the expression must evaluate to TRUE for the configuration context to be applied to the current session; if "OR" is used, then any portion of the expression must be TRUE for the context to be applied. The default setting for <IfGroup> is "AND".

If the "regex" keyword is used, the regexp should be a regular expression to match group names.

Example:

  # Only members of group webusers can upload/download HTML files
  <IfGroup !webusers>
    PathDenyFilter \.htm$|\.html$
  </IfGroup>

See also: <IfClass>, <IfUser>


<IfUser>

Syntax: <IfUser ["AND"|"OR"] user-expression|"regex" regexp>
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_ifsession
Compatibility: 1.2.8rc1 and later

The <IfUser> context should contain any configuration directives that should be in effect for any sessions that match the user-OR-expression. The authenticated user must be one of the users listed in the expression for the directives contained to be applied. Note that ! notation in front of a user name in the expression is supported.

The given user-expression may optionally be prefixed with either the "AND" or "OR" keywords, which affect how the expression is evaluated: if "AND" is used, then all portions of the expression must evaluate to TRUE for the configuration context to be applied to the current session; if "OR" is used, then any portion of the expression must be TRUE for the context to be applied. The default setting for <IfUser> is "OR".

If the "regex" keyword is used, the regexp should be a regular expression to match user names.

Example:

  # Alter the view of files for everyone except the admin
  <IfUser !ftpadm>
    <Directory />
      DirFakeUser on ~
      DirFakeGroup on ~
      DirFakeMode 0440
    </Directory>
  </IfUser>

  # Impose a PathDenyFilter on ftp users
  <IfUser regex ^ftp>
    PathDenyFilter \.conf$
  </IfUser>

See also: <IfClass>, <IfGroup>


Usage

Expressions, AND vs OR


Installation

To install mod_ifsession, copy the mod_ifsession.c file into:
  proftpd-dir/contrib/
after unpacking the latest proftpd-1.3.x source code. Then follow the usual steps for using third-party modules in proftpd:
  ./configure --with-modules=mod_ifsession
  make
  make install
Note that mod_ifsession should be the last module in the --with-modules list, if multiple modules are listed. This makes sure that mod_ifsession's changes will be seen properly by other modules.



Author: $Author: castaglia $
Last Updated: $Date: 2011/12/09 02:02:26 $


© Copyright 2000-2011 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/ftpquota.html0000644000175000017500000002616310142231610021501 0ustar frankiefrankie ftpquota: tool for ProFTPD mod_quotatab

ftpquota: tool for ProFTPD module mod_quotatab



This program is distributed with the mod_quotatab module for ProFTPD 1.2. It is used to create and manage quota tables of type "file".

The most current version of ftpquota is distributed with the ProFTPD source code.

Author

Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this program.



Usage

The following describes the common usage of the ftpquota tool. The options supported are described in more detail later.

Creating Tables
To start using mod_quotatab, the two required tables are required. Tables of type "file" have identifying magic headers such that ftpquota is needed to initially create both tables. It is an error to attempt to create a table that already exists:

  # ftpquota --create-table --type=limit
  ftpquota: cannot create existing table

To create the initial limit table:

  ftpquota --create-table --type=limit
To create the initial tally table:
  ftpquota --create-table --type=tally
The population of a tally table file with the tally for users, groups, classes, and all is done automatically by mod_quotatab.

For both of these operations, the --table-path can be used to create a table in a non-default location.

Updating Tables
Now that you have the initial tables created, but blank, you need to add records (to the limit table) for the users, groups, classes, etc on which you, as the administrator, wish to impose quotas.

To a basic limit record for a user bob using the default quotas (which are all "unlimited" by default):

  ftpquota --add-record --type=limit --name=bob --quota-type=user
Similarly for quotas of type group or class. Note that for quotas of type all, the --name option is not necessary; the all record applies to everyone, regardless of name or group or class membership. If no byte or file limits are specified, the default settings (unlimited numbers of bytes/files) are used.

It is an error to add a record that already exists. Note, however, that it is possible to have multiple records of the same name, but different quota types. The record to use for a given session is identified by the combination of name and quota type.

An example of creating a limit record with more complex quotas for a class named "browsers"

  ftpquota --add-record --type=limit --name=browsers --quota-type=class \
    --files-upload=0  --files-download=25 --table-path=/usr/local/etc/ftplimit.tab
or, another way:
  ftpquota --add-record --type=limit --name=browsers --quota-type=class \
    --bytes-upload=0 --bytes-download=2 --units=Gb --table-path=/usr/local/etc/ftplimit.tab
In general, it is a good idea to use either byte quotas or file quotas, but not both, unless you know what you are doing. In these examples, the --table-path option is used to add the record to a limit table in a non-default location.

Another option available when creating limit records is the --per-session option. By default, quotas are persistent, and apply to the user (or group, class, or everyone) across all sessions. Using this option means the limits will be enforced only for the duration of the client's session, and that the limits will apply only to that client. In other words, using this option for group, class, or all quotas is not a good idea.

Similarly, for removing records from the limit table (effectively removing quotas from affecting that user/group/class/all) or from the tally table (effectively resetting the quotas to zero for that user/group/class/all), there is the --delete-record option:

  ftpquota --delete-record --type=limit --name=browsers --quota-type=class

In addition to adding and removing records, an administrator may want to simply change the quotas in a given record, either in the limit or tally tables. In this case, use --update-record:

  ftpquota --update-record --type=tally --name=bob --quota-type=user \
    --bytes-download=100 --files-download=1
This example command manually sets user bob's download tally to 100 bytes, 1 file. It is an error to update a record that does not exist.

There are some administrators who wish to impose quotas on a daily basis, that is, to have a per-day quota. At present, the easiest way to do this is to have a cron job that, once a day, does the following:

  ftpquota --update-record --type=tally --name=name --quota-type=quotatype
This command will "reset" the matching tally record. By default, if no byte or file quotas are set, the default values are used: unlimited if updating a limit record, zero if updating a tally record.

When editing the tables, ftpquota will obtain read or write locks as necessary. If those tables are being used by a running server, which also performs locking, the script will wait until it is able to obtain a lock. Changing of in-use table information is ideally done while the server is quiescent. This locking is to avoid data synchronization and corruption issues.

Showing Tables
Having tables in binary format makes it difficult to easily see what the current records are, to double-check limits or simply to view the current tally. ftpquota thus supports the dumping out of table contents in human-legible form via the --show-records option:

  ftpquota --show-records --type=limit
or, for a tally table not in the location where the scripts expects it to be:
  ftpquota --show-records --type=tally --table-path=/usr/local/etc/ftpd/quota-tally.tab
When viewing tables this way, the --units option can be used to display byte quotas in other units (e.g. Kb, Mb, etc).



Options

The following is the output from running ftpquota --help:
usage: ftpquota [options]

 The following options describe the type of operation to be performed:

  --add-record         Create a new record with the specified limits.  Any
                       limits left unspecified with have their default
                       values.  This option requires the --name and
                       --quota-type options.

  --create-table       Create the table if not present.  Used to initialize
                       a table.  The default limit table path is
                       "./ftpquota.limittab".  The default tally table path is
                       "./ftpquota.tallytab".

  --delete-record      Deletes a quota record from the table.  This option
                       requires the --name and --quote-type options.

  --show-records       Prints out all of the quota records in the table in
                       a legible format.

  --update-record      Updates a quota record with the specified limits.  Any
                       limits left unspecified will be updated with their
                       default value.  This option requires the --name and
                       --quota-type options.

 The following option describes the type of table on which to operate:

  --type               Specifies a table type to use.  The allowable options
                       are: "limit" or "tally".  This is required.

 The following options are used to specify specific quota limits:

  --Bu                 Specifies the limit of the number of bytes that may be
  --bytes-upload       uploaded.  Defaults to -1 (unlimited).

  --Bd                 Specifies the limit of the number of bytes that may be
  --bytes-download     downloaded.  Defaults to -1 (unlimited).

  --Bx                 Specifies the limit of the number of bytes that may be
  --bytes-xfer         transferred.  Note that this total includes uploads,
                       downloads, AND directory listings.  Defaults to
                       -1 (unlimited).

  --Fu                 Specifies the limit of the number of files that may be
  --files-upload       uploaded.  Defaults to -1 (unlimited).

  --Fd                 Specifies the limit of the number of files that may be
  --files-download     downloaded.  Defaults to -1 (unlimited).

  --Fx                 Specifies the limit of the number of files that may be
  --files-xfer         transferred, including uploads and downloads.  Defaults
                       to -1 (unlimited).

  -L                   Specifies the type of limit, "hard" or "soft", of
  --limit-type         the bytes limits.  If "hard", any uploaded files that
                       push the bytes used counter past the limit will be
                       automatically deleted; if "soft", those extra bytes
                       will be allowed, but future uploads will be denied.
                       This option only makes sense if --type is "limit".

  -N                   Specifies a name for the quota record.  This name
  --name               will be the user/login name, group name, or class
                       name, depending on the quota type.  This option
                       is ignored if the quota type specified is "all".

  -P
  --per-session        Specifies that the quota limit is to be applied only
                       to each session, rather than persisting across
                       sessions.  By default, quotas are persistent.

  -Q                   Specifies a "quota type" for this record, where
  --quota-type         the type means to which category of FTP users this
                       quota will apply.  The quota type must be one of:
                       "user", "group", "class", or "all".

 The following options are miscellaneous:

  --help               Displays this message.

  --table-path         Specifies the path to a quota table file to use.

  --units              Specifies whether to treats bytes as is, in kilobytes,
                       megabytes, or gigabytes.  Allowable options are:
                       "B" or "byte", "Kb" or "kilo", "Mb" or "mega",
                       and "Gb" or "giga".  Defaults to "byte".

  --verbose            Toggles more verbose information about the doings of
                       the tool as it works.



Author: $Author: castaglia $
Last Updated: $Date: 2004/11/03 19:37:44 $


© Copyright 2000-2002 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_ban.html0000644000175000017500000004611712114205111021234 0ustar frankiefrankie ProFTPD module mod_ban

ProFTPD module mod_ban



The mod_ban module is designed to add dynamic "ban" lists to proftpd. A ban prevents the banned user, host, or class from logging in to the server; it does not prevent the banned user, host, or class from connecting to the server. mod_ban is not a firewall. The module also provides automatic bans that are triggered based on configurable criteria.

This module is contained in the mod_ban.c file for ProFTPD 1.2.x/1.3.x, and is not compiled by default. nstallation instructions are discussed here. Detailed documentation on mod_ban usage can be found here.

The most current version of mod_ban is distributed with the proftpd source.

Author

Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.

Directives

Control Actions


BanCache

Syntax: BanCache driver
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_ban
Compatibility: 1.3.4rc2 and later


BanCacheOptions

Syntax: BanCacheOptions opt1 ... optN
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_ban
Compatibility: 1.3.4rc2 and later


BanControlsACLs

Syntax: BanControlsACLs actions|"all" "allow"|"deny" "user"|"group" list
Default: None
Context: server config
Module: mod_ban
Compatibility: 1.2.10rc1 and later

The BanControlsACLs directive configures access lists of users or groups who are allowed (or denied) the ability to use the actions implemented by mod_ban. The default behavior is to deny everyone unless an ACL allowing access has been explicitly configured.

If "allow" is used, then list, a comma-delimited list of users or groups, can use the given actions; all others are denied. If "deny" is used, then the list of users or groups cannot use actions all others are allowed. Multiple BanControlsACLs directives may be used to configure ACLs for different control actions, and for both users and groups.

The actions provided by mod_ban are "ban" and "permit".

Examples:

  # Allow only user root to ban and permit users
  BanControlsACLs all allow user root


BanEngine

Syntax: BanEngine on|off
Default: off
Context: server config
Module: mod_ban
Compatibility: 1.2.10rc1 and later

The BanEngine directive enables or disables the banning of sessions by mod_ban. If it is set to off this module does no banning. Use this directive to disable the module instead of commenting out all mod_ban directives.


BanLog

Syntax: BanLog path|"none"
Default: None
Context: server config
Module: mod_ban
Compatibility: 1.2.10rc1 and later

The BanLog directive is used to a specify a log file for mod_ban reporting and debugging. The path parameter must be the full path to the file to use for logging. Note that this path must not be to a world-writeable directory and, unless AllowLogSymlinks is explicitly set to on (generally a bad idea), the path must not be a symbolic link.

If path is "none", no logging will be done at all.


BanMessage

Syntax: BanMessage mesg
Default: None
Context: server config
Module: mod_ban
Compatibility: 1.2.10rc1 and later

The BanMessage directive configures a message that will be sent to clients that have been banned. This message may contain the following variables:

  • %a: client IP address
  • %c: client class (if none, will be empty)
  • %u: USER name (if none, will be empty)

Example:

  BanMessage "Host %a has been banned"


BanOnEvent

Syntax: BanOnEvent event freq expires [mesg]
Default: None
Context: server config
Module: mod_ban
Compatibility: 1.2.10rc1 and later

The BanOnEvent directive is used to configure a "rule" that is triggered whenever the named event occurs. The currently supported events are:

  AnonRejectPasswords
  ClientConnectRate
  MaxClientsPerClass
  MaxClientsPerHost
  MaxClientsPerUser
  MaxCommandRate
  MaxConnectionsPerHost
  MaxHostsPerUser
  MaxLoginAttempts
  TimeoutIdle
  TimeoutLogin
  TimeoutNoTransfer
  TLSHandshake
  UnhandledCommand
An event is generated whenever one of these limits is reached by a client.

The freq parameter should be formatted as:

  N/hh:mm:ss
where N is the number of occurrences, and hh:mm:ss specifies a number of hours, minutes, and seconds. This parameter says that if N occurrences of event happen within the given time interval, then a ban is automatically added. The IP address of the connecting client is banned when the following event rules are triggered: AnonRejectPasswords, MaxCommandRate, MaxClientsPerHost, MaxConnectionsPerHost, MaxLoginAttempts, TimeoutIdle, TimeoutNoTransfer, and UnhandledCommand. The class of the connected client, if any, is banned when a rule for MaxClientsPerClass is triggered. Rules for MaxClientsPerUser and MaxHostsPerUser will cause the connected username to be banned.

The duration should be formatted as:

  hh:mm:ss
and specifies the numbers of hours, minutes, and seconds that the automatic ban generated a BanOnEvent rule lasts. Unlike bans added via the ban ftpdctl control action, automatic bans do not have infinite lifetimes.

An optional message, to be displayed to banned clients, can be configured. If no such optional message is configured using the BanOnEvent directive, then any BanMessage message will be displayed.

For example:

  # Configure a rule to automatically ban scripts looking for anonymous
  # servers to which they can upload
  BanOnEvent AnonRejectPasswords 1/01:00:00 99:99:99

  # Ban clients which connect too frequently.  This rule bans clients
  # which connect more than 5 times within one minute.  Include a special
  # message just for them.
  BanOnEvent ClientConnectRate 5/00:01:00 04:00:00 "Stop connecting frequently"

See also: BanMessage


BanTable

Syntax: BanTable path
Default: None
Context: server config
Module: mod_ban
Compatibility: 1.2.10rc1 and later

The BanTable directive configures a path to a file that mod_ban uses for handling its ban data. The given path must be an absolute path. Note: this directive is required for mod_ban to function. It is recommended that this file not be on an NFS mounted partition.

Note that ban data is not kept across daemon stop/starts. That is, once proftpd is shutdown, all current ban data is lost.


Control Actions


ban

Syntax: ftpdctl ban class|host|info|user [-s address#port] name1 [name2 ...]
Purpose: Add a ban or display ban information

The ban action is used to add bans to the mod_ban lists. For example, to ban a user:

  ftpdctl ban user dave
This will create a ban rule for user 'dave' for all virtual servers in your proftpd.conf. If you want to create such a ban rule, but only for one specific <VirtualHost>, use the -s command-line option, e.g.:
  ftpdctl ban user -s 1.2.3.4#21 dave
This example will create the user 'dave' ban rule for the <VirtualHost> handling IP address 1.2.3.4, port 21. The -s command-line option applies to host and class bans as well.

To ban specific hosts, you can use either IP addresses or DNS names:

  ftpdctl ban host 1.2.3.4 5.6.7.8
  ftpdctl ban host gw.evil.com
Banning a class works the same way:
  ftpdctl ban class anonftp

The info parameter is used to view information on current bans. Example listing:

  # ftpdctl ban info
  ftpdctl: Banned Hosts:
  ftpdctl:   127.0.0.1
Or, if you wish to see more information, use the -v option:
  # ftpdctl ban info -v
  ftpdctl: Banned Hosts:
  ftpdctl:   127.0.0.1
  ftpdctl:     Reason: MaxLoginAttempts autoban at Wed May 19 14:59:25 2004
  ftpdctl:     Expires: Wed May 19 14:59:55 2004 (in 24 seconds)
  ftpdctl:     <VirtualHost> ServerName (1.2.3.4#21)
It is also possible to see the state of ban event rules, using the -e option:
  # ftpdctl ban info -e
  ftpdctl: No bans
  ftpdctl: 
  ftpdctl: Ban Event Entries:
  ftpdctl:   Event: MaxLoginAttempts
  ftpdctl:   Source: 127.0.0.1
  ftpdctl:     Occurrences: 1/2
  ftpdctl:     Entry Expires: 589 seconds
This shows that no bans are currently in effect, and that a BanOnEvent has been configured for the MaxLoginAttempts event. That event has occurred once, and will need to happen one more time within 589 seconds in order for an automatic ban to be added.

See also: permit


permit

Syntax: ftpdctl permit class|host|user [-s address#port] name1 [name2 ...]
Purpose: Permit banned clients to connect

The permit action is used to remove a ban for users, hosts, and classes:

  # ftpdctl permit user dave
  # ftpdctl permit user -s 1.2.3.4#21 dave
  # ftpdctl permit host 1.2.3.4 gw.evil.com
  # ftpdctl permit class anonftp

See also: ban


Installation

To install mod_ban, copy the mod_ban.c file into:
  proftpd-dir/contrib/
after unpacking the latest proftpd-1.2.x source code. Then follow the usual steps for using third-party modules in proftpd, making sure to include the --enable-ctrls configure option, which mod_ban requires:
  ./configure --enable-ctrls --with-modules=mod_ban
  make
  make install


Usage

The mod_ban module implements its bans by checking if a client is banned, either by host or by class, when that client connects to the server. Banned clients are immediately disconnected. Banned users are checked after the client has sent the USER and PASS commands; if that user has been banned, the client is immediately disconnected.

Here is an example mod_ban configuration, demonstrating how to configure an automatic ban for MaxLoginAttempts:

  MaxLoginAttempts 1

  <IfModule mod_ban.c>
    BanEngine on
    BanLog /var/log/proftpd/ban.log
    BanTable /var/data//proftpd/ban.tab

    # If the same client reaches the MaxLoginAttempts limit 2 times
    # within 10 minutes, automatically add a ban for that client that
    # will expire after one hour.
    BanOnEvent MaxLoginAttempts 2/00:10:00 01:00:00

    # Allow the FTP admin to manually add/remove bans
    BanControlsACLs all allow user ftpadm
  </IfModule>

By default, the mod_ban module allocate size for 512 bans. In practice, this has seemed to work well. However, if you need to allocate space for more bans, you will need to recompile proftpd, and use the CFLAGS environment variable like so:

    ./configure CFLAGS="-DBAN_LIST_MAXSZ=1024" ...
or whatever your necessary ban list size is.

Frequently Asked Questions
Question: Why does mod_ban not store ban data across daemon stop/starts?
Answer: The mod_ban module was not designed to add yet another ACL mechanism to proftpd. For persistent access control, there is the <Limit LOGIN> section, the mod_wrap module, the /etc/ftpusers file, and various other mechanisms. The purpose of mod_ban is to provide dynamic, short-lived bans.

Question: What about having proftpd delay sending responses to clients, say by 30 seconds or so?
Answer: This is a bad idea. It would allow malicious clients, who knew they were banned, to tie up your proftpd processes, since those processes would be taking up space, waiting before sending responses back to the client. This makes it possible for those clients to use the delaying as a Denial of Service attack, eventually tying up your available system resources with waiting proftpd processes.

Question: I have the following, taken from the example config above, configured for mod_ban, but it does not appear to be working. Why not?

  # If the same client reaches the MaxLoginAttempts limit 2 times
  # within 10 minutes, automatically add a ban for that client that
  # will expire after one hour.
  BanOnEvent MaxLoginAttempts 2/00:10:00 01:00:00
Answer: The most common reason is that the MaxLoginAttempts directive does not function the way that many assume it does.

The above BanOnEvent rule says that the same client (i.e. source IP address) which reaches the MaxLoginAttempts limit 2 times within 10 minutes will be banned. If you test by connecting to proftpd, trying a bad password once, disconnecting, then connecting again and trying the same bad password again, you will not be hitting the MaxLoginAttempts limit. Remember that the MaxLoginAttempts directive configures a limit to the number of bad login attempts for the same connection; it does not configure limit on the number of bad login attempts across multiple connections.

The default MaxLoginAttempts value for proftpd is 3. Which means that simply connecting, trying a bad login attempt once, then disconnecting, will not trigger the MaxLoginAttempts limit. This is why the example configuration given above explicitly configures the MaxLoginAttempts limit to be lower:

  MaxLoginAttempts 1
in order to make mod_ban behave the way that most administrators assume it will. If you have not explicitly configured MaxLoginAttempts lower, then this is probably why your BanOnEvent rule is not taking effect as you expect.

Question: It looks like the BanTable file I configured is untouched:

  -rw-r--r-- 1 ftp  ftp     0 2007-01-13 23:18 ban.table
Does this mean that something is wrong, or that mod_ban is not using that file?

Answer: A BanTable file is needed, just not in an obvious way. The mod_ban module stores its ban information in a SysV shared memory segment. The configured BanTable file is used a) to generate a unique name/ID for the shared memory segment to use (and to see if a segment for that name/ID already exists), and b) for locking, as when multiple sessions are trying to update the shared memory segment at the same time. But mod_ban does not write any data into that file itself, and hence the last-modified-time of the file, and the file size, does not change much.

Question: How can I configure a whitelist of IP addresses, to be excluded from the effects of mod_ban?
Answer: This can be done using a combination of
Classes and the mod_ifsession module. For example:

  <Class whitelist>
    From ...
  </Class>

  <IfClass whitelist>
    # Turn the mod_ban module off for whitelisted clients
    BanEngine off
  </IfClass>

  <IfClass !whitelist>
    # Make sure the mod_ban module is on for clients that are not whitelisted
    BanEngine on
  </IfClass>
Note that it is important to have both <IfClass> sections in your configuration.



Author: $Author: castaglia $
Last Updated: $Date: 2013/03/01 20:06:33 $


© Copyright 2004-2013 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_tls_memcache.html0000644000175000017500000000550011526615006023125 0ustar frankiefrankie ProFTPD module mod_tls_memcache

ProFTPD module mod_tls_memcache


The mod_tls_memcache submodule is contained in the mod_tls_memcache.c file, and is not compiled by default. Installation instructions are discussed here.

This submodule a memcached-based implementation of an external SSL session cache for use by the mod_tls module's TLSSessionCache directive.

This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/).

This product includes cryptographic software written by Eric Young (eay@cryptsoft.com).

Author

Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.

The mod_tls_memmcache module supports the "memcache" string for the type parameter of the TLSSessionCache configuration directive. The info parameter for mod_tls_memcache is blank. This means the TLSSessionCache setting will look like:

  TLSSessionCache memcache:
If memcache support has not been enabled in your proftpd, this configuration cannot be used.

Examples

  <IfModule mod_memcache.c>
    MemcacheEngine on
    MemcacheServers memcache-servers
  </IfModule>

  <IfModule mod_tls.c>
    ...

    <IfModule mod_tls_memcache.c>
      TLSSessionCache memcache:
    </IfModule>
  </IfModule>


Installation

The mod_tls_memcache module is distributed with the ProFTPD source code. Simply follow the normal steps for using third-party modules in proftpd, being sure to include the mod_tls module (on which mod_tls_memcache depends), and enabling memcache support:
  ./configure --enable-memcache --with-modules=mod_tls:mod_tls_memcache
  make
  make install

Alternatively, if your proftpd was compiled with DSO support, you can use the prxs tool to build mod_tls_memcache as a shared module:

  prxs -c -i -d mod_tls_memcache.c


Author: $Author: castaglia $
Last Updated: $Date: 2011/02/16 00:27:50 $

© Copyright 2011 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_ldap.html0000644000175000017500000005710011051400126021410 0ustar frankiefrankie ProFTPD module mod_ldap

ProFTPD module mod_ldap



This module is contained in the mod_ldap.c file for ProFTPD 1.2.x/1.3.x, and is not compiled by default. Installation instructions are discussed here.

The most current version of mod_ldap is distributed with the ProFTPD source code.

Author

Please contact John Morrissey <jwm at horde.net> with any questions, concerns, or suggestions regarding this module.

Directives


LDAPAliasDereference

Syntax: LDAPAliasDereference never|always|search|find
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_ldap
Compatibility: 1.2.7rc1 and later

The LDAPAliasDereference directive configures how aliases are handled. The possible values have the following behaviors:

  • never

    Never dereference aliases

  • always

    Always dereference aliases

  • search

    Dereference aliases only when searching

  • find

    Dereference aliases only when locating the base object for the search

The default is "never", e.g.:

  <IfModule mod_ldap.c>
    LDAPAliasDeference never
  </IfModule>


LDAPAttr

Syntax: LDAPAttr old-attr-name new-attr-name
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_ldap
Compatibility: 1.2.7rc1 and later

The LDAPAttr directive is used to map, or to associate, a standard attribute name to a non-standard attribute name. If, for example, your LDAP directory schema used different names for some of the attributes used by mod_ldap, you would use this directive to tell mod_ldap what new attribute names to use.

The following LDAP attributes can be renamed in this manner:

  • uid
  • uidNumber
  • gidNumber
  • homeDirectory
  • userPassword
  • loginShell
  • cn
  • memberUid
  • ftpQuota


LDAPAuthBinds

Syntax: LDAPAuthBinds on|off
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_ldap
Compatibility: 1.2.7rc1 and later

By default, the DN specified by the LDAPDNInfo will be used to bind to the LDAP server to obtain user information, including the userPassword attribute. If LDAPAuthBinds is set to on, the DN specified by LDAPDNInfo will be used to fetch all user information except the userPassword attribute. Then, the mod_ldap module will bind to the LDAP server as the user who is logging in via FTP with the user-supplied password. If this bind succeeds, the user is considered authenticated and is allowed to log in. This method of LDAP authentication has the added benefit of supporting any password encryption scheme that your LDAP server supports.

In versions of mod_ldap up to 2.7.6, the default for LDAPAuthBinds was off. After mod_ldap 2.8, the default value for LDAPAuthBinds is on.


LDAPDNInfo

Syntax: LDAPDNInfo dn password
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_ldap
Compatibility: 1.2.7rc1 and later

The LDAPDNInfo directive configures the DN and the password that mod_ldap will use when binding to the LDAP directory. If this configuration directive is missing, then anonymous binds are used.

The default is:

  <IfModule mod_ldap.c>
    # Use anonymous binds
    LDAPDNInfo "" ""
  </IfModule>

See also: LDAPServer


LDAPDefaultAuthScheme

Syntax: LDAPDefaultAuthScheme crypt|clear
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_ldap
Compatibility: 1.2.7rc1 and later

The LDAPDefaultAuthScheme directive specifies the authentication scheme used for passwords which have no "{hashname}" prefix in the LDAP directory. For example, if you are:

  userPassword mypass
in your directory, you would want to set LDAPDefaultAuthScheme to clear.

The default value is crypt.


LDAPDefaultGID

Syntax: LDAPDefaultGID gid
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_ldap
Compatibility: 1.2.7rc1 and later

The LDAPDefaultGID directive sets the default GID to be used for users when no gidNumber attribute is found for that user.

This directive is useful primarily in virtual user environments common in large-scale ISPs and hosting organizations. If a user does not have an LDAP gidNumber attribute, the LDAPDefaultGID is used. This allows one to have a large number of users in an LDAP directory without gidNumber attributes; setting this configuration directive will automatically assign those users a single GID.

See also: LDAPDefaultUID


LDAPDefaultUID

Syntax: LDAPDefaultUID uid
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_ldap
Compatibility: 1.2.7rc1 and later

The LDAPDefaultUID directive sets the default UID to be used for users when no uidNumber attribute is found for that user.

This directive is useful primarily in virtual user environments common in large-scale ISPs and hosting organizations. If a user does not have an LDAP uidNumber attribute, the LDAPDefaultGID is used. This allows one to have a large number of users in an LDAP directory without uidNumber attributes; setting this configuration directive will automatically assign those users a single UID.

See also: LDAPDefaultGID


LDAPDoAuth

Syntax: LDAPDoAuth off|on base-dn search-filter-template
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_ldap
Compatibility: 1.2.7rc1 and later

The LDAPDoAuth configuration directive activates LDAP authentication. The second parameter to this directive is the LDAP base DN to use for authentication. The third parameter is a template to be used for the search filter; %v will be replaced with the username that is being authenticated.

By default, the search filter template used is:

  (&(uid=%v)(objectclass=posixAccount))
The uid for the the search filter is taken from the LDAPAttr directive. Search filter templates are only supported in versions of mod_ldap 2.7 and later.

See also: LDAPAttr


LDAPDoGIDLookups

Syntax: LDAPDoGIDLookups off|on base-dn cn-filter-template gid-number-filter-template member-uid-filter-template
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_ldap
Compatibility: 1.2.7rc1 and later

The LDAPDoGIDLookups directive activates LDAP GID-to-name lookups for directory listings. The second parameter to this directive is the LDAP base DN to use for GID-to-name lookups. The third through fifth parameters are templates to be used for the search filter; %v will be replaced with the GID that is being looked up.

By default, the CN filter template look like this:

  (&(LDAPAttr_cn=%v)(objectclass=posixGroup))
The gidNumber filter template is:
  (&(LDAPAttr_gidNumber=%v)(objectclass=posixGroup))
and the memberUid filter template used is: (&(LDAPAttr_memberUid=%v)(objectclass=posixGroup))
Note that filter templates are only supported in mod_ldap version 2.8.3 and later.

The attribute names used in the default search filters are taken from the LDAPAttr directive.


LDAPDoQuotaLookups

Syntax: LDAPDoQuotaLookups off|on base-dn quota-filter-template default-quota
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_ldap
Compatibility: 1.2.7rc1 and later

The LDAPDoQuotaLookups directive enables LDAP quota lookups. The second parameter of this directive is the LDAP base DN to use for quota limit search. The third parameter is a template to be used for the search filter; %v will be replaced with the username that is being authenticated.

By default, the search filter template is:

  (&(LDAPAttr_uid=%v)(objectclass=posixAccount))
The uid for the the search filter is taken from the LDAPAttr directive. Note that search filter templates are only supported in mod_ldap version 2.7 and later.

If specified, the default-quota parameter indicates the quota limits to use if a user does not have an ftpQuota attribute. This parameter is formatted the same way as the ftpQuota LDAP attribute.


LDAPDoUIDLookups

Syntax: LDAPDoUIDLookups off|on base-dn uid-filter-template
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_ldap
Compatibility: 1.2.7rc1 and later

The LDAPDoUIDLookups directive activates LDAP UID-to-name lookups for directory listings. The second parameter to this directive is the LDAP base DN to use for UID-to-name lookups. The third parameter is a template to be used for the search filter; %v will be replaced with the UID that is being looked up.

By default, the search filter template looks like this:

  (&(LDAPAttr_uidNumber=%v)(objectclass=posixGroup))
The uidNumber attribute name used in the search filter comes from the LDAPAttr directive. Note that filter templates are only supported in mod_ldap version 2.7 and later.


LDAPForceDefaultGID

Syntax: LDAPForceDefaultGID on|off
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_ldap
Compatibility: 1.2.7rc1 and later

Even when a LDAPDefaultGID is configured, the mod_ldap module will allow individual users to have gidNumber attributes that will override this default GID. With LDAPForceDefaultGID directive configured to be on, all LDAP-authenticated users are given the default GID; GIDs may not be overridden by gidNumber attributes.


LDAPForceDefaultUID

Syntax: LDAPForceDefaultUID on|off
Default: None
Context: server config
Module: mod_ldap
Compatibility: 1.2.7rc1 and later

Even when a LDAPDefaultUID is configured, the mod_ldap module will allow individual users to have uidNumber attributes that will override this default UID. With LDAPForceDefaultUID directive configured to be on, all LDAP-authenticated users are given the default UID; UIDs may not be overridden by uidNumber attributes.


LDAPForceGeneratedHomedir

Syntax: LDAPForceGeneratedHomedir off|on directory-mode
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_ldap
Compatibility: 1.2.7rc1 and later

See also: LDAPGenerateHomedir, LDAPGenerateHomedirPrefix, LDAPGenerateHomedirPrefixNoUsername


LDAPGenerateHomedir

Syntax: LDAPGenerateHomedir on|off
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_ldap
Compatibility: 1.2.7rc1 and later


LDAPGenerateHomedirPrefix

Syntax: LDAPGenerateHomedirPrefix prefix
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_ldap
Compatibility: 1.2.7rc1 and later


LDAPGenerateHomedirPrefixNoUsername

Syntax: LDAPGenerateHomedirPrefixNoUsername on|off
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_ldap
Compatibility: 1.2.7rc1 and later


LDAPNegativeCache

Syntax: LDAPNegativeCache on|off
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_ldap
Compatibility: 1.2.7rc1 and later

The LDAPNegativeCache directive specifies whether or not to cache negative responses from the LDAP server when using LDAP for UID/GID lookups. This option is useful if you also use/are in transition from another authentication system; if there are many users in your old authentication system that aren't in the LDAP database, there can be a significant delay when a directory listing is performed as the UIDs not in the LDAP database are repeatedly looked up in an attempt to present usernames instead of UIDs in directory listings. With LDAPNegativeCache set to on, negative ("not found") responses from the LDAP server will be cached and speed will improve on directory listings that contain many users not present in the LDAP database.


LDAPProtocolVersion

Syntax: LDAPProtocolVersion 2|3
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_ldap
Compatibility: 1.2.7rc1 and later

The LDAPProtocolVersion directive configures the version of the LDAP protocol that mod_ldap will use when talking to the LDAP servers. The default protocol version used is 3.


LDAPQueryTimeout

Syntax: LDAPQueryTimeout secs
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_ldap
Compatibility: 1.2.7rc1 and later

The LDAPQueryTimeout directive configures the timeout value, in seconds, that will be used for LDAP directory queries. The default timeout value is determined by your LDAP API.


LDAPSearchScope

Syntax: LDAPSearchScope onelevel|subtree
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_ldap
Compatibility: 1.2.7rc1 and later

The LDAPSearchScope directive is used to set the scope used for LDAP searches. The default setting, subtree, searches for all entries in the tree from the current level down. Setting this directive to onelevel searches only one level deep in the LDAP tree.


LDAPServer

Syntax: LDAPServer "host1:port1 host2:port2"
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_ldap
Compatibility: 1.2.7rc1 and later

The LDAPServer directive allows you to to specify the hostname(s) and port(s) of the LDAP server(s) to use for LDAP authentication. If no LDAPServer configuration directive is present, the default LDAP servers specified by your LDAP library will be used.

To specify multiple LDAP servers, enclose the entire list of servers in quotation marks. For example:

  LDAPServer "host1:port1 host2:port2"


LDAPUseSSL

Syntax: LDAPUseSSL on|off
Default: off
Context: server config, <VirtualHost>, <Global>
Module: mod_ldap
Compatibility: 1.3.1rc1 and later


LDAPUseTLS

Syntax: LDAPUseTLS on|off
Default: off
Context: server config, <VirtualHost>, <Global>
Module: mod_ldap
Compatibility: 1.2.7rc1 and later

The LDAPUseTLS directive configures whether mod_ldap will use SSL/TLS to protect the connections made to the configured LDAP servers.

By default, the mod_ldap module connects to the LDAP server via non-encrypted connections. Enabling this option causes mod_ldap to use an encrypted (TLS/SSL) connection to the LDAP server. If a secure connection to the LDAP server fails, mod_ldap will not authenticate users; mod_ldap will not fall back to an unsecure connection.



Usage



Installation

Follow the normal steps for using third-party modules in proftpd:
  ./configure --with-modules=mod_ldap
  make
  make install
You may need to specify the location of the OpenLDAP header and library files in your configure command, e.g.:
 ./configure --with-modules=mod_ldap \
    --with-includes=/usr/local/openldap/include \
    --with-libraries=/usr/local/openldap/lib



Usage

One mod_ldap user submitted the following configuration for allowing mod_ldap to communicate to a Windows Active Directory server. Note that this configuration has not been tested; if it works for you (or not), please let us know:

  <IfModule mod_ldap.c>
    LDAPServer dc.example.org:3268
    LDAPUseTLS on
    LDAPAuthBinds on
    LDAPDNInfo "cn=SRV_ACC_SVN_AUTH,ou=special accounts,ou=Sales,dc=example,dc=org" ******************

    LDAPDoAuth on ou=Users,ou=Sales,dc=example,dc=org "(&(sAMAccountName=%u)(objectclass=user)(memberOf=cn=Linux Admins,ou=Groups,ou=Sales,dc=example,DC=org))"
    LDAPSearchScope subtree

    # Assign default IDs
    LDAPDefaultUID 106
    LDAPDefaultGID 65534

    # Create the home directory
    LDAPGenerateHomedir on
    LDAPGenerateHomedirPrefix /home

    # Use different attribute names where necessary
    LDAPAttr uid sAMAccountName
    LDAPAttr gidNumber primaryGroupID

  </IfModule>



Author: $Author: castaglia $
Last Updated: $Date: 2008/08/15 22:16:54 $


© Copyright 2008 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_ifversion.html0000644000175000017500000001242211412404256022503 0ustar frankiefrankie ProFTPD module mod_ifversion

ProFTPD module mod_ifversion



The mod_ifversion module is designed for use in testsuites and production deployments of proftpd, which may have to deal with different ProFTPD versions and different configurations. The <IfVersion> sections supported by mod_ifversion allow flexible version checking, including numeric and regular expression comparisons.

This module is contained in the mod_ifversion.c file for ProFTPD 1.3.x, and is not compiled by default. Installation instructions are discussed here; a discussion on usage is also available.

The most current version of mod_ifversion is distributed with the proftpd source code.

Author

Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.

Directives


<IfVersion>

Syntax: <IfVersion [[!]operator] version>
Default: None
Context: All
Module: mod_ifversion
Compatibility: 1.3.1rc1 and later

The <IfVersion> section encloses configuration directives which will be used only if the proftpd version matches the configured criteria. For normal (numeric) comparisons the version argument has the following syntax:

  major[.minor[.revision[suffix]]]
e.g. 1.3.1, 1.3.2a, or 1.3.3rc1. If the minor or revision fields are omitted, they are assumed to be zero. An omitted suffix is assumed to be a stable release, instead of a release candidate (RC) or maintenance release.

The following numerical comparison operators are supported:

operator Description
= or == proftpd version is equal
> proftpd version is greater than
>= proftpd version is greater or equal
< proftpd version is less than
<= proftpd version is less or equal

It is also possible to use regular expressions to match the proftpd version. To use a regular expression, the operators are:

operator Description
= or == version has the form /regex/
~ version has the form regex

If you wish to reverse the meaning of the operator, prefix the operator with an exclamation mark (!), e.g.:

  <IfVersion != 1.3.1>
    # Do not use these directives if the version is 1.3.1
  </IfVersion>

If operator is omitted, it is assumed to be =.


Installation

To install mod_ifversion, copy the mod_ifversion.c file into:
  proftpd-dir/contrib/
after unpacking the latest proftpd-1.3.x source code. For including mod_ifversion as a staticly linked module:
  ./configure --with-modules=mod_ifversion
To build mod_ifversion as a DSO module:
  ./configure --enable-dso --with-shared=mod_ifversion
Then follow the usual steps:
  make
  make install

For those with an existing ProFTPD installation, you can use the prxs tool to add mod_ifversion, as a DSO module, to your existing server:

  # prxs -c -i -d mod_ifversion.c

Usage

The following examples demonstrate how the mod_ifversion can be used.

Using a simple numeric comparison:

  <IfVersion >= 1.3.1rc1>
    # Only use these directives for versions greater or equal 1.3.1rc1
  </IfVersion>

Using a regular expression:

  <IfVersion = /^rc[[:digit:]]$/>
    # Only use these directives for RC (release candidate) versions
  </IfVersion>

Using a reversed regular expression (i.e. in this case, meaning "proftpd version does not match this pattern"):

  <IfVersion !~ ^1.3.[012]$>
    # These directives are not for those versions
  </IfVersion>



Author: $Author: castaglia $
Last Updated: $Date: 2010/06/29 14:52:30 $


© Copyright 2009-2010 TJ Saunders
All Rights Reserved


proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_sftp.html0000644000175000017500000023343212154216660021465 0ustar frankiefrankie ProFTPD module mod_sftp

ProFTPD module mod_sftp



SFTP versus FTPS
There is a great deal of confusion and misunderstanding surrounding two very different protocols: SFTP and FTPS.

FTPS stands for "FTP over SSL/TLS". It is the existing FTP protocol, made to run over an SSL/TLS connection; in this manner, it is very similar to HTTPS (HTTP over SSL/TLS). In fact, that is where the name "FTPS" comes from. The mod_tls module for ProFTPD implements FTPS. Since FTPS is still FTP, any FTPS sessions require multiple TCP connections: one TCP connection for the FTP control channel, and separate TCP connections for each FTP data channel. The need for these multiple connections is undesirable for many network administrators, especially those that wish to restrict all protocols to a single TCP connection which can be passed through firewalls/NAT/router equipment. The network equipment, now, often inspects the application-level data in FTP packets in order to dynamically open the necessary firewall rules for the FTP data channels. However, FTPS encrypts those packets, and thus the network firewall must resort to using a statically configured range of ports, or not allow FTPS. There is a third solution: the CCC FTP command, which clears the FTP control channel of encryption, once the user has authenticated. Unfortunately, support for the CCC command is not widespread among FTPS clients and servers; the mod_tls module does support the CCC command.

By contrast, SFTP refers to "Secure File Transfer Protocol", and is not related to FTP in any way. SFTP is based on the SSH2 protocol, which uses binary encoding of messages over a secure channel. Unlike FTP, SSH2 only uses a single TCP connection, and multiplexes multiple transfers or "channels" over that single connection. For this reason, many sites prefer SFTP to FTPS for secure transfer of data.

SSH2 RFCs and SFTP Drafts
For those wishing to learn more about the SSH2 and SFTP protocols, see:

The mod_sftp module for ProFTPD
The mod_sftp module implements the SSH2 protocol and its SFTP subsystem, for secure file transfer over an SSH2 connection. The mod_sftp module supports:

  • Public key authentication
  • Password authentication (e.g. user authentication via mod_sql, mod_ldap, mod_auth_file, mod_auth_unix, mod_auth_pam)
  • SCP support
  • Quotas (via the mod_quotatab module)
  • FIPS support (see Usage section)
  • Throttled transfers (via TransferRate, and/or the mod_shaper module)
  • Blacklisted public keys
  • Configurable traffic analysis protection
  • Passphrase-protected host keys
  • SFTP extensions: check-file, copy-file, vendor-id, version-select, posix-rename@openssh.com, statvfs@openssh.com, fstatvfs@openssh.com
This module supports the SFTP and SCP file transfer protocols; it does not support shell access.

The mod_sftp module does not currently support:

  • <Anonymous>
  • ListOptions
  • MaxRetrieveFileSize

The mod_sftp module is contained in the mod_sftp/ directory, is intended for ProFTPD 1.3.3rc1 and later, and is not compiled by default. Installation instructions are discussed here.

The most current version of mod_sftp is distributed with the ProFTPD source code.

This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/). This product includes cryptographic software written by Eric Young (eay@cryptsoft.com).

Author

Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.

Directives


SFTPAcceptEnv

Syntax: SFTPAcceptEnv env1 ...
Default: LANG
Context: "server config", <VirtualHost>, <Gl obal>
Module: mod_sftp
Compatibility: 1.3.3rc3 and later

The SFTPAcceptEnv directive specifies which environment variables sent by the client, if any, will be used in the session environment. Environment variables are specified by name, and may contain the '*' and '?' wildcard characters. Multiple environment variables may be configured, either separated by whitespace or spread across multiple SFTPAcceptEnv directives.

Be warned that some environment variables may have special meaning to underlying libraries; care should be taken in the use of this directive.


SFTPAuthMethods

Syntax: SFTPAuthMethods meth1 ...
Default: publickey password
Context: "server config", <VirtualHost>, <Global>
Module: mod_sftp
Compatibility: 1.3.2rc2 and later

The SFTPAuthMethods directive configures the list of available authentication methods presented to connecting clients. The list of currently supported methods is:

  • hostbased
  • keyboard-interactive
  • publickey
  • password
In general, there is no need to use this directive unless only one specific authentication method must be used. Should it be needed, the list of authentication methods to use is provided as a space-delimited list, e.g.:
  # Offer publickey and keyboard-interactive authentication only
  SFTPAuthMethods publickey keyboard-interactive

The hostbased authentication method is only offered to clients if the SFTPAuthorizedHostKeys directive is configured.

The publickey authentication method is only offered to clients if the SFTPAuthorizedUserKeys directive is configured.

The keyboard-interactive authentication method is only offered to clients if the mod_sftp_pam module is present.


SFTPAuthorizedHostKeys

Syntax: SFTPAuthorizedHostKeys store1 ...
Default: None
Context: "server config", <VirtualHost>, <Global>
Module: mod_sftp
Compatibility: 1.3.2rc2 and later

The SFTPAuthorizedHostKeys directive configures the file that mod_sftp will use during the handling of hostbased authentication of users. The configured file may contain several public keys in RFC4716 format, in no particular order.

Note that a SFTPAuthorizedHostKeys directive is required for mod_sftp to handle sessions which want to use hostbased authentication properly.

Note: In order to use OpenSSH public keys in a SFTPAuthorizedHostKeys, you must convert them to the RFC4716 format (see the Usage section). This is done using OpenSSH's ssh-keygen tool:

  # ssh-keygen -e -f /path/to/file
The output from this command can then be added to the SFTPAuthorizedHostKeys file.


SFTPAuthorizedUserKeys

Syntax: SFTPAuthorizedUserKeys store1 ...
Default: None
Context: "server config", <VirtualHost>, <Global>
Module: mod_sftp
Compatibility: 1.3.2rc2 and later

The SFTPAuthorizedUserKeys directive configures the file that mod_sftp will use during the handling of publickey authentication of users. The configured file may contain several public keys in RFC4716 format, in no particular order.

Example:

  SFTPAuthorizedUserKeys file:~/.sftp/authorized_keys

Note: In order to use OpenSSH public keys in a SFTPAuthorizedUserKeys, you must convert them to the RFC4716 format (see the Usage section). This is done using OpenSSH's ssh-keygen tool:

  # ssh-keygen -e -f ~/.ssh/id_rsa.pub
The output from this command can then be added to the SFTPAuthorizedUserKeys file.

The configured path for a file containing authorized keys can use the %u variable, which will be interpolated with the name of the user being authenticated. This feature supports having per-user files of authorized keys that reside in a central location, rather than requiring (or allowing) users to manage their own authorized keys. For example:

  SFTPAuthorizedUserKeys file:/etc/sftp/authorized_keys/%u


SFTPCiphers

Syntax: SFTPCiphers algo1 ...
Default: None
Context: "server config", <VirtualHost>, <Global>
Module: mod_sftp
Compatibility: 1.3.2rc2 and later

The SFTPCiphers directive is used to specify the list of cipher algorithms that mod_sftp should use. The current list of supported cipher algorithms is, in the default order of preference:

  • aes256-ctr
  • aes192-ctr
  • aes128-ctr
  • aes256-cbc
  • aes196-cbc
  • aes128-cbc
  • blowfish-ctr
  • blowfish-cbc
  • cast128-cbc
  • arcfour256
  • arcfour128
  • 3des-ctr
  • 3des-cbc
By default, all of the above cipher algorithms are presented to the client, in the above order, during the key exchange.

The "none" cipher (i.e. no encryption) will not be presented to the client by default; any sites which wish to use "none" will have to explicitly configure it via SFTPCiphers.

Note that CTR mode ciphers (e.g. the aes128-ctr, aes192-ctr, and aes256-ctr ciphers) are recommended. Any CBC mode cipher allows for the possibility of an attack which causes several bits of plaintext to be leaked; the attack is described here. This attack is on the SSH2 protocol design itself; any SSH2 implementation which conforms to the RFCs will have this weakness.

In general, there is no need to use this directive unless only one specific cipher must be used.

For comparison, the cipher algorithms used by OpenSSH by default are:

  • aes128-cbc
  • 3des-cbc
  • blowfish-cbc
  • cast128-cbc
  • arcfour128
  • arcfour256
  • aes192-cbc
  • aes256-cbc
  • aes128-ctr
  • aes192-ctr
  • aes256-ctr
Thus if you wanted to configure mod_sftp to present the same cipher algorithms as OpenSSH, you would use:
  # Make mod_sftp present the same ciphers as OpenSSH
  SFTPCiphers aes128-cbc 3des-cbc blowfish-cbc cast128-cbc arcfour128 \
              arcfour256 aes192-cbc aes256-cbc aes128-ctr aes192-ctr aes256-ctr


SFTPClientAlive

Syntax: SFTPClientAlive count interval
Default: None
Context: "server config", <VirtualHost>, <Global>
Module: mod_sftp
Compatibility: 1.3.4rc1 and later

The SFTPClientAlive directive configured mod_sftp to send messages to a client, through the encrypted channel, to request a response from the client. If count client alive messages are sent without receiving any response messages from the client, the client will be disconnected. The interval indicates how much time, in seconds, that mod_sftp waits for data from the client before sending a client alive message.

For example, using:

  SFTPClientAlive 3 15
will cause an unresponsive client to be disconnected after approximately 45 seconds.


SFTPClientMatch

Syntax: SFTPClientMatch pattern key1 val1 ...
Default: None
Context: "server config", <VirtualHost>, <Global>
Module: mod_sftp
Compatibility: 1.3.2rc2 and later

The SFTPClientMatch directive is used to tune some of the SSH2/SFTP values based on the connecting client, for better interoperability with those clients. The pattern parameter specifies a POSIX regular expression which will be matched against the connecting client's SSH version banner. If the client's banner version matches pattern, then the configured keys/values are used for that session.

The currently supported SSH2/SFTP keys which can be tuned via SFTPClientMatch are:

  • channelPacketSize
    The value for this key can be a number, with an optional "KB" (kilobytes) suffix.

    The default mod_sftp channel packet size is 32KB.

  • channelWindowSize
    The value for this key can be a number, with an optional "GB" (gigabytes), "MB" (megabytes), or "KB" (kilobytes) suffix.

    The default mod_sftp channel window size is 4GB. Using smaller window sizes may be necessary for some clients; larger window sizes can help reduce latency for bulk data transfers.

  • sftpProtocolVersion
    The value for this key can be a specific version number, e.g. "3", or it can be a range such as "1-3". The mod_sftp module supports SFTP protocol versions 1-6; using any other protocol versions will result in bad configuration.
  • sftpUTF8ProtocolVersion
    The value for this key is a specific version number, e.g. "3". The mod_sftp module uses UTF8 encoding for handling paths/strings in SFTP messages for protocol version 4 and above by default; this key can be used to change the protocol versions for which UTF8 encoding is used.

    For example, if you set:

        SFTPClientMatch .* sftpUTF8ProtocolVersion 1
    
    then mod_sftp will try to use UTF8 for all SFTP protocol versions, all clients.

For example, to make mod_sftp only allow SFTP protocol version 3 to WinSCP clients, you would use:

  SFTPClientMatch ".*WinSCP.*" sftpProtocolVersion 3
Or for older OpenSSH clients, you may need to use a smaller channel window size, e.g.:
  SFTPClientMatch "^OpenSSH_3\\.*" channelWindowSize 8MB


SFTPCompression

Syntax: SFTPCompression on|off|delayed
Default: off
Context: "server config", <VirtualHost>, <Global>
Module: mod_sftp
Compatibility: 1.3.2rc2 and later

The SFTPCompression directive enables the use of zlib compression of the payload of SSH2 packets. This can make for smaller packets, but require more CPU time to compress/uncompress the data.

The delayed parameter tells mod_sftp to support a custom extension used by OpenSSH, where compression is not actually enabled until after the client has successfully authenticated.


SFTPCryptoDevice

Syntax: SFTPCryptoDevice driver|"all"|"none"
Default: None
Context: "server config", <VirtualHost>, <Global>
Module: mod_sftp
Compatibility: 1.3.2rc2 and later

The SFTPCryptoDevice directive is used to configure mod_sftp to use an OpenSSL "engine", a cryptographic module that OpenSSL library can use for accelerated cryptographic support, or HSM keys, etc.

To use all of the engines compiled into OpenSSL, use:

  SFTPCryptoDevice all
OpenSSL will find, from the list of supported engines, the first one usable, if any. If no usable engines are found, OpenSSL will default to its normal software implementation. If a specific engine is desired as the default engine to use, specify the engine name, e.g.:
  SFTPCryptoDevice chil

The OpenSSL command

  openssl engine
may be used to list all of the engine drivers supported by OpenSSL.


SFTPDHParamFile

Syntax: SFTPDHParamFile path
Default: dhparams.pem
Context: "server config", <VirtualHost>, <Global>
Module: mod_sftp
Compatibility: 1.3.2rc2 and later

The SFTPDHParamFile directive is used to configure the path to a file containing pre-computed Diffie-Hellman (DH) group parameters. These parameters will be used by mod_sftp when handling the Diffie-Hellman group exchange (see RFC4419) portion of the key exchange.

The SFTPDHParamFile is produced using OpenSSL, which uses PEM encodings of PKCS#3 DHparam structures. It is similar in nature to OpenSSH's moduli(5) file.

The mod_sftp source code comes with a dhparams.pem file which should be sufficient. If for any reason you find that you need to generate your own SFTPDHParamFile, use one of the following OpenSSL commands to create this file:

  # openssl dhparam -outform PEM -2 nbits >> dhparams.pem
  # openssl dhparam -outform PEM -5 nbits >> dhparams.pem
Using either -2 or -5 as the generator is fine. The nbits value used should vary between 1024 and 8192, inclusive. Beware: this process is quite slow, and CPU/memory intensive!


SFTPDigests

Syntax: SFTPDigests algo1 ...
Default: None
Context: "server config", <VirtualHost>, <Global>
Module: mod_sftp
Compatibility: 1.3.2rc2 and later

The SFTPDigests directive is used to specify the list of MAC digest algorithms that mod_sftp should use. The current list of supported MAC algorithms is:

  • hmac-sha2-256
  • hmac-sha2-512
  • hmac-sha1
  • hmac-sha1-96
  • hmac-md5
  • hmac-md5-96
  • hmac-ripemd160
  • umac-64@openssh.com
By default, all of the above MAC algorithms are presented to the client, in the above order, during the key exchange. Note that some algorithms (e.g. the SHA256 and SHA512 algorithms) may not be supported by the version of OpenSSL used; this will be automatically detected.

The "none" MAC (i.e. no MAC) will not be presented to the client by default; any sites which wish to use "none" will have to explicitly configure it via SFTPDigests.

In general, there is no need to use this directive unless only one specific MAC algorithm must be used.

For comparison, the MAC algorithms used by OpenSSH (depending on the version) by default are:

  • hmac-md5
  • hmac-sha1
  • hmac-sha2-256
  • hmac-sha2-512
  • hmac-ripemd160
  • hmac-sha1-96
  • hmac-md5-96
  • umac-64@openssh.com
Thus if you wanted to configure mod_sftp to present the same MAC algorithms as OpenSSH, you would use:
  # Make mod_sftp present the MAC ciphers as OpenSSH
  SFTPDigests hmac-md5 hmac-sha1 hmac-sha2-256 hmac-sha2-512 \
    hmac-ripemd160 hmac-sha1-96 hmac-md5-96 umac-64@openssh.com


SFTPDisplayBanner

Syntax: SFTPDisplayBanner path
Default: None
Context: "server config", <VirtualHost>, <Global>
Module: mod_sftp
Compatibility: 1.3.2rc2 and later

The SFTPDisplayBanner directive is used to configure the path of a file which will be sent to the client prior to authentication. Such files are often used to sent terms of use or other such policy terms to connecting clients.


SFTPEngine

Syntax: SFTPEngine on|off
Default: off
Context: "server config", <VirtualHost>, <Global>
Module: mod_sftp
Compatibility: 1.3.2rc2 and later

The SFTPEngine directive toggles the use of the SSH2/SFTP protocols engine (e.g. mod_sftp). This is usually used inside a <VirtualHost> section to enable SFTP sessions for a particular virtual host. By default mod_sftp is disabled for both the main server and all configured virtual hosts.


SFTPExtensions

Syntax: SFTPExtensions ext1 ... extN
Default: None
Context: "server config", <VirtualHost>, <Global>
Module: mod_sftp
Compatibility: 1.3.3rc3 and later

The SFTPExtensions directive can be used to enable/disable support for the various SFTP extensions supported by mod_sftp. The extension names used for the SFTPExtensions directive are:

  • checkFile
  • copyFile
  • fsync
  • vendorID
  • versionSelect
  • posixRename
  • spaceAvailable
  • statvfs
All extensions except vendorID are enabled by default.

To enable an extension, preface the extension name with a '+' (plus) character; to disable the extension, use a '-' (minus) character prefix. For example:

  # Allow the copy-file extension, but not version-select
  SFTPExtensions +copyFile -versionSelect


SFTPHostKey

Syntax: SFTPHostKey file|agent:/path
Default: None
Context: "server config", <VirtualHost>, <Global>
Module: mod_sftp
Compatibility: 1.3.2rc2 and later

The SFTPHostKey directive configures the path to a host key file. The mod_sftp module uses the keys thus configured as part of the SSH2 key exchange process.

Note that the SFTPHostKey directive is required. You can use either an RSA key, a DSA key, and/or ECDSA keys. These should be the exact same host key files as used by your SSH2 server, e.g.:

  SFTPHostKey /etc/ssh_host_dsa_key
  SFTPHostKey /etc/ssh_host_rsa_key
  SFTPHostKey /etc/ssh_host_ecdsa_key
or the equivalents in the /usr/local/etc/ directory. Using different host keys between your SSH2 server and mod_sftp will only cause confusion and problems for any SFTP clients. Most SFTP clients will assume that the host uses the same keys for SSH2 and SFTP; after all, it is the same host (even the same port), just different services. Thus having different host keys for an SSH2 server and mod_sftp will cause clients to constantly switch the host keys they record for the same host (and cause confusion for users).

The SFTPHostKey directive, as of proftpd-1.3.5rc1 and later, can also be used to load host keys from an SSH agent such as OpenSSH's ssh-agent. For example:

  # Load all of the keys from the ssh-agent configured for server use
  SFTPHostKey agent:%{env:SSH_AUTH_SOCK}
Using an SSH agent for storing host keys allows for configurations where the host keys are not stored on files on the server system, e.g. the keys can be loaded into the SSH agent from a PKCS#11 token.


SFTPKeyBlacklist

Syntax: SFTPKeyBlacklist "none"|path
Default: None
Context: "server config", <VirtualHost>, <Global>
Module: mod_sftp
Compatibility: 1.3.2rc2 and later

The SFTPKeyBlacklist directive configures the path to a specially formatted dictionary of known weak public keys. This key blacklist, and the code for using it, was primarily developed by Dmitry V. Levin under sponsorship by CivicActions. For the original posting, and further information, see:

  http://www.openwall.com/lists/oss-security/2008/05/27/3

These known weak public keys arose because of a vulnerability in the OpenSSL packages distributed by Debian:

  http://www.debian.org/security/2008/dsa-1571

The mod_sftp source code comes with a blacklist.dat file which should be sufficient. If for any reason you find that you need to generate your own SFTPDKeyBlacklist, use the blacklist-encode program mentioned in the above URLs.


SFTPKeyExchanges

Syntax: SFTPKeyExchanges algo1 ...
Default: None
Context: "server config", <VirtualHost>, <Global>
Module: mod_sftp
Compatibility: 1.3.2rc2 and later

The SFTPKeyExchanges directive is used to specify the list of key exchange algorithms that mod_sftp should use. The current list of supported key exchange algorithms is:

  • ecdh-sha2-nistp256
  • ecdh-sha2-nistp384
  • ecdh-sha2-nistp521
  • diffie-hellman-group-exchange-sha256
  • diffie-hellman-group-exchange-sha1
  • diffie-hellman-group14-sha1
  • diffie-hellman-group1-sha1
  • rsa1024-sha1
By default, all of the above key exchange algorithms are presented to the client, in the above order, during the key exchange.

In general, there is no need to use this directive unless only one specific key exchange algorithm must be used.


SFTPLog

Syntax: SFTPLog file|"none"
Default: None
Context: "server config", <VirtualHost>, <Global>
Module: mod_sftp
Compatibility: 1.3.2rc2 and later

The SFTPLog directive is used to specify a log file for mod_sftp's reporting on a per-server basis. The file parameter given must be the full path to the file to use for logging.

Note that this path must not be to a world-writable directory and, unless AllowLogSymlinks is explicitly set to on (generally a bad idea), the path must not be a symbolic link.


SFTPMaxChannels

Syntax: SFTPMaxChannels count
Default: 10
Context: server config, <VirtualHost>, <Global>
Module: mod_sftp
Compatibility: 1.3.2rc2 and later

The SFTPMaxChannels directive is used to configure the maximum number of simultaneously open channels permitted for a client. The default value is 10.

A malicious client might try to abuse the server's resources by opening an large number of SSH2 channels and then not using them. Most well-behaved SSH2 clients only ever open one channel.


SFTPOptions

Syntax: SFTPOptions opt1 ...
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_sftp
Compatibility: 1.3.2rc2 and later

The SFTPOptions directive is used to configure various optional behavior of mod_sftp. Note: all of the configured SFTPOptions parameters must appear on the same line in the configuration; only the first SFTPOptions directive that appears in the configuration is used.

For example:

  SFTPOptions IgnoreSFTPUploadPerms IgnoreSCPUploadPerms PessimisticKexinit

The currently implemented options are:

  • IgnoreSFTPSetOwners

    Use this option to have mod_sftp silently ignore any ownership changes sent by SFTP clients via the SETSTAT or FSETSTAT SFTP requests; these are equivalent to an FTP SITE CHGRP command.

    Note that this option first appeared in proftpd-1.3.5rc1.

  • IgnoreSFTPSetPerms

    Use this option to have mod_sftp silently ignore any permissions sent by SFTP clients via the SETSTAT or FSETSTAT SFTP requests; these are equivalent to an FTP SITE CHMOD command.

    Note that this option first appeared in proftpd-1.3.4rc2.

  • IgnoreSFTPSetTimes

    Use this option to have mod_sftp silently ignore any timestamps sent by SFTP clients via the SETSTAT or FSETSTAT SFTP requests; these are equivalent to an FTP SITE UTIMES command.

    Note that this option first appeared in proftpd-1.3.4rc4.

  • IgnoreSFTPUploadPerms

    When an SFTP client uploads a file or creates a directory, the desired permissions on the path are sent to the server as part of the upload. (This is different from FTP, which does not include the file permissions in an upload.) If you need more FTP-like functionality for any reason and wish to have mod_sftp silently ignore any permissions sent by the SFTP client, use this option.

  • IgnoreSCPUploadPerms

    When an SCP client uploads a file, the desired permissions on the file are sent to the server as part of the upload. (This is different from FTP, which does not include the file permissions in an upload.) If you need more FTP-like functionality for any reason and wish to have mod_sftp silently ignore any permissions sent by the SCP client, use this option.

  • MatchKeySubject

    When this option is used, if public key authentication is used, the mod_sftp module will check if the public key has a "Subject" header. If so, that the value of that header must match the name of the authenticating user/host.

    Note that this option first appeared in proftpd-1.3.4rc1.

  • OldProtocolCompat

    Older clients identity their protocol versions as "1.99", rather than as "2.0". By default, mod_sftp will refuse to handle connections from such clients. To enable compatibility with these clients (which tend to be derived from ssh.com/Tectia code), use this option.

    Note that this option automatically enables the PessimisticKexinit SFTPOption as well.

    Note that this option first appeared in proftpd-1.3.4rc1.

  • PessimisticKexinit

    As described here, the mod_sftp module tries to reduce the connection latency by optimistically sending the KEXINIT key exchange message. However, some SSH clients cannot handle this behavior. Use this option to disable the optimistic sending of the KEXINIT message.

    Note that this option first appeared in proftpd-1.3.4rc1.


SFTPPassPhraseProvider

Syntax: SFTPPassPhraseProvider path
Default: None
Context: server config
Module: mod_sftp
Compatibility: 1.3.2rc2 and later

The SFTPPassPhraseProvider directive is used to specify an external program which will be called, when mod_sftp starts up, for each encrypted host key file. The program will be invoked with two command-line arguments, passed on stdin to the program:

  servername:portnumber file
where servername:portnumber indicates the server using that encrypted certificate key, and file indicates the host key file in question. The program then must print the corresponding passphrase for the key to stdout.

The intent is that this external program can perform any security checks necessary, to make sure that the system is not compromised by an attacker, and only when these checks pass successfully will the passphrase be provided. These security checks, and the way the passphrase is determined, can be as complex as you like.

Example:

  SFTPPassPhraseProvider /etc/ftpd/sftp/get-passphrase


SFTPRekey

Syntax: SFTPRekey "none"|"required" [[interval bytes] timeout]
Default: None
Context: "server config", <VirtualHost>, <Global>
Module: mod_sftp
Compatibility: 1.3.2rc2 and later

The SFTPRekey directive configures the session rekey policy used by the mod_sftp module. When an SSH2 client connects, there is an initial exchange of hostkey, cipher, digest, and compression algorithms, followed by sharing of information which leads to the calculation of shared session keys. These keys are used in the various algorithms. The exchange of algorithms and calculation of new session keys can happen at any time during the SSH2 session; this is known as "rekeying".

By default, mod_sftp will only require rekeying when the packet sequence number (for sent or received SSH2 packets) reaches a rather high limit. The digest algorithm used, for example, might begin to leak cryptographically sensitive information if used for too many packets (see RFC4344). Outside of these sequence number limits, however, mod_sftp will not attempt to initiate rekeying.

To prevent mod_sftp from attempting rekeying, use:

  SFTPRekey none
Note that disabling rekeying altogether is a Very Bad Idea. While rekeying can cause delays in the SSH2 sesssion, it is intended to guard against certain attacks. You should therefore only disable rekeying for certain SSH2 clients which cannot support rekeying. Please report those clients (including the client version) to the mod_sftp maintainer, so that that client can be added to the list of known clients which cannot handle rekeying.

To require rekeying, simply use:

  SFTPRekey required
With this parameter, mod_sftp will default to requiring a rekey within 1 hour (3600 seconds) or after 2GB of data sent or received, whichever happens first. There will be no timeout once a rekeying has been requested.

However, administrators wishing to use different rekey intervals or rekey byte limits can use the optional interval (in seconds) and bytes (in MB) parameters, e.g.:

  # Require rekeying after 30 minutes, or 4 GB
  SFTPRekey required 1800 4096

Finally, the paranoid administrator may wish to set a timeout, in seconds, in which a client must complete a session rekeying, otherwise the client will be disconnected. This would look like:

  # Require rekeying after 30 minutes, or 4 GB.  If the rekeying is not
  # completed within 5 minutes of a rekey request, disconnect the client.
  SFTPRekey required 1800 4096 300
Note that normally such rekey timeouts are not necessary.


SFTPTrafficPolicy

Syntax: SFTPTrafficPolicy policy
Default: None
Context: "server config", <VirtualHost>, <Global>
Module: mod_sftp
Compatibility: 1.3.2rc2 and later

The SFTPTrafficPolicy directive is used to configure a measure of protection against traffic analysis attacks. Such attacks use the number of packets sent, the size of the packets, and the timing of the packets to try to gain information about the nature of the data being transmitted.

The SSH2 protocol includes a particular message, SSH_MSG_IGNORE, which all implementations (both clients and servers) must handle by dropping on the floor. Implementations, like mod_sftp, can use these messages to add random data to the session in the hopes of making such traffic analyses more difficult.

The SFTPTrafficPolicy directive supports the following range of policies; the chances columns list the probability that mod_sftp will send an SSH_MSG_IGNORE message.

Policy Name Chances Checks
"none" Never Never
"low" 1 in 1000 Every 5 seconds
"medium" 1 in 100 Every 5 seconds
"high" 1 in 10 Every second
"paranoid" Always Every second

The default SFTPTrafficPolicy setting is "none".

However, if a client negotiates the use of a CBC cipher, then a defensive traffic policy will automatically be used. RFC 4251, Section 9.3.1, specifically mentions the insertion of SSH_MSG_IGNORE messages as a way of mitigating the "Rogaway" attack on CBC ciphers. In order to disable this automatic mitigation behavior, you must explicitly configure a SFTPTrafficPolicy setting in your configuration, e.g.

  # Disable any automatic protection when CBC ciphers are used
  SFTPTrafficPolicy none
Note that this is not recommended!


Installation

To install mod_sftp, go to the third-party module area in the proftpd source code and unpack the mod_sftp source tarball:
  cd proftpd-dir/contrib/
  tar zxvf /path/to/mod_sftp-version.tar.gz
after unpacking the latest proftpd-1.3.2 source code. For including mod_sftp as a staticly linked module:
  ./configure --enable-openssl --with-modules=mod_sftp ...
Alternatively, mod_sftp can be built as a DSO module:
  ./configure --enable-dso --enable-openssl --with-shared=mod_sftp ...
Then follow the usual steps:
  make
  make install


Usage

Compiler Warnings
When compiling mod_sftp, you may notice the following compiler warning:

  contrib/mod_sftp/mod_sftp.a(fxp.o): In function `fxp_handle_create':
  fxp.c:(.text+0x4dc8): warning: the use of `mktemp' is dangerous, better use `mkstemp'
This warning can be ignored.

The mktemp(3) function is generally considered unsafe because, in the past, many applications would use this function to create the names of temporary files. The actual problem was not the mktemp(3) function itself, but rather that the applications did not check to see if the name generated by mktemp(3) already existed in filesytem first. This lead to race conditions where local users could create symlinks of the generated names, and the application would overwrite the symlinked file.

In the case of mod_sftp, however, the mktemp(3) function is not used to create files. Instead, it is used to create arbitrary unique strings that are used as "handles", as references, in the protocol. These strings have no relation to any actual path on the filesystem, and thus do not suffer from the above race condition.

Access Controls for SFTP Requests
Some of the requests supported by SFTP have FTP command equivalents. Other requests in SFTP have no FTP command equivalent. This makes the use of <Limit> sections for access controls in mod_sftp a little interesting.

First, the familiar territory. The following shows the <Limit> sections for FTP commands (just as for normal FTP sessions) which are honored by mod_sftp:

  • <Limit DELE>
    Applies to the REMOVE SFTP request
  • <Limit MKD XMKD>
    Applies to the MKDIR SFTP request
  • <Limit MLSD>
    Applies to the OPENDIR SFTP request
  • <Limit LIST NLST>
    Applies to the READDIR SFTP request, resulting in an empty directory listing.
  • <Limit RETR>
    Applies to the READ SFTP request
  • <Limit RNFR RNTO>
    Applies to the RENAME SFTP request
  • <Limit RMD XRMD>
    Applies to the RMDIR SFTP request
  • <Limit STOR>
    Applies to the WRITE SFTP request
  • <Limit SITE_CHGRP>
    Applies to the SETSTAT and FSETSTAT SFTP requests when they change file ownership
  • <Limit SITE_CHMOD>
    Applies to the SETSTAT and FSETSTAT SFTP requests when they change file permissions
Thus you can see that mod_sftp will reuse much of your existing <Limit>-based access controls for SFTP sessions.

For those SFTP requests which have no direct FTP equivalents elsewhere in proftpd, the mod_sftp module supports some slightly different <Limit> sections. Note that the following does not apply to FTP sessions, nor does it imply that FTP supports these commands:

  • <Limit FSTAT>
    Applies to the FSTAT SFTP request
  • <Limit LSTAT>
    Applies to the LSTAT SFTP request
  • <Limit LOCK>
    Applies to the LOCK and UNLOCK SFTP requests
  • <Limit OPEN>
    Applies to the OPEN SFTP request
  • <Limit READLINK>
    Applies to the READLINK SFTP request
  • <Limit SETSTAT>
    Applies to the FSETSTAT and SETSTAT SFTP requests
  • <Limit STAT>
    Applies to the STAT SFTP request
  • <Limit SYMLINK>
    Applies to the LINK and SYMLINK SFTP requests
Note that not all versions of SFTP support all of these requests; the LOCK and UNLOCK requests, for example, appear only in later versions of SFTP.

What about the READ and WRITE command groups?

  • <Limit READ>
    Applies to the SYMLINK and READ SFTP requests
  • <Limit WRITE>
    Applies to the LOCK, SETSTAT, SYMLINK, and WRITE SFTP requests

Environment Variables
The mod_sftp module will set the following environment variables whenever an SSH2 client connects:

  • SFTP
  • SFTP_LIBRARY_VERSION
  • SSH_CONNECTION
In addition, the following environment variables will be set (with appropriate values), once the client has successfully exchanged keys with mod_sftp:
  • SFTP_CLIENT_CIPHER_ALGO
  • SFTP_CLIENT_COMPRESSION_ALGO
  • SFTP_CLIENT_MAC_ALGO
  • SFTP_SERVER_CIPHER_ALGO
  • SFTP_SERVER_COMPRESSION_ALGO
  • SFTP_SERVER_MAC_ALGO

These environment variables are intended for informational purposes, e.g. ExtendedLog or SQLLog directives.

SSH2 Public Key Formats
SSH2 uses public keys for authentication and message protection. The very popular OpenSSH server uses a particular file format for storing public keys in files. However, that format is not portable; it uses a format very specific to OpenSSH. Thus the mod_sftp module uses a different format for public keys, specifically, the format specified in
RFC 4716. The hope is that this format is more interoperable with other SSH2/SFTP implementations.

This means that if you wish to use your OpenSSH public keys with the mod_sftp module, you will need to convert them from OpenSSH's format to the RFC4716 format. Fortunately, this is supported by OpenSSH's ssh-keygen utility, e.g.:

  # ssh-keygen -e -f ~/.ssh/id_rsa.pub
The output from this command can be added to the SFTPAuthorizedUserKeys used by mod_sftp.

Note that the RFC4716 format is not to be used with the SFTPHostKey directive. Even though OpenSSH's host keys have ".pub" public equivalents, host keys are different from the per-user keys that are used for authentication.

Known Client Issues
The following lists some of the various client interoperability issues that have been encountered, and how to address them.

SSH Channel Window Sizes
Some SFTP client implementations do not support the large SSH channel window size that the mod_sftp module uses by default. These clients include:

This FAQ describes the configuration to use for such clients.

SSH Protocol Version
If you are using an old ssh.com client, or perhaps a client which derives from the ssh.com (or Tectia) code, you may see the following error in the SFTPLog when trying to connect to mod_sftp:

  Bad protocol version 'SSH-1.99-3.2.9.1 SSH Secure Shell (non-commercial)' from x.x.x.x
To support such clients in mod_sftp, use SFTPOptions to enable compatibility with older protocol versions, e.g.:
  # Support old ssh.com/Tectia clients
  SFTPOptions OldProtocolCompat

SFTP Protocol Versions
Some SFTP clients do not properly handle some of the newer SFTP protocol versions. These clients include:

For these clients, use a SFTPClientMatch rule to restrict the SFTP protocol versions offered by the mod_sftp module, e.g.:
  # Only support SFTP protocol version 1 through 3 for WinSCP and CuteFTP
  SFTPClientMatch WinSCP|ClientSftp sftpProtocolVersion 1-3

KEXINIT Optimization
Some SFTP clients do not like this KEXINIT optimization that the mod_sftp module uses. These clients include:

  • Net::SSH::Perl, Net::SFTP Perl modules
  • edtFTPj
For these clients, use this configuration to disable the optimization:
  # Disable the KEXINIT optimization at the cost of latency
  SFTPOptions PessimisticKexinit

FIPS Compliance
FIPS stands for "Federal Information Processing Standard", and refers to a series of information processing standards issued and used by the US government. When speaking of FIPS and cryptographic software, the pertinent standard in particular is FIPS-140.

How then would you build OpenSSL and mod_sftp, and use them such that mod_sftp would be FIPS-compliant? Using OpenSSL in FIPS mode requires quite a few steps. First, you would configure proftpd to use the mod_sftp module as normal, assuming your OpenSSL installation has been compiled with FIPS support:

  ./configure --enable-openssl --with-modules=mod_sftp ...

Compiling proftpd requires the following, for FIPS support to work properly:

  make CC=/path/to/openssl/bin/fipsld FIPSLD_CC=gcc
The FIPSLD_CC variable should point to your normal C compiler, e.g. gcc. The use of this fipsld program is mandatory. The FIPS standard requires that the linking process happen a very specific way, involving verification of calculated and expected checksums of compiled code, etc. The OpenSSL packages with FIPS support supply this fipsld program which will link the compiled code according to the FIPS specifications. If you do not use fipsld, then attempts to use OpenSSL in FIPS mode will fail. For example, you would see the following if starting a proftpd daemon which has not been linked using fipsld while requesting use of FIPS:
  - mod_sftp/0.0: unable to use FIPS mode: (unknown)
  - Fatal: unable to load module 'mod_sftp.c': Operation not permitted

Now, assuming you have compiled and installed your proftpd properly, e.g.:

  make CC=/path/to/openssl/bin/fipsld FIPSLD_CC=gcc
  make CC=/path/to/openssl/bin/fipsld FIPSLD_CC=gcc install
you will now be ready to start proftpd.

In order for FIPS mode to be effective, OpenSSL must be told to run in FIPS mode from the very beginning. The mod_sftp module initializes the OpenSSL library when the mod_sftp module is loaded, before the proftpd.conf file is parsed. Thus the requesting of FIPS mode cannot be done via a setting in proftpd.conf. (Annoying, I know.)

Instead, you must use the -D command-line parameter when starting proftpd (see the docs for the <IfDefine> and Define directives) to define a specific variable, which the mod_sftp module will look for. Specifically, you will need to start proftpd like thus:

  /path/to/proftpd -DSFTP_USE_FIPS ...
This will define the SFTP_USE_FIPS variable; this tells mod_sftp to initialize OpenSSL using FIPS mode. When this works, you will see the following when proftpd starts up:
  - mod_sftp/0.0: FIPS mode enabled

When mod_sftp detects that OpenSSL has been configured for FIPS mode, it will refuse to advertise support for the following cipher algorithms:

  • arcfour128
  • arcfour256
  • blowfish-cbc
  • blowfish-ctr
  • cast128-cbc
and for the following digest algorithms:
  • hmac-md5
  • hmac-md5-96
  • hmac-ripemd160 as these algorithms are not compliant with the FIPS specification.

    For additional reading on OpenSSL and FIPS, see:

      http://www.openssl.org/docs/fips/SecurityPolicy-1.1.1.pdf
      http://www.openssl.org/docs/fips/UserGuide-1.1.1.pdf
    

    Example Configuration
    When using mod_sftp to handle SFTP connections, you will want to create a separate <VirtualHost> section for the mod_sftp configuration. SSH2 (and thus SFTP) requires a different port than FTP; in order to listen on different ports, proftpd requires different <VirtualHost> sections. You can have multiple <VirtualHost> sections for the same address (IP address or DNS name), just different Port directives.

      <IfModule mod_sftp.c>
        <VirtualHost a.b.c.d>
          SFTPEngine on
          SFTPLog /etc/proftpd/sftp/sftp.log
    
          # Configure the server to listen on the normal SSH2 port, port 22
          Port 22
    
          # Configure the RSA, DSA, and ECDSA host keys, using the same host key
          # files that OpenSSH uses. 
          SFTPHostKey /etc/ssh_host_rsa_key
          SFTPHostKey /etc/ssh_host_dsa_key
          SFTPHostKey /etc/ssh_host_ecdsa_key
    
          # Configure the file used for comparing authorized public keys of users.
          SFTPAuthorizedUserKeys file:~/.sftp/authorized_keys
    
          # Enable compression
          SFTPCompression delayed
    
          # Allow the same number of authentication attempts as OpenSSH.
          #
          # It is recommended that you explicitly configure MaxLoginAttempts
          # for your SSH2/SFTP instance to be higher than the normal
          # MaxLoginAttempts value for FTP, as there are more ways to authenticate
          # using SSH2.
          MaxLoginAttempts 6
    
        </VirtualHost>
      </IfModule>
    

    Logging
    The mod_sftp module supports different forms of logging. The main module logging is done via the SFTPLog directive. For debugging purposes, the module also uses trace logging, via the module-specific "scp", "sftp", and "ssh2" log channels. Thus for trace logging, to aid in debugging, you would use the following in your proftpd.conf:

      TraceLog /path/to/sftp-trace.log
      Trace scp:20 sftp:20 ssh2:20
    
    This trace logging can generate large files; it is intended for debugging use only, and should be removed from any production configuration.

    Suggested Future Features
    The following lists the features I hope to add to mod_sftp, according to need, demand, inclination, and time:

    • Look up authorized public keys from LDAP directories
    • Honor the MaxTransferPerHost, MaxTransfersPerUser, MaxRetrieveFileSize directives

    Frequently Asked Questions

    Question: When I telnet to port 22 of other SSH2 servers, I see the SSH2 version banner displayed, e.g.:

      # telnet example.com 22
      Trying 1.2.3.4...
      Connected to example.com.
      Escape character is '^]'.
      SSH-1.99-OpenSSH_5.1
    
    However, when I telnet to the port on which mod_sftp is listening, I see the version banner plus some data which can't be rendered in the terminal. What is that extra data?
    Answer: The short answer is that mod_sftp is pre-emptively sending the first key exchange data; it is this data which is not displayed well.

    This pre-emptive sending of the first key exchange message is an optimization. The SSH2 protocol (and many SSH2 servers) start off doing:

     (1) client ------------ connect -------------> server
     (2) client <-------- version banner ---------- server
     (3) client --- client's first key exchange --> server
     (4) client <-- server's first key exchange --- server
    
    So you can see that there's some back and forth. The "first key exchange" messages sent by the client are always the same for that client, likewise the server always sends the same "first key exchange" message (based on its configuration). So the above has several TCP packets and ACKs that need to be sent back and forth.

    The mod_sftp module avoids one unnecessary TCP packet+ACK by sending its version banner and its first key exchange message in the same TCP packet:

     (1) client ------------ connect -------------> server
     (2) client <-- version banner/1st key exch---- server
     (3) client --- client's first key exchange --> server
    
    This helps cut down on the latency during startup, since mod_sftp saves on one TCP round-trip time.

    This optimization was added after reading this informative paper on SSH and SSL/TLS by Peter Gutmann:

      Performance Characteristics of Application-level Security Protocols
    

    Question: My SSH2/SFTP client dies when trying to connect to mod_sftp. The login succeeds, but then the client is disconnected. The client logs show something like:

      ServerMaxPacket(32768) ServerWindow(-1) (from WS_FTP)
    
    or
      debug1: channel 0: open confirm rwindow -1 rmax 32768 (from OpenSSH_3.0.2p1)
    
    Answer: The issue, in short, involves that "-1" value you see, and the particular client implementation in question. (The example error above is from an old OpenSSH client.)

    The SSH2 protocol specifications say that implementations must encode the SSH2 channel "window size" as a 32-bit unsigned number. This means that the maximum window size is effectively 4294967295 (i.e. 2 ^ 32 - 1). This maximum window size is what mod_sftp uses by default. However, some client implementations use a signed data type for holding this value. This means that the value that mod_sftp sends to the client becomes a negative signed number to the client (the large value "wraps around" to the negative value), and the client chokes.

    As another example, the WS_FTP Pro client has this same problem; in the client, you will see something like the following error:

      Started subsystem "sftp" on channel 0760a2ce
      error 84350000 initializing sftp protocol
      Sending channel close message for channel 0760a2ce
      SSH Transport closed.
    

    There are two approaches for handling such cases. You can use the SFTPClientMatch directive to set a smaller channel window size for that particular client, e.g.:

      SFTPClientMatch ".*WS_FTP.*" channelWindowSize 256MB
      SFTPClientMatch ".*Axway" channelWindowSize 256MB
    
    or you can use SFTPClientMatch to set a general channel window size for all clients:
      SFTPClientMatch .* channelWindowSize 256MB
    

    The larger the channel window size, the better. (Note that the SSH2 channel window size has absolutely no relation to the TCP window size.) The smaller this SSH2 channel window size, the more frequently the peer needs to send a "window size adjustment" SSH2 request (which entails its own TCP packet and ACK) in order to keep the window size open. The larger the channel window size, the fewer "window size adjustment" requests the peer has to send, and thus the fewer TCP packets/ACKs are needed. Since each TCP packet adds latency, the smaller channel window sizes can increase the latency for data transfers.

    For this reason, my personal recommendation is to only set smaller channel window sizes for those SSH2/SFTP clients which need it; no need to incur the additional latency if the client supports the larger window sizes.

    Question: Can I configure mod_sftp to be an OpenSSH subsystem, e.g. by using the following in my sshd_config file:

      Subsystem  sftp  /usr/local/sbin/proftpd
    
    Answer: No. The mod_sftp module cannot be used as an OpenSSH subsystem because proftpd needs more information about the session than is provided to OpenSSH subsystems. ProFTPD needs to know all of the information about the authenticated user, the SSH2 channel IDs being used for the SFTP/SCP sessions, etc.

    Question: How can I configure proftpd so that it can handle both FTP and SFTP at the same time?
    Answer: The key to doing this is to create a <VirtualHost> section just for the mod_sftp configuration, listening on the address and port that you wish, e.g.:

      # The FTP configuration
      DefaultAddress a.b.c.d
      Port 21
    
      <IfModule mod_sftp.c>
        <VirtualHost a.b.c.d>
          # The SFTP configuration
          Port 22
    
          SFTPEngine on
          ...
        </VirtualHost>
      </IfModule>
    

    Question: How can I configure proftpd so that it only accepts SFTP connections (via mod_sftp), and no FTP connections?
    Answer: Use the following in your proftpd.conf:

      <Limit LOGIN>
        DenyAll
      </Limit>
    
      <VirtualHost a.b.c.d>
        <Limit LOGIN>
          AllowAll
        </Limit>
    
        SFTPEngine on
        ...
      </VirtualHost>
    
    The idea is to use the <Limit LOGIN> to deny all logins to any/all virtual host sections except for the mod_sftp section.

    Question: I followed the instructions to convert my authorized keys from OpenSSH to RFC4716 format, yet I see the following error in my SFTPLog:

      mod_sftp/0.9.7[31050]: line too long (74) on line 1 of 'authorized_keys'
    
    What can I do to fix this?

    Answer: OpenSSH's ssh-keygen tool had a bug where the RFC4716 keys it would generate might not comply to the RFC; see the
    OpenSSH bug filed for this issue.

    Chances are that the offending line in the RFC4716 key is a "Comment: " header that is too long. Simply delete that "Comment: " line; the mod_sftp ignores this header.

    Question: Is it true that using CBC mode ciphers in SSH is insecure?
    Answer: It is true that there are a couple of published theoretical attacks against the SSH protocol when CBC ciphers are used, including Rogaway, Wai, and Bellare (see RFC4251, Section 9.3.1) and
    "Plaintext Recovery Attacks Against SSH" (CPNI-957037).

    However, these attacks can be mitigated by countermeasures in the SSH implementation. The use of SSH_MSG_IGNORE messages for the Rogaway attack, and the delayed checking of packet length fields until the MAC check has passed (and then reading in a random amount of additional data from the network) to migitate CPNI-957037, are both implemented within the mod_sftp module as security measures.

    Question: I am trying to use ListOptions to change what is displayed for files in my SFTP clients, but it is not working. Why?
    Answer: Unlike FTP, in SFTP it is the client, not the server, which determines what to display to the end user. Thus the ListOptions directive is not honored by mod_sftp.

    Question: If I use a configuration like this:

      <Directory /path/to/upload>
        <Limit WRITE>
          AllowAll
        </Limit>
    
        <Limit SITE_CHMOD>
          DenyAll
        </Limit>
      </Directory>
    
    then why do my SFTP uploads fail, when the same configuration allows uploads to succeed using FTP?
    Answer: When a file is uploaded using FTP, the only parts of the file uploaded are its contents but not the file metadata (e.g. not the file timestamps or permissions). Separate FTP commands are used to sent the file metadata to the server.

    However, the SFTP protocol sends the file metadata as part of the normal upload. In the configuration above, the limit on SITE CHMOD is being applied to the SFTP upload. If you do not want this, and want your SFTP uploads to be more like your FTP uploads, then you should use:

      SFTPOptions IgnoreSFTPUploadPerms
    
    in your mod_sftp configuration.

    Question: I use UserOwner and GroupOwner in my mod_sftp configuration, but they are not being applied properly. Is this a bug?
    Answer: No.

    By default, the mod_sftp module drops root privileges as soon as it can, which is just after the user has been authenticated. Without root privileges, mod_sftp cannot change the ownership of files uploaded via SFTP/SCP as per UserOwner/GroupOwner settings.

    In ProFTPD 1.3.4rc1, honoring of the UserOwner and GroupOwner directives was added to the mod_sftp module. However, you will also need to add the following to your mod_sftp configuration to make them work properly:

      RootRevoke off
    
    This explicitly tells the mod_sftp to not drop root privileges after authentication, and instead to keep them for the duration of the session.

    Question: Why can't I use ssh to connect to my proftpd+mod_sftp server? When I try, I see:

      # ssh user@host
      Enter passphrase for key '/home/user/.ssh/id_rsa': 
      PTY allocation request failed on channel 0
      shell request failed on channel 0
    
    Answer: The mod_sftp module supports file transfers via SFTP and SCP. It does not support shell access, which is what the ssh command-line client tries to use. The above error messages from ssh show that mod_sftp refused the shell access requests.

    Question: When I try to start proftpd with mod_sftp configured to use my existing host key, it fails with one of the following error messages:

      error reading passphrase for SFTPHostKey 'hostkey': Invalid argument
      error reading passphrase for SFTPHostKey 'hostkey': (unknown)
    
    The permissions on my hostkey are fine, and it is not passphrase-protected. Is this a bug?

    Answer: You are probably trying to use a host key generated by Tectia's SSH software (or an older ssh.com host key).

    The mod_sftp module expects the configured SFTPHostKey file to be in the same format as used by OpenSSH. To check the format, run this command:

      # grep BEGIN hostkey
    
    If you see either of the following lines:
      -----BEGIN RSA PRIVATE KEY-----
      -----BEGIN DSA PRIVATE KEY-----
    
    then the format should be correct. If instead you see:
      ---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----
    
    then the format is incorrect. The above line indicates that your host key was generated by Tectia (nee ssh.com), and needs to be converted to a different format.

    To convert the format of your Tectia host key, use OpenSSH's ssh-keygen (not Tectia's ssh-keygen) and do the following:

      # ssh-keygen -i -f hostkey > /path/to/new-file
    
    The configure your SFTPHostKey directive with the path to the new file.

    Question: When I start proftpd, I see warnings that look like this:

      - mod_sftp/0.9.7: compiled using OpenSSL version 'OpenSSL 0.9.8n 24 Mar 2010' headers, but linked to OpenSSL version 'OpenSSL 0.9.8q 2 Dec 2010' library
    
    What does this mean?
    Answer: That is an informational/warning message.

    Some systems are badly maintained by their admins (and/or by the packages installed on the systems), such that the OpenSSL headers can become quite badly out of sync with the OpenSSL libraries. If this discrepancy becomes bad enough, you can see strange behavior from OpenSSL, ranging from random behavior to segfaults. So mod_sftp tries to let the admin know about the system's mismatched OpenSSL header/library versions.

    Usually a minor OpenSSL version difference like the example above is OK, but it really depends on exactly what changed in OpenSSL, and how.

    If you see the above message, it is not a requirement that you recompile proftpd against the OpenSSL headers of the same version as the OpenSSL libraries. However, the version discrepancy is a possible source of trouble.

    Question: When a client first connects to mod_sftp and starts the SSH handshake, the client sees that mod_sftp provides an SSH version identifier like "SSH-2.0-mod_sftp/0.9.8". Is there any way I can tell mod_sftp to hide/change that version?
    Answer: Yes. As of proftpd-1.3.5rc1, the mod_sftp module will honor the
    ServerIdent directive.

    For example, to see just "SSH-2.0-mod_sftp", without any mod_sftp version suffix, use the following within your mod_sftp <VirtualHost>:

      # Tell mod_sftp to not reveal its module version in the SSH version
      # identification
      ServerIdent off
    
    You can also use ServerIdent to make mod_sftp say it is something else completely, like this:
      # Tell mod_sftp to advertise itself as an OpenSSH server
      ServerIdent on "OpenSSH_5.6p1"
    

    Question: I notice that when I use some SFTP clients (e.g. DreamWeaver) with mod_sftp, the network performance is 5-6 times slower than with other SFTP clients. Using the same SFTP client against OpenSSH doesn't show the same slowdown. Network tools such as Wireshark show that mod_sftp is sending 2 TCP packets for each SFTP request, whereas OpenSSH only sends 1 TCP packet for each SFTP request. Why is mod_sftp so much slower than OpenSSH, but only for some SFTP clients?
    Answer: Investigations into this mod_sftp behavior have shown it to be caused by the
    SFTPTrafficPolicy behavior, particularly when the SFTP client negotiates the use of a CBC cipher.

    The recommended action to take is to disable the use of CBC ciphers, which will cause the SFTPTrafficPolicy mitigation to not go into effect, which keeps the number of SSH messages lower, thus improving network latency. Thus the change to make for your mod_sftp configuration is:

      # Remove the CBC ciphers from the ciphers we advertise
      SFTPCiphers aes256-ctr aes192-ctr aes128-ctr blowfish-ctr arcfour256 arcfour128 3des-ctr
    

    Question: When I use mod_sftp and get a directory listing, I notice that the timestamps on the files are localised (e.g. are in French). When I use OpenSSH, the timestamps are always in English. How I get get mod_sftp to behave like OpenSSH, and not localise the timestamps?
    Answer: This happens when your proftpd has been built with the --enable-nls configure option. To check, use `proftpd -V':

      ...
      Features:
        ...
        + NLS support
        ...
    
    This means that proftpd honors any locale-related environment variables when it starts up. The reason you see localised timestamps in the directory listings is probably because your environment has something like LANG=fr_FR.utf8.

    To tell proftpd to ignore that environment variable, you need to use this at the top of your proftpd.conf:

      Unsetenv LANG
    

    Question: When I use my SFTP client, I see something like this when I try to connect to proftpd with mod_sftp:

      500 SSH-2.0-OPENSSH 6.2 not understood
    
    Why would this happen?
    Answer: A "500 ... not understood" is an FTP response, not an SFTP response. This usually happens when your SFTP client connects to an FTP virtual host/port (versus an SFTP virtual host/port). So either a) the SFTP client is connecting to the wrong port on your server, or b) perhaps "SFTPEngine on" is not set in the virtual host for that port.



    Author: $Author: castaglia $
    Last Updated: $Date: 2013/06/06 23:39:28 $


    © Copyright 2008-2013 TJ Saunders
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_sql_passwd.html0000644000175000017500000004625612155404527022701 0ustar frankiefrankie ProFTPD module mod_sql_passwd

    ProFTPD module mod_sql_passwd



    Many FTP sites use SQL databases for storing user accounts, including the user name and password. And while the mod_sql module provides support for some formats for the passwords stored in SQL databases, many sites have other formats which are not supported by mod_sql. These other formats often include MD5 or SHA1 passwords, base64-encoded or hex-encoded, without the prefix which is required by mod_sql's "OpenSSL" SQLAuthType.

    The mod_sql_passwd module provides support for some of these other formats. When the mod_sql_passwd module is enabled, you can configure SQLAuthTypes of "MD5", "SHA1", "SHA256", or "SHA512", as well as the existing types supported by mod_sql.

    This module is contained in the mod_sql_passwd.c file for ProFTPD 1.3.x, and is not compiled by default. Installation instructions are discussed here; a discussion on usage is also available.

    This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/).

    This product includes cryptographic software written by Eric Young (eay@cryptsoft.com).

    The most current version of mod_sql_passwd is distributed with ProFTPD.

    Author

    Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.

    Directives


    SQLPasswordEncoding

    Syntax: SQLPasswordEncoding encoding
    Default: hex
    Context: "server config", <VirtualHost>, <Global>
    Module: mod_sql_passwd
    Compatibility: 1.3.3rc2 and later

    The SQLPasswordEncoding directive configures the encoding that mod_sql_passwd expects when handling password values retrieved from a SQL database.

    The following encoding values are currently supported:

    • base64
    • hex (for lowercase hex values)
    • HEX (for uppercase hex values)

    If no SQLPasswordEncoding directive is configured, mod_sql_passwd will use "hex" by default.


    SQLPasswordEngine

    Syntax: SQLPasswordEngine on|off
    Default: off
    Context: "server config", <VirtualHost>, <Global>
    Module: mod_sql_passwd
    Compatibility: 1.3.3rc2 and later

    The SQLPasswordEngine directive enables or disables the module's registered SQLAuthType handlers.


    SQLPasswordOptions

    Syntax: SQLPasswordOptions opts
    Default: None
    Context: "server config", <VirtualHost>, <Global>
    Module: mod_sql_passwd
    Compatibility: 1.3.4rc2 and later

    The SQLPasswordOptions directive is used to configure various behaviors of mod_sql_passwd. Note: all of the configured SQLPasswordOptions parameters must appear on the same line in the configuration; only the first SQLPassworOptions directive that appears in the configuration is used.

    Example:

      SQLPasswordOptions HashEncodeSalt HashEncodePassword
    

    The following options are currently supported:

    • HashPassword
    • HashEncodePassword
    • HashSalt
    • HashEncodeSalt

    See the transformations section for a fuller description of how mod_sql_passwd operates on the password and salt data.


    SQLPasswordPBKDF2

    Syntax: SQLPasswordPBKDF2 digest iterations length
    Default: None
    Context: "server config", <VirtualHost>, <Global>
    Module: mod_sql_passwd
    Compatibility: 1.3.5rc3 and later

    The SQLPasswordPBKDF2 directive configures the input parameters to be used for PBKDF2 (Password-Based Key Derivation Function, version 2) passwords. The digest parameter specifies the digest algorithm to use (e.g. "sha1" or "sha512"); the iterations specifies the number of iterations to use for the key derivation, and length indicates the number of bytes to emit for the derived key.

    Note that PBKDF2 requires that a salt be available, e.g. via SQLPasswordSaltFile or SQLPasswordUserSalt.

    Per RFC 2898, the salt used should be 8 bytes or longer in length; this RFC also recommends that iterations be 1000 or greater.

    Example:

      # Tell mod_sql to use PBKDF2 passwords
      SQLAuthTypes pbkdf2
      ...
    
      # Use the SHA1 digest algorithm, 1000 iterations, and expect an output
      # length of 20 bytes.
      SQLPasswordPBKDF2 sha1 1000 20
    
      SQLPasswordSaltFile /path/to/salt/file
    

    Use of digest algorithms other than SHA1 for SQLPasswordPBKDF2 requires OpenSSL-1.0.0c or later; earlier versions did not have the necessary APIs.


    SQLPasswordRounds

    Syntax: SQLPasswordRounds count
    Default: 1
    Context: "server config", <VirtualHost>, <Global>
    Module: mod_sql_passwd
    Compatibility: 1.3.4rc2 and later

    The SQLPasswordRounds directive configures the number of rounds through which the password (and possibly salt) data will be hashed and encoded. The count parameter must be greater than 1.

    See the transformations section for a fuller description of how mod_sql_passwd operates on the password and salt data.


    SQLPasswordSaltFile

    Syntax: SQLPasswordSaltFile path|"none" ["Prepend"|"Append"]
    Default: none
    Context: "server config", <VirtualHost>, <Global>
    Module: mod_sql_passwd
    Compatibility: 1.3.3rc2 and later

    The SQLPasswordSaltFile directive configures a file which contains salt data. This salt will be added to the digest, along with the password sent by the client. Note that the salt will be used for all users.

    Since many editors will automatically add a newline when writing a file, the mod_sql_passwd file will automatically trim the last newline in the salt data, if there is one. This means that if your salt must end in a newline character, then your SQLPasswordSaltFile must contain "salt\n\n".

    When using salted passwords, some systems will prepend the salt as a prefix to the data, and others will append the salt as a suffix. The optional second parameter to SQLPasswordSaltFile controls how this module will use the salt:

      SQLPasswordSaltFile /path/to/salt Prepend
    
    tells mod_sql_passwd to prepend the salt as a prefix, and:
      SQLPasswordSaltFile /path/to/salt Append
    
    will cause the salt to be appended as a sufix. Note that the default behavior is to append the salt as a suffix.

    If no SQLPasswordSaltFile is configured, then no salting is done.


    SQLPasswordUserSalt

    Syntax: SQLPasswordUserSalt "name"|source ["Prepend"|"Append"]
    Default: none
    Context: "server config", <VirtualHost>, <Global>
    Module: mod_sql_passwd
    Compatibility: 1.3.3 and later

    The SQLPasswordUserSalt directive configures a per-user salt that will be added to the digest, along with the password sent by the client.

    If "name" is specified, then the per-user salt data will be the name of the user logging in. Alternatively, you can configure a SQLNamedQuery which returns a single column of a single row, containing a string to use as the salt data, e.g.:

      SQLNamedQuery get-user-salt SELECT "salt FROM user_salts WHERE user_name = '%{0}'"
      SQLPasswordUserSalt sql:/get-user-salt
    

    When using salted passwords, some systems will prepend the salt as a prefix to the data, and others will append the salt as a suffix. The optional second parameter to SQLPasswordUserSalt controls how this module will use the salt:

      SQLPasswordUserSalt name Prepend
    
    tells mod_sql_passwd to prepend the salt as a prefix, and:
      SQLPasswordUserSalt name Append
    
    will cause the salt to be appended as a sufix. Note that the default behavior is to append the salt as a suffix.

    Installation

    The mod_sql_passwd module is distributed with ProFTPD. Simply follow the normal steps for using third-party modules in proftpd. The mod_sql_passwd module requires OpenSSL support, so you must use the --enable-openssl configuration option. NOTE: it is important that mod_sql_passwd appear after mod_sql in your --with-modules configure option:
      ./configure --enable-openssl --with-modules=mod_sql:mod_sql_passwd ...
    
    To build mod_sql_passwd as a DSO module:
      ./configure --enable-dso --enable-openssl --with-shared=mod_sql_passwd
    
    Then follow the usual steps:
      make
      make install
    

    For those with an existing ProFTPD installation, you can use the prxs tool to add mod_sql_passwd, as a DSO module, to your existing server:

      # prxs -c -i -d mod_sql_passwd.c
    

    Usage

    The following examples demonstrate how the mod_sql_passwd can be used.

    To configure mod_sql_passwd to handle MD5 passwords that are base64-encoded, use:

      <IfModule mod_sql_passwd.c>
        SQLPasswordEngine on
        SQLPasswordEncoding base64
      </IfModule>
    
      <IfModule mod_sql.c>
        ...
    
        # Now that mod_sql_passwd is used, we can configure "MD5" as an
        # SQLAuthType that mod_sql will handle.
        SQLAuthTypes MD5
      </IfModule>
    

    To have mod_sql_passwd to handle hex-encoded (and in lowercase) passwords, use:

      <IfModule mod_sql_passwd.c>
        SQLPasswordEngine on
        SQLPasswordEncoding hex
      </IfModule>
    

    And if for some reason your database values are stored as hex values in uppercase, you would use:

      <IfModule mod_sql_passwd.c>
        SQLPasswordEngine on
        SQLPasswordEncoding HEX
      </IfModule>
    

    To use salted passwords, write the salt to use into a file, and configure the mod_sql_passwd module to use it:

      <IfModule mod_sql_passwd.c>
        SQLPasswordEngine on
        SQLPasswordEncoding hex
        SQLPasswordSaltFile /path/to/salt
      </IfModule>
    

    Processing of Password and Salt Data
    The logical description of the processing that mod_sql_passwd does can be expressed as:

      ENCODE(HASH(data))
    
    where data is comprised of the password, and possibly a salt. The function ENCODE() is determined by SQLPasswordEncoding, and the function HASH() by SQLAuthTypes.

    Thus if we use a configuration like:

      SQLAuthTypes MD5
      SQLPasswordEncoding hex
    
    Then mod_sql_passwd performs the following processing:
      hex(MD5(data))
    
    in order to calculate the value that it will compare against the password value stored for the authenticating client.

    Using Salts
    By default, the mod_sql_passwd module uses the password, as sent by the client, as the data on which to perform its processing. In many cases, however, a salt is needed in addition to the password. The SQLPasswordSaltFile and SQLPasswordUserSalt directives are used to tell mod_sql_passwd that it should add a salt to the data before processing it. These directives also specify whether the salt should be prepended to the password, e.g.:

      data = salt + password
    
    or appended to the password, e.g.:
      data = password + salt
    

    Let's show a configuration which uses a prepended salt:

      SQLAuthTypes MD5
      SQLPasswordEncoding hex
      SQLPasswordSaltFile /path/to/salt.data Prepend
    
    This means that mod_sql_passwd would end up checking the following computed value against the value in the database:
      hex(MD5(salt + password))
    

    Some sites will have even more complex requirements for how the data processed by mod_sql_passwd need to be constructed. The salt data may need to be hashed before being used with the password, or may need to be hashed and encoded before use. Or maybe the password data needs to be hashed before use with the salt, or hashed and encoded. The SQLPasswordOptions directive supports options for supporting these use cases.

    Each of the following examples assumes the following configuration:

      SQLAuthTypes MD5
      SQLPasswordEncoding hex
      SQLPasswordSaltFile /path/to/salt.data Prepend
    
    Let's look at each of the SQLPasswordOptions in turn:
    • HashPassword

      This option says that mod_sql_passwd should use the HASH() function on the password data before using it, regardless of whether a salt is used or not. I.e.:

        data = salt + HASH(password)
      
      which assuming hex and MD5, means:
        data = salt + MD5(password)
      
    • HashSalt

      This option says that mod_sql_passwd should use the HASH() function on the salt data before using it. If no salt is used, this option is silently ignored. Thus:

        data = HASH(salt) + password
      
      which assuming hex and MD5, means:
        data = MD5(salt) + password
      
    • HashEncodePassword

      This option says that mod_sql_passwd should use the HASH() function and then the ENCODE() function on the password data before using it. This option is only useful when salts are also used. Thus:

        data = salt + ENCODE(HASH(password))
      
      which assuming hex and MD5, means:
        data = salt + hex(MD5(password))
      
      Note: If no salt is present, this option will be ignored. Without a salt, this option is equivalent to adding another round of transformation, which is not an obvious side effect.
    • HashEncodeSalt

      This option says that mod_sql_passwd should use the HASH() function and then the ENCODE() function on the salt data before using it. If no salt is used, this option is silently ignored. Thus:

        data = ENCODE(HASH(salt)) + password
      
      which assuming hex and MD5, means:
        data = hex(MD5(salt)) + password
      

    Of course, these various options can be combined:

      SQLPasswordOptions HashEncodePassword HashEncodeSalt
    
    which would cause the data on which mod_sql_passwd operates to be constructed like so:
        data = ENCODE(HASH(salt)) + ENCODE(HASH(password))
        data = hex(MD5(salt)) + hex(MD5(password))
    

    Rounds
    For convenience, let's assume that the function TRANSFORM encompasses the entire ENCODE(HASH()) operation:

      TRANSFORM(data) = ENCODE(HASH(data))
    
    Let's also assume that passwords are stored in your database using something like this:
      hex(MD5(hex(MD5(hex(MD5(data))))))
    
    That means that the data value has gone through multiple rounds of the TRANSFORM function, e.g.:
      TRANSFORM(TRANSFORM(TRANSFORM(data)))
    
    In this case, there are 3 rounds of transformation:
      for (i = 0; i < nrounds; i++)
        data = TRANSFORM(data)
    

    Using the above example case, you would configure mod_sql_passwd to perform multiple rounds of transformation using the SQLPasswordRounds directive, like so:

      SQLAuthTypes MD5
      SQLPasswordEncoding hex
      SQLPasswordRounds 3
    
    The combination of SQLPasswordOptions and SQLPasswordRounds means that quite few combinations of password values can be supported by the mod_sql_passwd module.



    Author: $Author: castaglia $
    Last Updated: $Date: 2013/06/10 17:13:59 $


    © Copyright 2009-2013 TJ Saunders
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_sql_odbc.html0000644000175000017500000002277511553405520022302 0ustar frankiefrankie ProFTPD module mod_sql_odbc

    ProFTPD module mod_sql_odbc



    ODBC means Open Database Connectivity, and defines a standard way of connecting to a database server such as MySQL, Postgres, SQL Server, Oracle, etc. Many of the these databases also provide their own native APIs for connectivity, in addition to supporting ODBC. Other databases provide ODBC support, but no support for native connectivity.

    The ProFTPD distribution includes the mod_sql_mysql module for talking to a MySQL database using the native MySQL API, and a mod_sql_postgres for connecting to Postgres databases using the native Postgres API. However, there was no support for databases other than these -- until now. The purpose of the mod_sql_odbc module is to allow ProFTPD's mod_sql module to connect to any database that supports ODBC. This module also allows proftpd to work with databases that may already provide APIs for native connectivity, but for which a specific mod_sql has not yet been developed.

    This module is contained in the mod_sql_odbc.c file for ProFTPD 1.3.x, and is not compiled by default. Installation instructions are discussed here.

    The most current version of mod_sql_odbc is distributed with ProFTPD.

    Author

    Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.


    Installation

    The mod_sql_odbc relies on one of the two following libraries for ODBC support:
      http://www.iodbc.org
      http://www.unixodbc.org
    
    One of these ODBC libraries must be installed prior to using mod_sql_odbc.

    Follow the usual steps for using contrib modules in proftpd, making sure to list mod_sql. Note that you will need to use the LIBS environment variable for indicating which ODBC library to link against.

    For example, if you wish to use the unixODBC library, you would use:

      ./configure LIBS=-lodbc --with-modules=mod_sql:mod_sql_odbc ...
      make
      make install
    
    On the other hand, for using the iODBC library, the invocation is slightly different, specifying a different library name:
      ./configure LIBS=-liodbc --with-modules=mod_sql:mod_sql_odbc ...
      make
      make install
    

    You may need to specify the location of the ODBC header and library files in your configure command, e.g.:

      ./configure \
        LD_LIBRARY_PATH=/usr/local/odbc/lib \
        LDFLAGS=-L/usr/local/odbc/lib \
        LIBS=-lodbc \
        --with-modules=mod_sql:mod_sql_odbc \
        --with-includes=/usr/local/odbc/include \
        --with-libraries=/usr/local/odbc/lib
    


    Usage

    Note: some of the following information is taken from:
      http://www.mysql.com/products/myodbc/manual.html#Introduction_to_ODBC
    

    What is ODBC?
    ODBC (Open Data Base Connectivity) provides a way for client programs to access a wide range of databases or data sources.

    ODBC is a standardized API, developed according to the specifications of the SQL Access Group, that allows one to connect to SQL databases. It defines a set of function calls, error codes and data types that can be used to develop database-independent applications. ODBC is usually used when database independence, or simultaneous access to different data sources, is required.

    For more information about ODBC, refer to:

      http://www.microsoft.com/data/odbc/
    

    When should mod_sql_odbc be used?
    There are two cases where a site might need to use the mod_sql_odbc module: when the site's database does not provide a native connectivity API (e.g. FrontBase), and when the site's database does not have a corresponding mod_sql_db module for it. For example, ProFTPD does not have a mod_sql_oracle module. Using mod_sql_odbc and an Oracle-provided ODBC driver would allow a site to have proftpd communicate with their Oracle database.

    How does ODBC work?
    An ODBC driver is a dynamically loadable library that knows how to talk to a specific database. Many databases come bundled with an ODBC driver. The following lists where to find ODBC drivers for the popular MySQL and Postgres databases:

    MySQL ODBC Driver (MyODBC)
    http://www.mysql.com/products/myodbc/

    Postgres ODBC Driver (psqlODBC)
    http://gborg.postgresql.org/project/psqlodbc/

    The ODBC driver manager is a library that manages communication between the ODBC-aware application and ODBC drivers. Its main functionality includes:

    • resolving Data Source Names (DSN)
    • loading and unloading of the drivers
    • processing ODBC function calls or passing them to the driver
    The following lists some commonly used driver managers:
    iODBC ODBC Driver Manager for Unix
    http://www.iodbc.org

    unixODBC Driver Manager for Unix
    http://www.unixodbc.org

    Microsoft Windows ODBC Driver Manager
    http://www.microsoft.com/data/

    Environment Variables
    There are two environment variables that both the iODBC and unixODBC libraries use: LD_LIBRARY_PATH and ODBCINI. The ODBCINI environment variable specifies the configuration file used by the library; this file specifies the driver to use, and any database connection information that driver may need.The LD_LIBRARY_PATH environment variable is used to tell the Driver Manager where it may find the driver libraries. Note that on a Linux system, if the /etc/ld.so.conf contains the directory where the ODBC driver libraries live (and /sbin/ldconfig has been run), use of the LD_LIBRARY_PATH setting may not be necessary.

    Configuring ODBC
    The hard part about using the iODBC or unixODBC Unix driver managers is their configuration. Often in ODBC documentation you will mention of DSNs, or Data Source Names. A data source identifies a path to data that can include a network library, server, database, and other attributes. To connect to a data source, the driver manager checks for specific connection information. This specific connection information is recorded in a file usually called "odbc.ini".

    Example iODBC odbc.ini file:

      [ODBC Data Sources]
      mysql = MySQL ODBC Connector (MyODBC)
    
      [mysql]
      Driver = /usr/local/iodbc/lib/libmyodbc3.so
      Description = MySQL Driver
      Server = localhost
      Database = proftpd
      Port = 3306
      Socket = /tmp/mysql.sock
    

    Example unixODBC odbc.ini file:

      [mysql]
      Description = MySQL
      Driver = mysql
      Server = localhost
      Database = proftpd
      Port = 3306
      Socket = /tmp/mysql.sock
    
    More details on the contents of odbc.ini files, and the different meanings of configuration options, can be found in the respective driver manager documentation.

    Configuring mod_sql_odbc
    For the most part, mod_sql_odbc requires little configuration. It relies on the ODBC driver managers, which in turn use the above environment variables. This means that ODBCINI and LD_LIBRARY_PATH can be set in the environment, before starting proftpd, and mod_sql_odbc would then work. The one required bit of information is the SQLConnectInfo directive. This directive needs to contain the name of the stanza in your odbc.ini file which holds the configuration. Using the example odbc.ini files above, you would need the following in your proftpd.conf:

      # Tells mod_sql to use mod_sql_odbc
      SQLBackend odbc
    
      # Tells mod_sql_odbc which odbc.ini stanza to use
      SQLConnectInfo mysql
    

    Starting with proftpd 1.2.10rc1, it is possible to use the SetEnv configuration directives to set the environment variables directly in the proftpd.conf file, which makes configuration more centralized. Example configuration using SetEnv:

      <IfModule mod_sql_odbc.c>
        SetEnv LD_LIBRARY_PATH /path/to/odbc/lib
        SetEnv ODBCINI /path/to/odbc.ini
      </IfModule>
    
    Please contact the author directly with any questions or comments.



    Author: $Author: castaglia $
    Last Updated: $Date: 2011/04/19 22:23:12 $


    © Copyright 2003-2011 TJ Saunders
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_rewrite.html0000644000175000017500000007264311734257430022202 0ustar frankiefrankie ProFTPD module mod_rewrite

    ProFTPD module mod_rewrite



    This module is contained in the mod_rewrite.c file for ProFTPD 1.3.x, and is not compiled by default. Installation instructions are discussed here.

    The most current version of mod_rewrite is distributed with the ProFTPD source code.

    A discussion of the usage of this module follows.

    Author

    Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.

    Directives


    RewriteCondition

    Syntax: RewriteCondition condition pattern [flags]
    Default: None
    Context: server config, <VirtualHost>, <Global>, <Anonymous>, <Directory>
    Module: mod_rewrite
    Compatibility: 1.2.6rc1 and later

    The RewriteCondition directive defines a rule condition. Precede a RewriteRule directive with one or more RewriteCondition directives. The following rewriting rule is only used if its pattern matches the current state of the FTP command and if these additional conditions apply too.

    Condition is a string which can contain the following expanded constructs in addition to plain text:

    • RewriteRule backreferences
      These are backreferences of the form:
          $N
      
      (0 <= N <= 9) which provide access to the grouped parts (parentheses!) of the pattern from the corresponding RewriteRule directive (the one following the current bunch of RewriteCondition directives). Note that $0 will refer back to the entire original string being matched.

      Use an extra $ character to escape a sequence which looks like a RewriteRule backreference, e.g. $$N.

    • RewriteCondition backreferences
      These are backreferences of the form:
          %N
      
      (0 <= N <= 9) which provide access to the grouped parts (parentheses!) of the pattern from the previous RewriteCondition attached to this RewriteRule.

      Use an extra % character to escape a sequence which looks like a RewriteCondition backreference, e.g. %%N.

    • RewriteMap expansions:
      These are expansions of the form:
         ${map-name:lookup-key|default-value}
      
      See the documentation for RewriteMap for more details.
    • Variable substitutions:
      These are substitutions of the form:

      %a Client IP address
      %c Name of Class for current session
      %f Filename
      %F Transfer path, as seen by the client (only useful for upload/download commands)
      %g Primary group of authenticated user
      %G Supplemental groups of authenticated user
      %h Client DNS name
      %m FTP command
      %p Port of server handling the session
      %u Name of authenticated user
      %U Name of user sent by client via USER
      %v ServerName of server handling the session
      %{TIME_YEAR} Current local year in YYYY format
      %{TIME_MON} Current local month in MM format
      %{TIME_DAY} Current local day in DD format
      %{TIME_WDAY} Current local day of week (Sunday is 0)
      %{TIME_HOUR} Current local hour in HH format
      %{TIME_MIN} Current local minute in mm format
      %{TIME_SEC} Current local second in ss format
      %{TIME} Current local time in YYYYMMDDHHmmss format

    • Environment Variable substitutions:
      These are substitutions of the form:
        %{ENV:variable-name}
      
      If the variable-name environment variable is not present, it will be substituted with the empty string.

    Pattern is the condition pattern, i.e., a regular expression which is applied to the current instance of the condition, i.e., condition is evaluated and then matched against pattern. You can prefix the pattern string with a '!' character (exclamation mark) to specify a non-matching pattern.

    The pattern can also be one of these special variants:

    • <pattern (is lexically lower)
      Treats the pattern as a plain string and compares it lexically to condition. True if condition is lexically lower than pattern
    • >pattern (is lexically greater)
      Treats the pattern as a plain string and compares it lexically to condition. True if condition is lexically greater than pattern
    • =pattern (is lexically equal)
      Treats the pattern as a plain string and compares it lexically to condition. True if condition is lexically equal to pattern, i.e. the two strings are exactly equal (character by character). If pattern is just "" (two quotation marks) this compares condition to the empty string
    • -d (is directory)
      Treats the condition as a pathname and tests if it exists and is a directory
    • -f (is regular file)
      Treats the condition as a pathname and tests if it exists and is a regular file
    • -s (is regular file with size)
      Treats the condition as a pathname and tests if it exists and is a regular file with size greater than zero
    • -l (is symbolic link)
      Treats the condition as a pathname and tests if it exists and is a symbolic link
    Notice: All of these variants can also be prefixed by an exclamation mark ('!') to negate their meaning.

    Flags, if present, modify how this RewriteCondition is evaluated. Supported flags are:

    • nocase|NC (no case)
      This makes the pattern case-insensitive, i.e. there is no difference between 'A-Z' and 'a-z' when pattern is matched against the condition
    • ornext|OR (or next condition)
      Use this to combine rule conditions with a logical OR
      instead of the implicit AND. Typical example:
          RewriteCondition %h  ^host1.*  [OR]
          RewriteCondition %h  ^host2.*  [OR]
          RewriteCondition %h  ^host3.*
          RewriteRule ...some special stuff for any of these hosts...
      
      Without this flag you would have to write the condition/rule combination three times.


    RewriteEngine

    Syntax: RewriteEngine on|off
    Default: off
    Context: server config, <VirtualHost>, <Global>
    Module: mod_rewrite
    Compatibility: 1.2.6rc1 and later

    The RewriteEngine directive enables or disables the module's runtime rewriting engine. If it is set to off this module does no parsing or rewriting at all. Use this directive to disable the module instead of commenting out all mod_rewrite directives.


    RewriteLock

    Syntax: RewriteLock file
    Default: None
    Context: server config, <VirtualHost>, <Global>
    Module: mod_rewrite
    Compatibility: 1.2.6rc1 and later

    The RewriteLock directive sets the filename for a synchronization lockfile which mod_rewrite needs to communicate with RewriteMaps of type fifo. Set file to a local absolute path (not on a NFS-mounted device) when you want to use a rewriting FIFO. It is not required for other types of rewriting maps.


    RewriteLog

    Syntax: RewriteLog file|"none"
    Default: None
    Context: server config, <VirtualHost>, <Global>
    Module: mod_rewrite
    Compatibility: 1.2.6rc1 and later

    The RewriteLog directive is used to a specify a log file for mod_rewrite reporting and debugging, and can be done a per-server basis. The file parameter must be the full path to the file to use for logging. Note that this path must not be to a world-writeable directory and, unless AllowLogSymlinks is explicitly set to on (generally a bad idea), the path must not be a symbolic link. In general, this directive should only be used for debugging your mod_rewrite configuration, and should be removed once debugging is completed; do not use this directive in a production configuration.

    If file is "none", no logging will be done at all; this setting can be used to override a RewriteLog setting inherited from a <Global> context.


    RewriteMap

    Syntax: RewriteMap map-name map-type:map-source
    Default: None
    Context: server config, <VirtualHost>, <Global>
    Module: mod_rewrite
    Compatibility: 1.2.6rc1 and later

    The RewriteMap directive defines a rewriting map which can be used inside rule substitution strings by the mapping-functions to insert/substitute fields through a key lookup. The source of this lookup can be of various types.

    The map-name is the name of the map and will be used to specify a mapping-function for the substitution strings of a rewriting rule via one of the following constructs:

    ${ map-name : lookup-key }
    ${ map-name : lookup-key | default-value}
    When such a construct occurs the map map-name is consulted and the key lookup-key is resolved. If the key is found, the map-function construct is substituted by subst-value. If the key is not found then it is substituted by default-value or by the empty string if no default-value was specified.

    The following combinations for map-type and map-src can be used:

    • Standard Plain Text
      map-type: txt, map-src: Unix filesystem path to valid regular file.

      This is the standard rewriting map feature where the map-src is a plain ASCII file containing either blank lines, comment lines (starting with a '#' character) or pairs like the following - one per line.

      matching-key subst-value

      Example:

          # --------------------------------------------
          # usermap.txt -- map for rewriting user names
          # --------------------------------------------
      
          Dave.Admin      dave       # The Uber-admin
          root            anonymous  # no one should be logging in as root anyway
          
      And, to configure this map to be used:
          RewriteMap real-to-user txt:/path/to/file/usermap.txt
          
    • FIFO/Named Pipe
      map-type: fifo, map-src: Unix filesystem path to valid FIFO.

      For this rewriting map, map-src is a FIFO (a.k.a. named pipe). To create it, you can use the mkfifo(1) command. An external program that opens the FIFO for reading and writing must be started before proftpd is started. This program can communicate with the rewriting engine via the FIFO. For each mapping lookup, it can read the key to lookup as a newline-terminated string from the FIFO. It then has to write back to the FIFO the looked-up value as a newline-terminated string, or just simply newline character (denoting an empty string) if there is no corresponding value for the given key).

      An example program which will implement a 1:1 mapping (i.e., key == value) could be:

          #!/usr/bin/perl
          use strict;
      
          use File::Basename qw(basename);
          use Getopt::Long;
          use IO::Handle;
          use IO::Select;
      
          my $default_delay = 0.5;
          my $program = basename($0);
          my %opts = ();
      
          GetOptions(\%opts, 'delay=f', 'fifo=s', 'help', 'verbose');
      
          usage() if $opts{'help'};
      
          my $delay = $opts{'delay'} ? $opts{'delay'} : $default_delay;
      
          die "$program: missing required --fifo parameter\n" unless $opts{'fifo'};
          my $fifo = $opts{'fifo'};
      
          my $verbose = $opts{'verbose'} ? 1 : 0;
      
          open(my $fifo_fh, "+> $fifo") or die "$program: unable to open $fifo: $!\n";
      
          # Instantiate a Select object for knowing when to read from and write to
          # the FIFO.
          my $sel = IO::Select->new();
      
          while (1) {
      
            # Blocking select() for reading.
            $sel->add($fifo_fh);
      
            print STDERR "$program: selecting for reading\n" if $verbose;
            my ($rfh) = $sel->can_read();
      
            my $key = <$rfh>;
            print STDERR "$program: read '$key'\n" if $verbose;
      
            # Lookup a value for the given key.
            my $value = lookup_value($key);
      
            # Clear the Select object's filehandles.
            $sel->remove();
      
            print $fifo_fh "$value\n" if $verbose;
            $fifo_fh->flush();
      
            print STDERR "$program: wrote '$value'\n" if $verbose;
      
            # Wait for the buffer's byte to be cleared before reading again.
            wait_fifo($fifo_fh);
          }
      
          close($fifo_fh);
          print STDOUT "$program: done\n" if $verbose;
      
          exit 0;
      
          # --------------------------------------------------------------------------
          sub lookup_value {
            my ($key) = @_;
      
            # NOTE: do something to obtain a value for the given key here.
            chomp(my $value = $key);
      
            return $value;
          }
      
          # --------------------------------------------------------------------------
          sub usage {
            print STDOUT <<END_OF_USAGE;
      
          usage: $program [options]
      
            --delay         Configure the buffer check delay.
                            The default is $default_delay seconds.
      
            --fifo          Configure the path to the FIFO.  Required.
      
            --help          Displays this message.
      
            --verbose       Enables verbose output while $program runs.
      
          END_OF_USAGE
      
            exit 0;
          }
      
          # --------------------------------------------------------------------------
          sub wait_fifo {
            my ($fh) = @_;
      
            # Now we get tricky.  Use ioctl(2) to poll the number of bytes to
            # be read from the FIFO filehandle.  When the number drops to zero,
            # it means that the data we just wrote has been read from the buffer
            # by some other process, so we can go back to the top of this loop.
            # Otherwise, if this program loops faster than the reader/writer on
            # the other end of the FIFO, we'd end up reading the data we just
            # wrote.  Quite annoying, actually.
            #
            # Note: this value must be manually extracted from the system header files
            # using the following program:
            #
            # -------- fionread.c -------------------
            #  #include <sys/ioctl.h>
            #
            #  int main(int argc, char *argv[]) {
            #   printf("%#08x\n", FIONREAD);
            #   return 0;
            # }
            # ---------------------------------------
            #
            # > cc -o fionread fionread.c
            # > ./fionread
      
            my $FIONREAD = 0x00541b;
      
            my $size = pack('L', 0);
            ioctl($fh, $FIONREAD, $size) or die "$program: unable to use ioctl: $!\n";
            $size = unpack('L', $size);
      
            while ($size != 0) {
              print STDERR "$program: waiting for buffer to be read\n" if $verbose;
              select(undef, undef, undef, $delay);
      
              $size = pack('L', 0);
              ioctl($fh, $FIONREAD, $size) or die "$program: unable to use ioctl: $!\n";
              $size = unpack('L', $size);
            }
          }
      
      
      To make use of this example script, simply implement your lookup code in the lookup_value() subroutine. Be very careful with such scripts, though:

      1. "Keep it simple, stupid" (KISS), because if this program hangs it will hang proftpd when the rule occurs. Well, keep it as simple as possible...

      2. Avoid one common mistake: avoid buffered I/O if possible. This can cause a deadloop. If necessary, be sure to flush the filehandle before reading, and after writing.

      3. Use the RewriteLock directive to define a lockfile mod_rewrite can use to synchronize the communication to the FIFO program. By default no such synchronization takes place.

    • Internal Function
      map-type: int, map-src: Internal mod_rewrite function.

      Here the map-src is a mod_rewrite built-in function. Currently you cannot create your own, but the following functions already exist:

      • replaceall:
        Replace all occurrences, in the looked up key, of one string with another string
      • toupper:
        Converts the looked up key to all upper case.
      • tolower:
        Converts the looked up key to all lower case.
      • unescape:
        Translates hex encodings (i.e. "URL encoding"; see RFC2396, Section 2.4.1), in the looked up key back to special characters.
      • utf8trans:
        Translates UTF-8 encodings in the lookup up key into Latin-1 characters.
    The RewriteMap directive can occur more than once. For each mapping-function use one RewriteMap directive to declare its rewriting map name.

    Note: For plain text files the looked-up keys are cached in-core until the mtime of the text map file changes or the server does a restart. This way you can have map-functions in rules which are used for every request. This is no problem, because the parsing of the text files only happens once!


    RewriteMaxReplace

    Syntax: RewriteMaxReplace count
    Default: 8
    Context: server config, <VirtualHost>, <Global>
    Module: mod_rewrite
    Compatibility: 1.3.5rc1 and later

    The RewriteMaxReplace directive is used to increase the number of replacements/substitutions that mod_rewrite will perform, when rewriting commands. By default, mod_rewrite will only replace up to 8 occurrences of a pattern in the input string; if there are more than 8 replacement occurrences, then the input string will be unchanged. If your input strings happen to have more than 8 occurrences to be replaced, you can use the RewriteMaxReplace to increase that limit.

    For example, to increase the limit to 32 occurrences to be replaced, use:

      RewriteMaxReplace 32
    


    RewriteRule

    Syntax: RewriteRule pattern substitution [flags]
    Default: None
    Context: server config, <VirtualHost>, <Global>, <Anonymous>, <Directory>
    Module: mod_rewrite
    Compatibility: 1.2.6rc1 and later

    The RewriteRule directive is the real rewriting workhorse. The configuration directive can occur more than once. Each directive defines a single rewriting rule. The order of definition of these rules is important, because this order is used when applying the rules at run-time.

    Pattern can be POSIX regular expression which gets applied to the current FTP command argument(s).

    Some hints about the syntax of regular expressions:

    • Text:
        .           Any single character
        [chars]     Character class: one of chars
        [^chars]    Character class: none of chars
        text1|text2 Alternative: text1 or text2
      
    • Quantifiers:
        ?           0 or 1 of the preceding text
        *           0 or N of the preceding text (N > 0)
        +           1 or N of the preceding text (N > 1)
      
    • Grouping:
       (text)       Grouping of text
                    (either to set the borders of an alternative or
                    for making backreferences where the Nth group can 
                    be used on the RHS of a RewriteRule with $N)
      
    • Anchors:
        ^           Start of line anchor
        $           End of line anchor
      
    • Escaping:
        \char       Escape that particular char
                    (for instance to specify the chars ".[]()" etc.)
      

    For more information about regular expressions have a look at your local regex(3) manpage. If you are interested in more detailed information about regular expressions and their variants (POSIX regex, Perl regex, etc.) have a look at the following dedicated book on this topic:

    Mastering Regular Expressions
    Jeffrey E.F. Friedl
    Nutshell Handbook Series
    O'Reilly & Associates, Inc. 1997
    ISBN 1-56592-257-3

    Additionally in mod_rewrite the NOT character ('!') is a possible pattern prefix. This gives you the ability to negate a pattern; to say, for instance: "if the current argument(s) does NOT match this pattern". This can be used for exceptional cases, where it is easier to match the negative pattern, or as a last default rule.

    Notice: When using the NOT character to negate a pattern you cannot have grouped wildcard parts in the pattern. This is impossible because when the pattern does NOT match, there are no contents for the groups. In consequence, if negated patterns are used, you cannot use $N in the substitution string.

    Substitution of a rewriting rule is the string which is substituted for (or replaces) the original argument(s) for which pattern matched. Beside plain text you can use:

    1. $N backreferences to the RewriteRule pattern
    2. %N backreferences to the last matched RewriteCondition pattern
    3. variables as in RewriteCondition test strings
    4. map function calls (${map-name:lookup-key|default-value})
    5. environment variable substitutions (%{ENV:variable-name})
    Backreferences are $N (N=0..9) identifiers which will be replaced by the contents of the Nth group of the matched pattern. The variables are the same as for the condition of a RewriteCondition directive, with two additions:
       %P   process ID
       %t   Unix time since the epoch, in seconds
    
    The map functions come from the RewriteMap directive and are explained there. These four types of variables are expanded in the order of the above list.

    All of the rewriting rules are applied to substitution. The command argument(s) is completely replaced by the substitution.

    Flags, if present, modify how this RewriteRule is evaluated. Supported flags are:

    • nocase|NC (no case)
      This makes the pattern case-insensitive, i.e. there is no difference between 'A-Z' and 'a-z' when pattern is matched against the command arguments


    Usage

    The mod_rewrite's regular expressions are POSIX extended regular expressions, not Perl regular expressions. This can catch the unsuspecting admin unawares, especially if they are used to Perl.

    When processing a RewriteRule, the mod_rewrite engine will first execute the RewriteRule's regular expression against the command parameters. If that expression fails, the RewriteRule is skipped. Any RewriteConditions that are attached to the rule are processed only if the rule's expression matches first.

    One of the consequences is that the rewritten path may run afoul of any configured AllowFilter, DenyFilter, PathAllowFilter, or PathDenyFilter directives, causing unexpected or unwanted transfers. Please keep this in mind when configuring RewriteRules.

    Some metas are not available at certain times (e.g. %U/%u for USER/PASS commands, etc)...

    Examples
    The following example configuration shows how to configure mod_rewrite so that all files uploaded to the server will have all-uppercase filenames:

      <IfModule mod_rewrite.c>
        RewriteEngine on
    
        # Have a log for double-checking any errors
        RewriteLog /var/log/ftpd/rewrite.log
    
        # Define a map that uses the internal "toupper" function
        RewriteMap uppercase int:toupper
    
        # Make the file names used by STOR be in all uppercase
        RewriteCondition %m STOR
    
        # Apply the map to the command parameters
        RewriteRule ^(.*) ${uppercase:$1}
    
      </IfModule>
    
    This example shows how to convert all spaces in uploaded file names to underscores:
      <IfModule mod_rewrite.c>
        RewriteEngine on
        RewriteLog /var/log/ftpd/rewrite.log
    
        # Define a map that uses the internal "replaceall" function
        RewriteMap replace int:replaceall
    
        # We only want to use this rule on STOR commands
        RewriteCondition %m STOR
    
        # Apply the map to the command parameters
        RewriteRule ^(.*) "${replace:/$1/ /_}"
    
      </IfModule>
    


    Installation

    To install mod_rewrite, follow the usual steps for using third-party modules in proftpd:
      ./configure --with-modules=mod_rewrite
      make
      make install
    



    Author: $Author: castaglia $
    Last Updated: $Date: 2012/03/27 06:32:56 $


    © Copyright 2000-2012 TJ Saunders
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_unique_id.html0000644000175000017500000000727610703454033022474 0ustar frankiefrankie ProFTPD module mod_unique_id

    ProFTPD module mod_unique_id



    The mod_unique_id module attempts to generate a unique ID for every FTP session. To make the ID unique across multiple servers, the following bits of information are used:

    • host IP address
    • client IP address
    • process ID
    • time of day (including microseconds)
    The generated ID is stored in the UNIQUE_ID environment variable in a printable form; other modules can retrieve the unique session ID from the environment. (Note that you will want mod_unique_id listed toward the end of your --with-modules configure list, so that the ID generation runs early in the session establishment process.) The contents of the UNIQUE_ID should be considered opaque, and are subject to change in the future.

    This module is contained in the mod_unique_id file for ProFTPD 1.3.x, and is not compiled by default. Installation instructions are discussed here.

    The most current version of mod_unique_id is distributed with the proftpd source code.

    Author

    Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.

    Directives


    UniqueIDEngine

    Syntax: UniqueIDEngine on|off
    Default: on
    Context: "server config"
    Module: mod_unique_id
    Compatibility: 1.3.1rc1 and later

    The UniqueIDEngine directive enables or disables the module's generation of a unique ID for each FTP session.

    By default, UniqueIDEngine is on.


    Installation

    To install mod_unique_id, copy the mod_unique_id.c file into:
      proftpd-dir/contrib/
    
    after unpacking the latest proftpd-1.3.x source code. For including mod_unique_id as a staticly linked module:
      ./configure --with-modules=mod_unique_id
    
    Alternatively, mod_unique_id could be built as a DSO module:
      ./configure --with-shared=mod_unique_id
    
    Then follow the usual steps:
      make
      make install
    


    Usage

    Since mod_unique_id generates a new unique ID for each session by default, there is no special configuration needed for enabling the module. Taking advantage of mod_unique_id, however, requires some adjustments in other parts of your proftpd.conf.

    Example configuration:

      <IfModule mod_unique_id.c>
    
        # Include the unique session ID in an ExtendedLog
        LogFormat session "%{UNIQUE_ID}e %h %l %u %t \"%r\" %s %b"
        ExtendedLog /path/to/extended.log ALL session
    
        # Store the unique ID in a SQL table named 'ftpsessions'
        SQLLog PASS login
        SQLNamedQuery login INSERT "'%{env:UNIQUE_ID}', '%u', now()" ftpsessions
    
      </IfModule>
    



    Author: $Author: castaglia $
    Last Updated: $Date: 2007/10/11 17:06:35 $


    © Copyright 2006-2007 TJ Saunders
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_qos.html0000644000175000017500000000524611344030021021274 0ustar frankiefrankie ProFTPD module mod_qos

    ProFTPD module mod_qos



    The mod_qos module can be used to set the Differentiated Services field (RFC2474) of IP packet headers. This can dramatically aid in the handling of these packets in the network, depending on the network QoS configuration.

    This module is contained in the mod_qos file for ProFTPD 1.3.x, and is not compiled by default. Installation instructions are discussed here.

    The most current version of mod_qos is distributed with the proftpd source code.

    Directives


    QoSOptions

    Syntax: QoSOptions "ctrlqos" value|"dataqos" value
    Default: None
    Context: "server config", <VirtualHost>
    Module: mod_qos
    Compatibility: 1.3.4rc1 and later

    The QoSOptions directive configures the QoS bits to use for the control and/or data connections.

    The possible values to use are:

    • cs0
    • cs1
    • cs2
    • cs3
    • cs4
    • cs5
    • cs6
    • cs7
    • af11
    • af12
    • af13
    • af21
    • af22
    • af23
    • af31
    • af32
    • af33
    • af41
    • af42
    • af43
    See RFC2474 for a better discussion of these values.

    Note that while the following values are also supported, their use is deprecated, and can have adverse effects on TCP congestion control:

    • lowcost
    • lowdelay
    • mincost
    • reliability
    • throughput


    Installation

    For including mod_qos as a staticly linked module in your proftpd, use:
      ./configure --with-modules=mod_qos
    
    Alternatively, mod_qos could be built as a DSO module:
      ./configure --enable-dso --with-shared=mod_qos
    
    Then follow the usual steps:
      make
      make install
    



    Author: $Author: castaglia $
    Last Updated: $Date: 2010/03/04 22:11:29 $


    © Copyright 2010 TJ Saunders
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_geoip.html0000644000175000017500000003520112072651560021607 0ustar frankiefrankie ProFTPD module mod_geoip

    ProFTPD module mod_geoip



    The mod_geoip module uses the GeoIP library from MaxMind to look up various geographic information for a connecting client:

      http://www.maxmind.com/app/c
    
    This information can be used to set access controls for the server.

    This module is contained in the mod_geoip.c file for ProFTPD 1.3.x, and is not compiled by default. Installation instructions are discussed here.

    The most current version of mod_geoip is distributed with the ProFTPD source code.

    This product includes GeoLite data created by MaxMind, available from http://www.maxmind.com/.

    Author

    Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.

    Directives


    GeoIPAllowFilter

    Syntax: GeoIPAllowFilter filter pattern
    Default: none
    Context: "server config", <VirtualHost>, <Global>
    Module: mod_geoip
    Compatibility: 1.3.3rc1 and later

    The GeoIPAllowFilter directive is used to configure ACLs based on the geographic data provided by the GeoIP library.

    Multiple GeoIPAllowFilter directives in the configuration are supported; if any filter matches the connecting client, the connection will be allowed.

    The filter parameter specifies the GeoIP value to which to apply the configured pattern for matching. The possible filter values are:

    • AreaCode
    • ASN
    • City
    • Continent
    • CountryCode
    • CountryCode3
    • CountryName
    • ISP
    • Latitude
    • Longitude
    • NetworkSpeed
    • Organization
    • PostalCode
    • Proxy
    • RegionCode
    • RegionName
    • Timezone

    The pattern parameter is case-insensitive regular expression that will be applied to the specified filter value, if available.

    Examples:

      # Allow clients with high-speed connections
      GeoIPAllowFilter NetworkSpeed corporate
    
      # Reject clients connecting from North America or South America
      GeoIPDenyFilter Continent (NA|SA)
    


    GeoIPDenyFilter

    Syntax: GeoIPDenyFilter filter pattern
    Default: none
    Context: "server config", <VirtualHost>, <Global>
    Module: mod_geoip
    Compatibility: 1.3.3rc1 and later

    The GeoIPDenyFilter directive is used to configure ACLs based on the geographic data provided by the GeoIP library.

    Multiple GeoIPDenyFilter directives in the configuration are supported; if any filter matches the connecting client, the connection will be rejected.

    See GeoIPAllowFilter for a description of the directive syntax and parameters.


    GeoIPEngine

    Syntax: GeoIPEngine on|off
    Default: off
    Context: "server config", <VirtualHost>, <Global>
    Module: mod_geoip
    Compatibility: 1.3.3rc1 and later

    The GeoIPEngine directive enables or disables the module's lookup of geographic information for a connecting client, and subsequent enforcement of any configured ACLs.


    GeoIPLog

    Syntax: GeoIPLog file|"none"
    Default: None
    Context: "server config", <VirtualHost>, <Global>
    Module: mod_geoip
    Compatibility: 1.3.3rc1 and later

    The GeoIPLog directive is used to specify a log file for mod_geoip's reporting on a per-server basis. The file parameter given must be the full path to the file to use for logging.

    Note that this path must not be to a world-writable directory and, unless AllowLogSymlinks is explicitly set to on (generally a bad idea), the path must not be a symbolic link.


    GeoIPPolicy

    Syntax: GeoIPPolicy "allow,deny"|"deny,allow"
    Default: GeoIPPolicy allow,deny
    Context: server config, <VirtualHost>, <Global>
    Module: mod_geoip
    Compatibility: 1.3.5rc1 and later

    The GeoIPPolicy directive determines whether the mod_geoip module will allow a connection by default or not.

    If GeoIPPolicy is configured using "allow,deny" (which is the default setting), then the mod_geoip module will allow the connection, unless the connecting client is rejected by any GeoIPDenyFilter rules.

    If GeoIPPolicy is configured using "deny,allow", then the mod_geoip module will reject any connection, unless the connecting client matches any configured GeoIPAllowFilter rules.


    GeoIPTable

    Syntax: GeoIPTable path [flags]
    Default: None
    Context: "server config", <VirtualHost>, <Global>
    Module: mod_geoip
    Compatibility: 1.3.3rc1 and later

    The GeoIPTable directive is used to a GeoIP database file for use by the GeoIP library. The path parameter given must be the full path to the database file.

    If no GeoIPTable directive is configured, then the GeoIP library will use the default GeoIP Country database file installed with the library. Otherwise, only the database files configured via GeoIPTable directives will be used.

    Multiple GeoIPTable directives can be used to configure multiple different GeoIP database files for use at the same time.

    The possible flags values supported are:

    • Standard

      Reads the database from the filesystem; uses the least memory but causes database to be read for each connection.

    • MemoryCache

      Loads the database into memory; faster performance but uses the most memory. Tables configured with MemoryCache are loaded into the parent process memory, avoiding the need to read them for each connection.

    • CheckCache

      Causes the GeoIP library to check for database updates. If the database has been updated, the library will automatically reload the file and/or memory cache.

    • IndexCache

      Loads just the most frequently accessed index portion of the database into memory, resulting in faster lookups than Standard but less memory usage than MemoryCache. This can be useful for larger databases such as GeoIP Organization and GeoIP City.

    • MMapCache

      Loads the database into mmap shared memory.

    • UTF8

      Tells the GeoIP library to return UTF8 strings for the data obtained from this database file. By default, the GeoIP library uses ISO-8859-1 encoded strings.

    Multiple different flags can be configured.

    Examples:

      GeoIPTable /path/to/GeoIP.dat MemoryCache CheckCache
      GeoIPTable /path/to/GeoISP.dat Standard
      GeoIPTable /path/to/GeoIPCity.dat IndexCache
    


    Installation

    The mod_geoip module requires that the GeoIP library be installed.

    After installing GeoIP, follow the usual steps for using contrib modules in proftpd: To install mod_geoip, copy the mod_geoip.c file into:

      cp mod_geoip.c proftpd-dir/contrib/
    
    after unpacking the latest proftpd-1.3.x source code. For including mod_geoip as a staticly linked module:
      ./configure --with-modules=mod_geoip
    
    Alternatively, mod_geoip could be built as a DSO module:
      ./configure --with-shared=mod_geoip
    
    Then follow the usual steps:
      make
      make install
    
    You may need to specify the location of the GeoIP header and library files in your configure command, e.g.:
      ./configure --with-modules=mod_geoip \
        --with-includes=/usr/local/geoip/include \
        --with-libraries=/usr/local/geoip/lib
    

    Alternatively, if your proftpd was compiled with DSO support, you can use the prxs tool to build mod_geoip as a shared module:

      prxs -c -i -d mod_geoip.c
    


    Usage

    Access Controls
    If any GeoIPAllowFilter or GeoIPDenyFilter directives are configured, the mod_geoip module applies them against the geographic information retrieved from the GeoIP library. First any GeoIPAllowFilters are checked. If any of these filters matches the connecting client's information, the connection is allowed. Next, any GeoIPDenyFilters are checked. If any of these filters matches the connecting client's information, the connection is closed. Otherwise, the connection is allowed.

    This means that if you wanted to reject connections from the US except for connections from California, you might use something like this:

      # Deny all connections from the US
      GeoIPDenyFilter CountryCode US
    
      # But allow connections from California
      GeoIPAllowFilter RegionCode CA
    

    Environment Variables
    The mod_geoip module will set the following environment variables whenever a client connects, assuming that the appropriate GeoIP tables have been configured and the values are known for the connecting client:

    • GEOIP_AREA_CODE
    • GEOIP_ASN
    • GEOIP_CITY
    • GEOIP_CONTINENT_CODE
    • GEOIP_COUNTRY_CODE (two-letter country code)
    • GEOIP_COUNTRY_CODE3 (three-letter country code)
    • GEOIP_COUNTRY_NAME
    • GEOIP_ISP
    • GEOIP_LATITUDE
    • GEOIP_LONGITUDE
    • GEOIP_NETSPEED
    • GEOIP_ORGANIZATION
    • GEOIP_POSTAL_CODE
    • GEOIP_PROXY
    • GEOIP_REGION
    • GEOIP_REGION_NAME
    • GEOIP_TIMEZONE
    These values are also available in the session.notes table, under keys of the names above.

    Example Configuration

      <IfModule mod_geoip.c>
        GeoIPEngine on
        GeoIPLog /path/to/ftpd/geoip.log
    
        # Load GeoLite city database into memory on server startup, and use
        # UTF8-encoded city names
        GeoIPTable /path/to/GeoLiteCity.dat MemoryCache UTF8
    
        # Add your GeoIPAllowFilter/GeoIPDenyFilter rules here
      </IfModule>
    

    Logging
    The mod_geoip module supports different forms of logging. The main module logging is done via the GeoIPLog directive. For debugging purposes, the module also uses trace logging, via the module-specific "geoip" log channel. Thus for trace logging, to aid in debugging, you would use the following in your proftpd.conf:

      TraceLog /path/to/ftpd/trace.log
      Trace geoip:20
    
    The geographic information retrieved from the GeoIP library for the connecting client is logged using this "geoip" trace log channel. This trace logging can generate large files; it is intended for debugging use only, and should be removed from any production configuration.

    Suggested Future Features
    The following lists the features I hope to add to mod_geoip, according to need, demand, inclination, and time:

    • Configure a message to be sent to rejected clients
    • Support requiring all GeoIPAllowFilter/GeoIPDenyFilter to apply, in addition to any

    Frequently Asked Questions

    Question: How I can whitelist specific clients from mod_geoip's checking?
    Answer: You should be able to easily do this using
    classes and the mod_ifsession module. For example:

      <Class geop-whitelist>
        From 1.2.3.4
      </Class>
    
      <IfModule mod_geoip.c>
        # Add the normal mod_geoip directives here except GeoIPEngine
      </IfModule>
    
      <IfClass geoip-whitelist>
        # Disable mod_geoip for the whitelisted clients
        GeoIPEngine off
      </IfClass>
    
      <IfClass !geoip-whitelist>
        # Enable mod_geoip for all non-whitelisted clients
        GeoIPEngine on
      </IfClass>
    



    Author: $Author: castaglia $
    Last Updated: $Date: 2013/01/07 23:00:00 $


    © Copyright 2010-2013 TJ Saunders
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_ctrls_admin.html0000644000175000017500000003224111723257713023010 0ustar frankiefrankie ProFTPD module mod_ctrls_admin

    ProFTPD module mod_ctrls_admin



    This module is contained in the mod_ctrls_admin.c file for ProFTPD /1.3.x, and is not compiled by default. Installation instructions are discussed here.

    This module implements administrative control actions for the ftpdctl program.

    The most current version of mod_ctrls_admin is distributed with the ProFTPD source.

    Author

    Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.

    Directives

    Control Actions


    Directives


    AdminControlsACLs

    Syntax: AdminControlsACLs actions|all allow|deny user|group list
    Default: None
    Context: server config
    Module: mod_ctrls_admin
    Compatibility: 1.2.10rc1 and later

    The AdminControlsACLs directive configures access lists of users or groups who are allowed (or denied) the ability to use the actions implemented by mod_ctrls_admin. The default behavior is to deny everyone unless an ACL allowing access has been explicitly configured.

    If "allow" is used, then list, a comma-delimited list of users or groups, can use the given actions; all others are denied. If "deny" is used, then the list of users or groups cannot use actions all others are allowed. Multiple AdminControlsACLs directives may be used to configure ACLs for different control actions, and for both users and groups.


    AdminControlsEngine

    Syntax: AdminControlsEngine on|off|actions
    Default: None
    Context: server config
    Module: mod_ctrls_admin
    Compatibility: 1.2.10rc1 and later

    The AdminControlsEnginedirective enables or disables the mod_ctrls_admin module, and thus the handling of its implemented control actions.

    If only certain of the module's control actions are wanted, provide a list of those actions, rather than the normal "on" or "off". Any of mod_ctrls_admin's control actions that do not appear in actions will be unregistered; by default, all of the module's control actions are registered.


    Control Actions


    debug

    Syntax: ftpdctl debug [level [number]]|memory|config
    Purpose: Obtain debug information from the running daemon

    Obtaining debug output from the server greatly helps in diagnosing problems. The trick is in getting this debug output from the server. The debug control action can be used to gather such information.

    First, this control action can increase or query the debug logging verbosity of the daemon on-the-fly, to obtain the needed output, and then to return the daemon to a more silent state of logging.

    Example:

      ftpdctl debug level 9
    
    raises the verbosity of the daemon to its maximum level. Once enough output has been collected, use:
      ftpdctl debug level 0
    
    to return the daemon to its default debug output level.

    Instead, to simply check the current debug logging verbosity, use:

      ftpdctl debug level
    

    Alternatively, for developers (i.e. if proftpd was compiled with the --enable-devel configure option), this control action can be used to display the current memory allocation of the daemon:

      ftpdctl debug memory
    
    Memory allocations for session processes are currently not available via this control action.


    dns

    Syntax: ftpdctl dns on|off
    Purpose: DNS configuration

    The dns control action can be used to enable or disable the UseReverseDNS configuration at run time:

      # Enable resolution of IP addresses to DNS names
      ftpdctl dns on
    
      # Disable resolution of IP addresses to DNS names
      ftpdctl dns off
    

    Note that the dns control action also supports a command for clearing any cached DNS lookup information:

      ftpdctl dns clear cache
    


    down

    Syntax: ftpdctl down ip-address|dns-name[#port]|"all"
    Purpose: Turn down a virtual server

    The down control action can be used to "turn down" an individual virtual server, so that clients cannot connect to it. Once a virtual server has been "downed", the "up" control action can be used to bring that virtual server back up.

    If a port number is not specified, it defaults to 21.

    Note that using "down all" effectively puts the daemon in an "administrative" shutdown state, where the daemon is still running but no servers are available for servicing incoming connection requests. Current sessions are not affected.


    get

    Syntax: ftpdctl get "config"|"directives"
    Purpose: Obtain configuration information

    The get control action can be used obtain various sorts of configuration information from the daemon. At present, this control action only supports the "config" and "directives" parameters.

    The "config" parameter causes ftpdctl to display a configuration dump, similar to what is displayed by a syntax check (i.e. using the -t proftpd command-line option).

    The "directives" parameter causes ftpdctl to display a sorted list of all supported configuration directives, as well as the module which handles the corresponding directive.


    kick

    Syntax: ftpdctl kick [class name]|[host dns-name|ip-address][user name]
    Purpose: Kick a currently connected class, host or user from the daemon

    The kick control action can be used to disconnect a currently connected class, host or user from the daemon.

    Examples:

      ftpdctl kick user bob dave 
    
    will kick all sessions that have logged in as user "bob" or user "dave".
      ftpdctl kick host luser.host.net
    
    will kick all sessions that have connected from host "luser.host.net".
      ftpdctl kick class eval intranet
    
    will kick all sessions that belong to classes "eval" and "intranet".

    You can also use the -n <count> command-line option to specify the maximum number of clients to be kicked. For example, perhaps you only want to kick off 10 clients from host "luser.host.net" rather than kicking all of them off. To do this, use:

      ftpdctl kick host -n 10 luser.host.net
    


    restart

    Syntax: ftpdctl restart
    Purpose: Restart the daemon

    The restart control action causes the daemon to re-read its configuration file, just as if a SIGHUP had been used. This is convenient for administrators, as it does not (necessarily) require root privileges, nor knowledge of the daemon's PID, to restart the daemon.

    Example:

      # ftpdctl restart
    
    In addition, you can use the restart control to ask the daemon how many times it has been restarted:
      # ftpdctl restart count
      ftpdctl: restarted 4 times since 2010-01-06 23:20:09 GMT
    


    scoreboard

    Syntax: ftpdctl scoreboard scrub
    Purpose: Scrubs the ScoreboardFile for dead processes

    The scoreboard control action can be used to force the ScoreboardFile to be "scrubbed" for dead session processes which may not have exited cleanly.

      ftpdctl scoreboard scrub
    
      # The verb "clean" is synonymous with "scrub"
      ftpdctl scoreboard clean
    


    shutdown

    Syntax: ftpdctl shutdown ["graceful" seconds]
    Purpose: Stop the daemon

    The shutdown control action shuts the daemon down. This is convenient for administrators, as it does not (necessarily) require root privileges, nor knowledge of the daemon's PID, to stop the daemon.

    The optional "graceful" parameter allows for a graceful shutdown, in which proftpd will wait for the given number of seconds for all current sessions to end, before shutting down.

    Example:

      ftpdctl shutdown graceful 30
    
    will cause proftpd to wait for 30 seconds for all current sessions to end before shutting down completely.


    status

    Syntax: ftpdctl status ip-address|dns-name[#port]|"all"
    Purpose: Display the status of virtual servers

    The status control action can be used to show the status of a particular virtual server, whether it is up or down.

    If a port number is not specified, it defaults to 21.

    If "status all" is used, the status of all virtual servers will be displayed.


    trace

    Syntax: ftpdctl trace channel:level|"info"
    Purpose: Configure trace channel log levels

    The trace control action can be used to dynamically change the log levels of trace log levels.

    Example:

      ftpdctl trace delay:10
    
    will set the log verbosity level of the delay trace log channel to 10.

    Additionally, the trace control action can be used to display the list of current trace channels and their log levels, e.g.:

      # ftpdctl trace info
      ftpdctl: Channel    Level 
      ftpdctl: ---------- ------
      ftpdctl:        pam 10    
      ftpdctl:     netacl 10    
      ftpdctl:   response 10    
      ftpdctl:       auth 10    
      ftpdctl:       utf8 10    
      ftpdctl:       inet 10    
      ftpdctl:    binding 10    
      ftpdctl:        dns 10    
      ftpdctl:        dso 10    
      ftpdctl:     parser 10    
      ftpdctl:       pool 10    
      ftpdctl:      ctrls 10    
      ftpdctl:       data 10    
      ftpdctl:      netio 10    
      ftpdctl:     config 10    
      ftpdctl:      ident 10    
      ftpdctl:    command 10    
      ftpdctl:      delay 10    
      ftpdctl:      timer 10    
      ftpdctl:        var 10    
      ftpdctl:      event 10    
      ftpdctl:       fsio 10    
      ftpdctl:       site 10    
    


    up

    Syntax: ftpdctl up ip-address|dns-name[#port]
    Purpose: Turn up a "downed" virtual server

    The up control action can be used to "turn up" any virtual server that has been "downed" by the "down" control action. Note that using the "restart" control action is sufficient to enable, with one command, all virtual servers that have been downed.

    If a port number is not specified, it defaults to 21.


    Installation

    This module requires that controls support be enabled in proftpd via the --enable-ctrls configure option. Follow the normal steps for using third-party modules in ProFTPD:
      ./configure --enable-ctrls --with-modules=mod_ctrls_admin
      make
      make install
    


    Last Updated: $Date: 2012/02/28 23:14:19 $


    © Copyright 2004-2012 The ProFTPD Project
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/contrib/mod_quotatab.html0000644000175000017500000006147112071102500022314 0ustar frankiefrankie ProFTPD module mod_quotatab

    ProFTPD module mod_quotatab



    This module is contained in the mod_quotatab.c, mod_quotatab.h, and in its submodule source files, for ProFTPD 1.2.x/1.3.x, and is not compiled by default. Installation instructions can be found here.

    This module is designed to impose quotas, both byte- and file-based, on FTP accounts, based on user, group, class, or for all accounts. It is based on the ideas contained in Eric Estabrook's mod_quota; however, this module has been written from scratch to implement quotas in a very different manner. A more detailed explanation of the usage of this module follows the directive explanations.

    The most current version of mod_quotatab's submodules supports storage of quota table information in various formats:

    The most current version of mod_quotatab is distributed with the ProFTPD source code.

    Author

    Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.

    Thanks

    2002-01-12: Thanks to SupaFly <ntlfy at ntlworld.com> for helping debug an issue with a missing tally table.

    2002-03-30: Thanks to Kai Langheim <kl at q-nic.de> for pointing out several small bugs affecting users with no quota entries.

    2003-01-24: Thanks to Arne Blankerts <Blankerts at tow.de> for noting small bug with the file upload counter being incorrectly incremented for overwritten files.

    Directives

    SITE Commands


    QuotaDefault

    Syntax: QuotaDefault quota-type per-session limit-type bytes-avail-in bytes-avail-out bytes-avail-xfer files-avail-in files-avail-out files-avail-xfer
    Default: None
    Context: server config, <VirtualHost>, <Global>
    Module: mod_quotatab
    Compatibility: 1.3.5rc1 and later

    The QuotaDefault directive configures a "default" quota limit, to be used when a limit is not found for the current user (e.g. a limit has not yet been configured for the user via one of the mod_quotatab backends). Since this "default" needs to provide all of the limit information required by mod_quotatab, there are quite a few required parameters:

    • quota-type
    • per-session
    • limit-type
    • bytes-avail-in
    • bytes-avail-out
    • bytes-avail-xfer
    • files-avail-in
    • files-avail-out
    • files-avail-xfer
    The meaning of these parameters is discussed in more detail here.

    For example, you might use:

      QuotaDefault user false hard 10485760 0 0 0 0 0
    


    QuotaDirectoryTally

    Syntax: QuotaDirectoryTally on|off
    Default: QuotaDirectoryTally off
    Context: server config, <VirtualHost>, <Global>
    Module: mod_quotatab
    Compatibility: 1.2.5rc2 and later

    The QuotaDirectoryTally directive configures mod_quotatab to take directory operations (e.g. creating a directory, removing a directory) into account when tallying.


    QuotaDisplayUnits

    Syntax: QuotaDisplayUnits "b"|"Kb"|"Mb"|"Gb"
    Default: None
    Context: server config, <VirtualHost>, <Global>
    Module: mod_quotatab
    Compatibility: 1.2.5rc2 and later

    This directive configures how the user's current byte quota values will be reported to them. Note that this directive does not affect how the quota values are stored in the quota table, only their presentation to the user.

    "b" causes quotas to be displayed in bytes; "Kb", kilobytes; "Mb", megabytes; and "Gb", gigabytes.

    Example:

      # display quota information in megabytes
      QuotaDisplayUnits Mb
    


    QuotaEngine

    Syntax: QuotaEngine on|off
    Default: None
    Context: server config, <VirtualHost>, <Global>
    Module: mod_quotatab
    Compatibility: 1.2.5rc2 and later

    The QuotaEngine directive enables or disables the module's runtime quota engine. If it is set to off this module does no runtime processing at all. Use this directive to disable the module instead of commenting out all mod_quotatab directives.


    QuotaExcludeFilter

    Syntax: QuotaExcludeFilter regex|"none"
    Default: None
    Context: server config, <VirtualHost>, <Global>
    Module: mod_quotatab
    Compatibility: 1.3.1rc1 and later

    The QuotaExcludeFilter directive configures a regular expression filter that is applied to every file handled by mod_quotatab; this includes files that are scanned if:

      QuotaOptions ScanOnLogin
    
    is in effect. Any file which matches the configured regular expression is ignored by mod_quotatab, and will not affect the tally updates.

    Note that the regular expression is applied to the absolute path of the file being handled. This allows for a regular expression which can exclude particular directories, or just certain filenames.


    QuotaLimitTable

    Syntax: QuotaLimitTable source-type:source-info
    Default: None
    Context: server config, <VirtualHost>, <Global>
    Module: mod_quotatab
    Compatibility: 1.2.5rc2 and later

    This directive configures the information necessary for the module to locate and use the table containing the quota limit, the maximum number of bytes and/or files defined for use by specific users, groups, classes, etc, and is required for mod_quotatab to function. Note that "groups" here refers to the groups of which the user is a member, the same groups as used for filesystem permissions; "classes" refers to connection classes.

    Please consult the relevant submodule documentation for details on that module's syntax for this configuration directive.

    See also: QuotaTallyTable


    QuotaLock

    Syntax: QuotaLock file
    Default: None
    Context: server config, <VirtualHost>, <Global>
    Module: mod_quotatab
    Compatibility: 1.2.9rc1 and later

    The QuotaLock directive sets the filename for a synchronization lockfile which mod_quotatab needs when communicating with some submodules, such as for SQL-based tables, which have trouble providing the needed synchronization/locking semantics. Use of QuotaLock is recommended, but not required.

    If QuotaLock is used, it is strongly advised that the configured lock file not be on an NFS (or any other network) filesystem.


    QuotaLog

    Syntax: QuotaLog file|"none"
    Default: None
    Context: server config, <VirtualHost>, <Global>
    Module: mod_quotatab
    Compatibility: 1.2.5rc2 and later

    The QuotaLog directive is used to a specify a log file for mod_quotatab reporting, and can be done a per-server basis. The file parameter must be the full path to the file to use for logging. Note that this path must not be to a world-writeable directory and, unless AllowLogSymlinks is explicitly set to on (generally a bad idea), the path must not be a symbolic link.

    If file is "none", no logging will be done at all; this setting can be used to override a QuotaLog setting inherited from a <Global> context.


    QuotaOptions

    Syntax: QuotaOptions opt1 ...
    Default: None
    Context: server config, <VirtualHost>, <Global>
    Module: mod_quotatab
    Compatibility: 1.3.1rc1 and later

    The QuotaOptions directive is used to configure various optional behavior of mod_quotatab.

    Example:

      QuotaOptions ScanOnLogin
    

    The currently implemented options are:

    • ScanOnLogin

      If configured, this causes mod_quotatab to recursively scan the user's home directory when the user logs in, and to update the tally entry for that user, if any, with the number of bytes and files found. Note that these scans will cause a longer login time for the user, depending on the size of their home directory.

      Note that this scanning will only happen if the configured limits for the user have either a bytes-in value greater than zero or a files-in value greater than zero. (These are the only two limits related to upload, hence why ScanOnLogin only goes into effect based on them.)


    QuotaShowQuotas

    Syntax: QuotaShowQuotas on|off
    Default: on
    Context: server config, <VirtualHost>, <Global>
    Module: mod_quotatab
    Compatibility: 1.2.5rc2 and later

    The QuotaShowQuotas directive can be used to enable/disable mod_quotatab's response to a SITE QUOTA request. For some sites, revealing the current quota information may be considered an unnecessary, perhaps even detrimental, information leak; other sites may consider this a definite feature.


    QuotaTallyTable

    Syntax: QuotaTallyTable source-type:source-info
    Default: None
    Context: server config, <VirtualHost>, <Global>
    Module: mod_quotatab
    Compatibility: 1.2.5rc2 and later

    This directive configures the information necessary for the module to locate and use the table containing the quota tally, or the current byte/file counts for users, groups, classes, etc, and is required for mod_quotatab to function. Note that "groups" here refers to the groups of which the user is a member, the same groups as used for filesystem permissions; "classes" refers to connection classes.

    Please consult the relevant submodule documentation for details on that module's syntax for this configuration directive.

    See also: QuotaLimitTable



    SITE QUOTA

    The SITE QUOTA command will display the quota, both the limit and the current tally, to the client. This SITE command accepts no parameters, and can only be used once the client has successfully logged in.

    Example:

    ftp> quote SITE QUOTA
    200-The current quota for this session are [current/limit]:
     Name: tj
     Quota Type: User
     Per Session: True
     Limit Type: Hard
       Uploaded Kb:         unlimited
       Downloaded Kb:       unlimited
       Transferred Kb:      unlimited
       Uploaded files:      1/1
       Downloaded files:    unlimited
       Transferred files:   unlimited
    200 Please contact root@familiar.castaglia.org if these entries are inaccurate
    ftp> 
    
    Use of this SITE command can be controlled via <Limit>, e.g.:
      <Limit SITE_QUOTA>
        AllowUser tj
        DenyAll
      </Limit>
    

    Like many SITE commands, the FTP client will probably not recognize or support SITE QUOTA. Hopefully the client does have the ability to send arbitrary commands to the server, as the common ftp(1) client does via quote.

    The email address displayed in the SITE QUOTA output can be configured via the ServerAdmin directive.



    Usage

    To use mod_quotatab's functionality, you must first define the tables that together contain the quota information.

    There are two such quota tables: one table, called the limit table for providing quota information about the absolute byte/file limits for users, groups, and classes, and a separate table, called the tally table for maintaining the current tally, or number of bytes/files used, for those same users, groups, and classes. (Note that "groups" here refers to the groups of which the user is a member, the same groups as used for filesystem permissions; "classes" refers to connection classes.) This separation of information allows for a configuration such as using LDAP to efficiently distribute the limit information, and local SQL databases for efficiently storing the tally. The limit table is considered a read-only table, and is only accessed at the start of session in order to determine what the session limits should be. The tally table is accessed in read-write mode, and is updated after the relevant FTP commands have been processed.

    This module was not explicitly designed for easy interaction with other applications, but rather for other criteria:

    • Efficient lookups and updates
    • No need for ~/.quota files
    • No need of requirement for root privileges to access quotas
    • Easy support for an abstraction layer for storing quota information in other formats
    • Support for a SITE command that allows users to view their current quotas

    This module maintains its quotas based solely on FTP commands - it does not enforce quotas based on files that may have been added, deleted, or moved via shell access or any mechanism other than through the proftpd server.

    When a client logs in, assuming QuotaEngine is on, mod_quotatab will check the limit table for the record most appropriate for that client. This check first examines the table for records of type user that match the client's login name.

    If no such matching records are found, it checks for records of type group that match any of the user's groups (both primary and supplemental). If there are multiple group-type limits available and applicable to the user's groups, which one is used? The mod_quotatab module first checks for a quota limit for the user's primary group. If there is a group limit for the user's primary group, that limit is used. Otherwise, the supplemental groups for the user are checked, in the order returned by the authenticating module (e.g. mod_auth_unix, mod_sql, mod_ldap, etc).

    If no such matching group quotas are found, the mod_quotatab will check for records of type class that belong to the class (if enabled) from which the client is connecting. The order of classes matched is the order in which the classes are defined in the proftpd.conf file.

    If still no matching records are found, the table will be searched for a record of type all; if absent, the module will assume that no quotas apply to the client.

    Note that there is only one type of limit in effect at a given time; mod_quotatab does not combine multiple user/group/class/all limits for the same client. The module was designed such that only one limit (and its corresponding tally) would be enforced/used for a given session. In the case of multiple applicable group or class type quotas, only the matching quota limit and tally will be used and updated. Currently, there is no support for multiple simultaneous (or "layered") limits/tallies.

    Once the limits for the current session have been established, mod_quotatab examines the tally table to see what the current numbers in the matching tally record are. Should the client have an applicable limit record but no matching tally record, the module will initialize a new record in the tally table. If the limit record specifies that quotas are per-session, mod_quotatab will ignore any existing tally records, and will not update the tallies.

    For the purposes of tracking the number of uploaded bytes/files, the tally will be adjusted accordingly upon use of the following FTP commands: APPE (bytes only), DELE, STOR, and STOU. The number of bytes used for the calculation will be determined from the difference in file size of the file in question.

    For the purposes of tracking the number of downloaded bytes/files, the tally will be adjusted accordingly upon use of the following FTP commands: RETR. The number of bytes used for the calculation will be determined from the number of bytes sent to the client.

    For the purposes of tracking the number of transferred bytes/files, the tally will be adjusted accordingly upon use of the following FTP commands: APPE (bytes only), DELE, RETR, STOR, and STOU. The number of bytes used for the calculation will be determined from the number of bytes sent to the client. This type of limit allows for byte/file limits to be set that encompass both uploads and downloads.

    Note that if all three types of quotas are set (upload, download, and transfer), any quota reached will cause denial of FTP commands. This means that a high upload quota will never be reached if a low transfer quota is in effect. This holds true for bytes and files quota. For example, if a user has a limited number of both bytes and files to be uploaded in their limit record, the first limit reached (bytes or files) is the effective limit. Caveat emptor.

    For any quota limit that is set as "unlimited", mod_quotatab will not keep the tally. Many site administrators might want this ability, for accounting purposes. However, that ability is outside of the intended design of this module; other logging modules are much better suited for accounting purposes (e.g. mod_sql's SQLLog directive).

    A "hard" limit type means that a user's tally will never be allowed to exceed the limit; any file uploaded that exceeds the user's quota limit will be deleted, and the tally will not be incremented. A "soft" limit type, on the other hand, is a little less strict, for it will allow a user to exceed the quota limit by one file only. For example, assume a user's tally is close their limit. That user uploads a large file, one that pushes the tally up over the quota limit. If their limit type is "hard", the large file will be deleted once uploaded, and a message returned to the client informing them of this. If the user's limit type is "soft", the large file will be allowed, but any other uploads are denied (until the user deletes some files, and brings their tally back down below the quota limit).

    If any developers wish to make use of mod_quotatab's quota information, or to develop a new submodule, there is developer documentation available here.

    Display Variables
    The following variables are provided by mod_quotatab, and can be used in any Display file (e.g. DisplayLogin) other than DisplayConnect. The values for the variables are not known when the client connects to the daemon, hence why the variables are not useful in a DisplayConnect file.

      %{mod_quotatab.limit.bytes_in}
      %{mod_quotatab.limit.bytes_out}
      %{mod_quotatab.limit.bytes_xfer}
      %{mod_quotatab.limit.files_in}
      %{mod_quotatab.limit.files_out}
      %{mod_quotatab.limit.files_xfer}
      %{mod_quotatab.tally.bytes_in}
      %{mod_quotatab.tally.bytes_out}
      %{mod_quotatab.tally.bytes_xfer}
      %{mod_quotatab.tally.files_in}
      %{mod_quotatab.tally.files_out}
      %{mod_quotatab.tally.files_xfer}
    
    Note that the values for the various byte variables honor any QuotaDisplayUnits setting.


    Installation

    Follow the usual steps for using third-party modules in proftpd:
      ./configure --with-modules=quotatab-modules
      make
      make install
    
    where quotatab-modules will depend on the types of quota tables you wish to support.

    For file-based quota tables, include the mod_quotatab_file submodule, e.g.:

      mod_quotatab:mod_quotatab_file
    

    For LDAP-based quota limit tables, include mod_quotatab_ldap in addition to either mod_quotatab_file or mod_quotatab_sql:

      mod_quotatab:mod_quotatab_file:mod_quotatab_ldap
    
    Note that file- or SQL-based tally tables are needed since mod_quotatab_ldap cannot handle tally tables, only limit tables. mod_quotatab_ldap also requires a correct installation of the mod_ldap module.

    For SQL-based quota tables, include the mod_quotatab_sql submodule, e.g.:

      mod_quotatab:mod_quotatab_sql
    
    And, if you wish to support file- and SQL-based quota tables:
      mod_quotatab:mod_quotatab_file:mod_quotatab_sql
    
    Note that SQL tables require that a correct installation of mod_sql (and any of its backend modules) also be used. Consult the mod_sql documentation for installation instructions for that module.



    Author: $Author: castaglia $
    Last Updated: $Date: 2013/01/02 19:06:40 $


    © Copyright 2000-2013 TJ Saunders
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/howto/0000755000175000017500000000000012156653653016466 5ustar frankiefrankieproftpd-dfsg-1.3.5~rc3/doc/howto/Scoreboard.html0000644000175000017500000002227712071660272021440 0ustar frankiefrankie ProFTPD mini-HOWTO - The ScoreboardFile

    ProFTPD and the ScoreboardFile


    What is the Scoreboard?
    The ScoreboardFile is used by proftpd for tracking information for each current FTP session. It is necessary for things like MaxClients, MaxClientsPerUser, etc. The utility programs (ftpwho, ftpcount, ftptop) read the scoreboard and display its information.

    Here's how proftpd handles its scoreboard: There is a default path that proftpd will use for writing its scoreboard (var/proftpd/proftpd.scoreboard). This default path depends on how you install proftpd (i.e. if you install from source and use the --prefix configure option, the default path will be adjusted to honor your --prefix). However, you can also explicitly tell the daemon what location to use for its scoreboard using the ScoreboardFile configuration directive in your proftpd.conf. When the daemon starts up, it looks to see if there is a scoreboard already there; if there isn't, it makes a new one.

    The most common error encountered when opening the scoreboard is:

      unable to open scoreboard: No such file or directory
    
    This usually means that proftpd is trying to open a ScoreboardFile in a directory that does not exist. Some packages fail to create the needed directory; this will result in the error message above. If you cannot find your ScoreboardFile, you should try explicitly configuring the path to the file to use in your proftpd.conf, using the ScoreboardFile configuration directive, and then obtaining debugging output from your proftpd, to see if the daemon ran into problems using that defined location.

    In proftpd-1.3.4rc1, a new ScoreboardMutex directive was added. This file is used as a mutex for starting/ending sessions, for improving performance under load; see Bug#3208 for the technical details. The default path (usually var/proftpd/proftpd.scoreboard.lck) for ScoreboardMutex should suffice. If you need to explicitly configure a different ScoreboardMutex file, make absolutely sure that you do not place the file on a networked filesystem. Your performance will suffer greatly if you do.

    What's in the Scoreboard?
    What types of information about each session is tracked in the scoreboard? What else is recorded in the scoreboard?

    The ScoreboardFile records the following information about the parent/daemon proftpd process:

    • scoreboard file format identifier
    • daemon PID
    • daemon uptime
    • daemon version
    and for each session, the ScoreboardFile records:
    • session PID
    • session protocol (e.g. "ftp", "ftps", "sftp")
    • session UID
    • session GID
    • session user name
    • session server IP address/port
    • session virtual host name
    • session client IP address, DNS name
    • session class
    • time since session started
    and some other data related to data transfers. The data transfer-related fields include the filename being transferred (may be relative or absolute, depending on what the client sent), the transfer command (e.g. RETR for downloads, STOR for uploads, etc), the amount of data transferred so far, and percentage of transfer completed (for downloads only).

    Scrubbing the Scoreboard
    There is a bad habit among system administrators of using `kill -9' to kill a misbehaving process. Any process that is terminated this way, though, does not have a chance of properly shutting down. Administrators would use `kill -9' on some of proftpd's session processes, which means that they would not be able to remove their entries from the ScoreboardFile. Utilities like ftpwho and ftptop would show sessions that no longer existed.

    The chance of changing this bad habit in system administrators is slim, so proftpd was changed to check the ScoreboardFile periodically. It will scan the entire file, and for each scoreboard session listed, it asks the operating system if that session process is still alive. If the answer is no, the entry is removed from the file. This process is known as "scrubbing".

    By default, this scrubbing process occurs every 30 seconds. For busy/heavily loaded sites, this scrubbing interval might be too short; heavily loaded servers are more likely to encounter lock contention issues between sessions trying to update their scoreboard entry and the daemon trying to scrub the scoreboard. Such sites are advised to use ScoreboardScrub configuration directive. This directive can be used to turn on or off the periodic scrubbing, or to set a different scrub interval. The following shows some examples of ScoreboardScrub usage:

      # The default is to use scoreboard scrubbing, at the default interval
      ScoreboardScrub on
    
      # If we are busy server, we might want to turn off scoreboard scrubbing
      # entirely
      ScoreboardScrub off
    
      # Scrubbing is acceptable, but have it happen every 5 minutes instead
      ScoreboardScrub 300
    

    Note that if scoreboard scrubbing is turned off, the ScoreboardFile can still be scrubbed on demand, either by using the mod_ctrls_admin's "ftpdctl scoreboard scrub" action, or by using the ftpscrub command-line utility.

    Frequently Asked Questions
    Question: Why doesn't proftpd create the needed directories, if they're not there, when opening the scoreboard?
    Answer: The short answer is because that is the job of the system administrator, not the application. The long reason is that proftpd does not know the filesystem layout being used, and does not know what sort of permissions should be given to any directories it might need to create for its scoreboard.

    Question: Can I copy my scoreboard from one server to another?
    Answer: No. ScoreboardFiles cannot be copied from server to server; they are specific to that particular installation.

    In the same fashion, you should not try to place the scoreboard on an NFS filesystem. First, attempting to share the scoreboard is not supported, and will only lead to trouble. Second, NFS does not support file locking, which proftpd requires for handling the scoreboard.

    Question: Why do I see "scrubbing scoreboard" in my debugging output?
    Answer: These debug messages indicate when the proftpd daemon is scrubbing the ScoreboardFile.

    Question: Our site has many connections, and it looks like the logins/sessions are slow. Analysis shows that the session processes are all waiting/competing for the ScoreboardFile. What can be done to fix this?
    Answer: One particular trick to use for this situation is to use /dev/null, e.g.:

      ScoreboardFile /dev/null
    
    For one site which tried this configuration, proftpd was able to function without complaining about using /dev/null as the ScoreboardFile, the system load dropped dramatically, and the FTP sessions were no longer slow.

    However, be aware that using this trick causes the following to NOT work:

    • ftpcount
    • ftpwho
    • ftptop
    • ftpdctl kick
    • MaxClients
    • MaxClientsPerClass
    • MaxClientsPerHost
    • MaxClientsPerUser
    • MaxConnectionsPerHost
    • MaxHostsPerUser
    • MaxTransfersPerHost
    • MaxTransfersPerUser

    Question: What should I do if I see this error in my logs:

      error opening scoreboard: bad version (too old)
    
    Answer: This error usually only happens for servers which have:
      ServerType inetd
    
    in their proftpd.conf files. It indicates that the existing ScoreboardFile is using a format which is too old for the running code. The fix is simple: delete that old ScoreboardFile. The daemon will automatically create a new scoreboard in the correct format.


    $Date: 2013/01/04 23:07:38 $
    proftpd-dfsg-1.3.5~rc3/doc/howto/Quotas.html0000644000175000017500000004104311232075745020624 0ustar frankiefrankie ProFTPD mini-HOWTO - Quotas

    ProFTPD Quotas


    A busy FTP server handles hundreds to thousands of files belonging to hundreds to thousands of users. There is not an infinite capacity on the disks of the server, however, and eventually those files will take up too much space. Thus many sites have a pressing need to set limits on just how much can be stored on the server by their users.

    Most Unix systems have support for OS- or fileystem-level quotas. These have the advantage of being transparent to applications like proftpd, which means that the applications need not worry about maintaining and enforcing quotas. The kernel/filesystem will handle that. One disadvantage these OS-level quotas have, though, is that they are strictly tied to OS and/or filesystem, and not all Unix kernels and filesystems are the same. They also rely on each user having their own separate user ID. In the case of virtual users for proftpd, it is possible for many users to have the same user ID, which causes problems for these traditional Unix quotas.

    For these reasons, the mod_quotatab module was developed for ProFTPD. This module, being part of the application, applies to all the Unix kernels and filesystems which support ProFTPD, and easily handles virtual users. The mod_quotatab documentation covers how to configure proftpd for quotas.

    Note: This howto is a work-in-progress. Please contact me with suggestions, questions, requests, etc for what you would like to see covered here. Thanks!

    Example Configuration
    Here is an example mod_quotatab configuration for supporting quotas via file tables and SQL tables. This is an example only.

      <IfModule mod_quotatab.c>
        QuotaEngine on
        QuotaLog /var/log/ftpd/quota.log
    
        # For more information on using files for storing the limit and tally
        # table quota data, please see the mod_quotatab_file documentation:
        #
        #   http://www.castaglia.org/proftpd/modules/mod_quotatab_file.html
        #
        <IfModule mod_quotatab_file.c>
          QuotaLimitTable file:/etc/ftpd/ftpquota.limittab
          QuotaTallyTable file:/etc/ftpd/ftpquota.tallytab
        </IfModule>
    
        # For more information on using a SQL database for storing the limit and
        # tally table quota data, please see the mod_quotatab_file documentation:
        #
        #   http://www.castaglia.org/proftpd/modules/mod_quotatab_sql.html
        #
        <IfModule mod_quotatab_sql.c>
          SQLNamedQuery get-quota-limit SELECT "* FROM quotalimits WHERE name = '%{0}' AND quota_type = '%{1}'"
          SQLNamedQuery get-quota-tally SELECT "* FROM quotatallies WHERE name = '%{0}' AND quota_type = '%{1}'"
          SQLNamedQuery update-quota-tally UPDATE "bytes_in_used = bytes_in_used + %{0}, bytes_out_used = bytes_out_used + %{1}, bytes_xfer_used = bytes_xfer_used + %{2}, files_in_used = files_in_used + %{3}, files_out_used = files_out_used + %{4}, files_xfer_used = files_xfer_used + %{5} WHERE name = '%{6}' AND quota_type = '%{7}'" quotatallies
          SQLNamedQuery insert-quota-tally INSERT "%{0}, %{1}, %{2}, %{3}, %{4}, %{5}, %{6}, %{7}" quotatallies
    
          QuotaLock /var/lock/ftpd.quotatab.lock
          QuotaLimitTable sql:/get-quota-limit
          QuotaTallyTable sql:/get-quota-tally/update-quota-tally/insert-quota-tally
        </IfModule>
      </IfModule>
    

    Frequently Asked Questions

    Question: How do I set the disk space limit for a user?
    Answer: The short answer is to use the "upload bytes limit" setting.

    It's true that the various limits maintained by mod_quotatab, for either bytes or files (or both), are confusing. When designing the module, I anticipated administrators wanting to limit download as well as upload transfers; in reality, most administrators wish to limit the disk space for their users. The bytes uploaded limit doubles as the disk space limit, for there is no effective difference between them; any bytes uploaded via FTP are automatically stored on disk.

    Question: mod_quotatab only tracks changes made using proftpd, and my users can add/remove files other ways. What am I supposed to do?
    Answer: As the mod_quotatab documentation states, the module was designed only to track changes done via FTP; it made implementation of quotas simpler.

    This question is also often posed as "Why can't mod_quotatab just calculate the amount of space used by a user?" The module could do this, but there are some considerations with this kind of approach.

    The primary consideration is the time cost of having to recurse a directory. If the directory is relatively small, the time needed is small. For very large/deep directories, however, the time needed to do the scan could be long, possibly long enough for users to notice and complain. Another complication is the disk space used by a given user is not confined to their home directory. Many sites have home directories for users, and have a shared directory that all users can use. Somehow mod_quotatab would need to know to scan these shared directories.

    As of proftpd-1.3.1rc1, the mod_quotatab supports this feature via the ScanOnLogin parameter of the QuotaOptions directive.

    Question: If I use this ScanOnLogin option, how do I tell it to ignore certain files?
    Answer: Use the new QuotaExcludeFilter directive. For example, if you wanted to exclude all files that ended in ".log" from the automatic quota calculation, you might use:

      <IfModule mod_quotatab.c>
         ...
    
         # Automatically calculate the used quota on login
         QuotaOptions ScanOnLogin
    
         # Do not include files ending in ".log" in the automatically
         # calculated quota
         QuotaExludeFilter \.log$
      </IfModule>
    

    Question: If mod_quotatab does not automatically scan for disk space usage, how will it know about my existing users?
    Answer: By default, mod_quotatab indeed knows nothing about what disk space is already occupied by your users; the tally table starts out blank.

    To help address this, there is a diskuse.pl Perl script:

      http://www.castaglia.org/proftpd/contrib/diskuse
    
    which will display the number of bytes owned by a given user (or group) within a list of directories. The parameters needed for running diskuse.pl are documented here.

    Once you've run diskuse.pl to find out the current usage for your users, you can enter those numbers into your tally table. Unfortunately diskuse.pl cannot read your proftpd.conf file to know whether you are using a file- or SQL-based tally table, so it cannot automatically update your tally table.

    Question: How can I set a default quota for all of my users?
    Answer: Unfortunately, there is no way currently to do this. The mod_quotatab module was designed such that the administrator would have to explicitly create limits for every user.

    However, a mod_quotatab_default module could be written to provide default quotas. I simply do not know if this would be desirable enough to users for writing the module.

    Question: What is a "tally table"?
    Answer: Tally tables, and limit tables, are covered in the mod_quotatab documentation.

    Question: How do I construct the limit and tally files for file-based quotas?
    Answer: There is a Perl script called ftpquota which can create the necessary files. This script can also be found under the contrib/ directory of the proftpd source distribution.

    Question: Is there a SQL script for the SQL quota tables used by mod_quotatab_sql?
    Answer: No. However, the mod_quotatab_sql documentation contains example schema for the necessary tables.

    Question: How do I set a limit on the size of a directory?
    Answer: Currently, you cannot.

    Traditional Unix quotas are implemented in terms of ownership: the thing that counts is not where a file is located on the filesystem, but which user and/or group owns the file. Asking about directory quotas assumes a different basis for quotas, based on location rather than ownership (such quotas are often called tree-based quotas). The mod_quotatab module followed the example of traditional Unix quotas, but I have started designing how location-based quotas might be implemented.

    Question: Why isn't mod_quotatab updating my tally table?
    Answer: It depends.

    One possibility is that the per session flag in the limit in effect is set to true, which means that the limits will only be applied to this session. When this happens, mod_quotatab will not update the tally table.

    Another possibility is that your configured limits are "unlimited" (i.e. zero). As it states in the mod_quotatab documentation:

      For any quota limit that is set as "unlimited", mod_quotatab will not keep the tally.
      Many site administrators might want this ability, for accounting purposes. However,
      that ability is outside of the intended design of this module; other logging modules
      are much better suited for accounting purposes (e.g. mod_sql's SQLLog directive).
    

    If the above cases are not applicable, then consider looking in the QuotaLog file for more information.

    Question: Can I use mod_quotatab to set monthly quotas?
    Answer: Sort of. mod_quotatab itself has no concept of time, so this sort of capability is not built-in. However, it can be approximated by having some other process, such as a cron job, periodically (such as once a month) clear the tally table, yielding the effect of monthly quotas.

    Question: How can users see their current quota?
    Answer: There are two ways to show the current quota to users. There is the SITE QUOTA command. And there are certain Display variables that are supported by the mod_quotatab module.

    Question: What if I want to set limits on the size of individual files being transferred?
    Answer: For this, you do not need the mod_quotatab module. ProFTPD has the MaxRetrieveFileSize and MaxStoreFileSize directives.

    Question: Why do I see the following error?

      QuotaLimitTable: unsupported table source type: 'sql'
    
    Answer: The mod_quotatab module acts as a general quota managing front-end; it relies on other backend modules to handle the specifics of storage formats. Every backend module (e.g. mod_quotatab_file, mod_quotatab_sql, mod_quotatab_ldap) registers a supported table type with the main mod_quotatab module. The error above indicates that the mod_quotatab_sql module has not been compiled/loaded into proftpd.

    Question: How do group quotas work? If a user is in multiple groups, what happens?
    Answer: The mod_quotatab module searches for applicable quotas, by type, in the following order:

    • user quotas
    • group quotas
    • class quotas
    • the "all" quota
    Thus if there is a user-specific quota, it will be used; the search stops there. The mod_quotatab module does not combine multiple different quotas.

    What happens, then, if a user belongs to multiple different groups, and there are different quotas set for those different groups? First, the primary group of the user is checked; this is the group that is included, for example, in the entry for the user in the /etc/passwd file. If no quota for the primary group is found, the module then checks against each of the user's supplemental groups. The order in which these groups are checked is dependent up on the order in which the groups are returned from the auth module providing them, e.g. mod_sql, mod_ldap, or perhaps mod_auth_unix.

    Question: Does mod_quotatab handle the case where a client might append to/overwrite an existing file, in terms of tracking bytes?
    Answer: Yes. The mod_quotatab module checks the size of the file before the upload/append starts, and then checks the size of the file again after the upload/append completes. The difference in file sizes is used for tracking the byte-related tallies.

    Question: I configured limits for my users such that only the transfer bytes limit is set. On uploads, my transfer bytes tally is incremented properly. But when I delete a file, the transfer bytes tally is not decremented. Is this a bug?
    Answer: No, it's not a bug.

    Deleting a file does not count as transferred bytes (i.e. it does not pertain to the bytes_xfer limit); it counts as uploaded bytes (i.e. the bytes_in limit). And since there is only a limit, in this case, on the transferred bytes, the mod_quotatab module ends up not changing any tally value for a delete. More details on this can be found in Bug#2897.


    $Date: 2009/07/23 15:04:05 $
    proftpd-dfsg-1.3.5~rc3/doc/howto/Tracing.html0000644000175000017500000002134412031111144020717 0ustar frankiefrankie ProFTPD mini-HOWTO - ProFTPD Tracing

    ProFTPD Tracing


    What is Tracing?
    "Tracing" is a new form of logging, introduced in the 1.3.1 ProFTPD release series.

    Trace logging has the concept of multiple logging channels, each of which has its own log level. Layers and APIs within the ProFTPD source will tend to use their own channels. There is no limit to the number of different log channels that can be supported.

    Within a channel, the assumption is that lower log levels indicate higher priority or importance. Or to look at it another way, the higher the log level for channel, the more noisy that log channel might be. The lowest log level is 1; there is no upper log level limit.

    Why have this new form of logging, in addition to all the other kinds of logs (e.g. SystemLog, ExtendedLog, etc) that a proftpd daemon can currently produce? The usual SystemLog of proftpd debug logging, at a high DebugLevel, was becoming unreadable; it is difficult to find the tidbits of knowledge amidst the other messages in that file. By separating log messages into channels and levels, tracing gives the administrator a much finer-grained control over the logging, given them a way of focusing the logging more narrowly, so only the area of code of interest is logged.

    Support for tracing is enabled by default. Use the --disable-trace configure option, when compiling ProFTPD, to disable all tracing support. I recommend that high-traffic production sites, which have no need for debug logging at this granularity, use the --disable-trace option.

    Configuration Directives
    There are two new configuration directives for tracing: TraceLog and Trace. Note that for tracing to be effective, these two directives, if used, must appear at the start of your proftpd.conf file, before any other directives.

    The TraceLog directive specifies a filename to which to write the tracing log messages. For example:

      TraceLog /var/ftpd/trace.log
    
    Without this directive, no trace logging will occur.

    Once you have configured your TraceLog, you will use the Trace directive to control the verbosity of that log:

      Trace channel1:level1 channel2:level2 ...
    
    This directive lets you set each log channel and its level differently, e.g.:
      Trace command:5 response:8 timer:2 config:9
    
    There is also support for a special "DEFAULT" keyword:
      Trace DEFAULT:10
    
    The following is the list of channels which are covered by the "DEFAULT" keyword:
    • auth
    • binding
    • command
    • config
    • ctrls
    • data
    • delay
    • dns
    • dso
    • encode
    • event
    • facl
    • fsio
    • ident
    • inet
    • lock
    • netacl
    • netio
    • pam
    • pool
    • regexp
    • response
    • scoreboard
    • signal
    • site
    • timer
    • var
    This means that if you use the following in your proftpd.conf file, at the very top:
      TraceLog /path/to/ftpd/trace.log
      Trace DEFAULT:10
    
    Then all of the above channels, up to log level 10, will have their messages logged.

    If you want to look at the default trace channels except for a particular channel, use level 0 to effectively disable that channel. For example, to exclude the "fsio" channel but see the rest of the default channels, you would use:

      Trace DEFAULT:10 fsio:0
    

    Note that there are trace channel names that are not part of the "DEFAULT" channel name list (e.g. "class"); any custom channel names, such as might be used by a third-party module, are also not covered in the "DEFAULT" list. For example, the mod_tls module may log to a "tls" channel. Any messages to that "tls" channel would not appear in the TraceLog file, using the above configuration. Instead, you would need to explicitly mention the "tls" channel, i.e.:

      TraceLog /path/to/ftpd/trace.log
      Trace DEFAULT:10 tls:10
    

    Optional Trace Log Channels
    In addition to the default trace log channels listed above, there are optional trace log channels:

    • directory

      The "directory" log channel is used when the core engine attempts to find the closest matching <Directory> section for a path.

    • fileperms

      The "fileperms" log channel is used whenever a user action involving the filesystem (e.g. opening/closing/writing/renaming/deleting files or directories) fails. This channel will log the relevant FTP command, user name, UID/GID, filesystem path, and the error.

    Trace Log Format
    Every log message in a TraceLog uses the following format:

      timestamp [process ID] <channel:level>: message
    
    For example:
      Jan 16 17:15:58 [30583] <auth:6>: dispatching auth request "endgrent" to module mod_auth_unix
    
    This shows process ID 30583 logging to the "auth" channel, log level 6, a message about handling the "endgrent" Auth API request.

    Runtime Tracing
    If Controls support is enabled in your proftpd, and you are using the mod_ctrls_admin module, then you can also use the ftpdctl command to adjust the trace logging settings in the running proftpd, without needing to change your proftpd.conf file. See:

      doc/contrib/mod_ctrls_admin.html#trace
    
    for more information on the ftpdctl trace action.

    Here's a concrete example of how tuning the trace logging at runtime can be useful. You may need the extra information logged via trace logging in order to track down/debug some issue, but you do not want to enable trace logging all of the time in your environment. Fortunately, it is possible to make it possible to get the trace logging information you need, when you need to get it, and then turn the trace logging off all without restarting proftpd.

    First, you need to configure your proftpd.conf like so:

      TraceLog /path/to/proftpd/trace.log
      Trace DEFAULT:0
    
    This configuration tells proftpd to direct all trace logging to that TraceLog file, but to not actually write anything to the file; the log level zero (0) filters out all trace logging messages. Start proftpd with the updated proftpd.conf. Later, while proftpd is running, you can tune the tracing using the ftpdctl utility, like this:
      # ftpdctl trace lock:10 scoreboard:5
    
    which dynamically changes the 'lock' trace channel level to 10, and the 'scoreboard' trace channel level to 5. Once you have gathered the necessary information in the TraceLog file, you then use ftpdctl again and restore the trace levels back to zero, effectively turning off trace logging once more:
      # ftpdctl trace DEFAULT:0
    
    Note that the changed settings will only apply to new sessions; this does not change the trace logging for existing sessions.

    Use Only When Needed
    Remember that tracing is a verbose (and thus expensive) form of logging, and thus makes the proftpd daemon run slower. Tracing should only ever be used for debugging and development purposes; once your proftpd is up and running the way you need, you should remove all Trace and TraceLog directives from your proftpd.conf.

    Frequently Asked Questions

    Question: Can I configure Trace on a per-user basis, using mod_ifsession's <IfUser>?
    Answer: You can indeed use mod_ifsession for Trace configurations, starting in ProFTPD 1.3.4rc1. To do this, you need to use the optional "session" keyword in your Trace configuration, e.g.:

      <IfUser traced-user>
        Trace session DEFAULT:10
      </IfUser>
    
    This goes for <IfClass> and <IfGroup> sections as well.


    $Date: 2012/09/27 17:52:36 $
    proftpd-dfsg-1.3.5~rc3/doc/howto/Limit.html0000644000175000017500000003622412147434463020435 0ustar frankiefrankie ProFTPD mini-HOWTO - Configuring <Limits>

    Configuring <Limits>


    ProFTPD's <Limit> configuration sections allow for powerful fine-grained control over who is allowed to use which FTP commands. This power comes at the price of complexity, however. This document describes some of the things to keep in mind when writing <Limit> sections.

    Precedence
    Perhaps the hardest part of using <Limit> is understanding its rules of precedence, which dictate which <Limit>'s restrictions apply when. Precedence is discussed in the directive documentation, and will be mentioned here. First, there are three types of parameters in a <Limit> directive: "raw" FTP commands, FTP command groups, and the ALL keyword.

    "Raw" FTP commands are listed here, including the RFC-mandated X-variant FTP commands, which are often missing from a thorough <Limit> configuration.

    The FTP command groups are:

    • ALL
      Covering: all FTP commands (but not LOGIN)

    • DIRS
      Covering: CDUP, CWD, LIST, MDTM, MLSD, MLST, NLST, PWD, RNFR, STAT, XCUP, XCWD, XPWD

    • LOGIN
      Covering: client logins

    • READ
      Covering: RETR, SIZE

    • WRITE
      Covering: APPE, DELE, MKD, RMD, RNTO, STOR, STOU, XMKD, XRMD

    <Limit>s that use "raw" FTP commands have the highest precedence, followed by <Limit>s that use the command groups, and, having the lowest precedence, the ALL keyword. If a <Limit> has both "raw" commands and command groups, then it boils down to the order of appearance of <Limit> sections in proftpd.conf that use the "raw" command in question.

    SITE Commands
    To apply a <Limit> to a SITE command, combine "SITE" and the command (e.g. "CHMOD") by an underscore ("_"), like so:

      <Limit SITE_command>
    
    Thus, in order to place a limit on SITE CHMOD, one would have:
      <Limit SITE_CHMOD>
        DenyAll
      </Limit>
    

    Inheritance
    Most <Limit> sections appear within <Directory> sections in proftpd.conf. This means that, like the other <Directory> configuration effects, the <Limit>s will be inherited by all subdirectories that appear in the <Directory> path, unless explicitly overridden by a "closer" <Limit> section. This means that one could configure a <Limit> section denying all FTP commands for all directories, and then explicitly allow the READ or WRITE FTP command groups in appropriate subdirectories (e.g. pub/ or incoming/ directories).

    Using AllowUser and DenyUser
    There is a catch to using the AllowUser configuration directive that causes confusion, primarily when a single AllowUser directive is being used to allow access to some FTP commands only to certain users. ProFTPD uses the same function for parsing the AllowUser and AllowGroup (and other) directives. This function parses the list of names for such directives as a Boolean AND list, which means that each name on the list must evaluate to TRUE (must match) for the current user in order for the directive to apply. For AllowGroup, this makes sense, and allows a great deal of flexibility. However, it does not make sense for AllowUser, because a user may not be multiple users at the same time. This is a known issue, and a proper, thorough solution is being developed. In the meantime, however, there is a workaround for allowing multiple users via the AllowUser directive. Rather than listing the users using a single AllowUser, using a separate AllowUser for each user. For example, instead of:

      AllowUser bob,dave,wendy
    
    try using:
      AllowUser bob
      AllowUser dave
      AllowUser wendy
    
    All of this applies to the DenyUser directive as well.

    Another important item to keep in mind is that the names used in <Limit> sections, e.g. using AllowUser, DenyUser, AllowGroup, and DenyGroup, are not resolved to an ID and then applied; the limits are applied only to the names. Why is this important? Consider the case where the site is using virtual users, where two different user names are assigned the same UID. Different limits can be applied to each name separately. Do not assume that the limits are applied to the underlying IDs.

    Using Order
    One thing that sometimes trips up some administrators is the difference between ProFTPD's and Apache's Order configuration directives. For Apache, an Order of "Allow,Deny" means that access is denied by default, unless an Allow directive explicitly allows access; an Order of "Deny,Allow" means that access is allowed by default, unless a Deny directive explicitly denies access. This is different from ProFTPD, where an Order of "Allow,Deny" allows access by default, unless denied by a Deny directive; "Deny,Allow" denies access by default, unless explicitly granted by an Allow directive. The developers of ProFTPD felt their interpretation to be the more "common sense" interpretation, even though it does not match Apache's interpretation.

    Examples
    Here are examples to help illustrate the use of <Limit>. First, a common configuration: an upload-only directory.

      <Directory /path/to/uploads>
        <Limit ALL>
          DenyAll
        </Limit>
    
        <Limit CDUP CWD PWD XCWD XCUP>
          AllowAll
        </Limit>
    
        <Limit STOR STOU>
          AllowAll
        </Limit>
      </Directory>
    
    The first <Limit ALL> section blocks use of all FTP commands within the /path/to/uploads directory. Having denied use of all commands, we then proceed to define which commands can be used. The CDUP and CWD commands (and their X variants) should be allowed so that clients can change into and out of the directory. Next, STOR and STOU are allowed, so that clients can actually upload files into the directory (assuming that the filesystem permissions allow for the client to write files in the directory as well). The WRITE command group might have been used, but that also allows things like creating and deleting subdirectories, which is usually not wanted in an upload-only configuration.

    This next example shows a "blind" directory, where clients can upload and download files from the directory, but they cannot see what is in the directory:

      <Directory /path/to/dir>
        <Limit LIST NLST MLSD MLST STAT>
          DenyAll
        </Limit>
      </Directory>
    
    That's it. By default, all commands are allowed in a directory. By blocking the FTP commands used to list a directory's contents (i.e. LIST, MLSD, MLST, and NLST), we have effectively blocked the client from seeing anything in the directory. Not many clients use the STAT command, but it also needs to be limited, as it can return information about files in a directory as well.

    Cautious system administrators may want only a few select system users to be able to connect to their proftpd server--all other users are to be denied access. The LOGIN command group is designed for just this scenario:

      <Limit LOGIN>
        AllowUser barb
        AllowUser dave
        AllowGroup ftpuser
        DenyAll
      </Limit>
    
    This allows the users barb and dave, as well as any user in the ftpuser group, to login. All other users will be denied.

    What if a site wished to allow only anonymous access? This would be configured using the LOGIN command group, as above:

      <Limit LOGIN>
        DenyAll
      </Limit>
    
      <Anonymous ~ftp>
        <Limit LOGIN>
          AllowAll
        </Limit>
        ...
      </Anonymous>
    
    The <Limit> section outside of the <Anonymous> section denies logins to everyone. However, the <Anonymous> section has a <Limit> that allows everyone to login; anonymous logins are allowed, and non-anonymous logins are denied.

    Another related question often asked is "How can I limit a user to only being able to login from a specific range of IP addresses?" The <Limit LOGIN> can be used, in conjunction with the mod_ifsession module and a Class, to configure this:

      <Class friends>
        From 1.2.3.4/8
      </Class>
    
      <IfUser dave>
        <Limit LOGIN>
          AllowClass friends
          DenyAll
        </Limit>
      </IfUser>
    

    Or if you want to have a specific IP address, rather than a range, you can do this without classes (but still requiring mod_ifsession):

      <IfUser dave>
        <Limit LOGIN>
          Deny from 1.2.3.4
        </Limit>
      </IfUser>
    
    Note that the same effect can be achieved by using the mod_wrap2 module to configure user-specific allow/deny files.

    One issue that you should avoid is having multiple different <Limit LOGIN> sections in your config for the same vhost. Consider a config like this:

      <VirtualHost 1.2.3.4>
        ...
        <Limit LOGIN>
          Order allow, deny
          Allow from 192.168.0.0/16
          DenyAll
        </Limit>
        ...
        <Limit LOGIN>
          Order deny, allow
          Deny from 192.168.0.0/16
        </Limit>
        ...
      </VirtualHost>
    
    The two <Limit LOGIN> sections conflict; which one will proftpd actually use for deciding whether to allow a connection to that <VirtualHost>? Answer: the last <Limit LOGIN> section defined. To avoid confusion, then, it is best to consolidate all of your <Limit LOGIN> rules into a single section for a given vhost.

    In Apache, it is possible to configure password-protected directories. Some sysadmins attempt to configure proftpd similarly, by unsuccessfully attempting something like this in the proftpd.conf file:

      <Directory /some/path>
        <Limit LOGIN>
          DenyUser foo
        </Limit>
      </Directory>
    
    The above will not work. FTP clients (unlike HTTP clients) login to the server, not into specific directories.

    One situation that often arises is one where the administrator would like to give users the ability to upload and dowload files from a given directory, but not to be able to delete files from that directory. This cannot be accomplished using normal Unix filesystem permissions, for if a user has write permission on a directory (necessary for uploading files to that directory) they also have delete permissions. In Unix, a directory file serves as a sort of "table of contents", tracking the files in the directory. Adding or removing a file are thus changes on the directory file, and do not involve checking the permissions on the file being added or removed. This is also how a non-root user can delete files that are owned by root and only have user-write permissions. So how then can a site be configured to allow writes but not deletes? By using a configuration similar to the following:

      <Directory /path/to/dir>
        <Limit DELE>
          AllowUser ftpadm
          DenyAll
        </Limit>
      </Directory>
    
    This will allow the user ftpadm to delete files in the /path/to/dir, but no other users.

    The FTP protocol has two types of data transfers: active and passive. In some configurations, only one type of transfer is allowed by the network (e.g. active transfers should be denied because clients are sending the wrong IP addresses). The ability to place a <Limit> on the FTP commands response for active and passive data transfers was added to ProFTPD in 1.2.10rc1. If you are using that version or later, you can use the following to block active transfers:

      <Limit EPRT PORT>
        DenyAll
      </Limit>
    
    Or, conversely, to block passive data transfers:
      <Limit EPSV PASV>
        DenyAll
      </Limit>
    

    Another common question is: "How can I create a read-only account using <Limit> sections"? Here's how:

      # Assumes that the user is chrooted into their home directory
      <Directory ~user>
        <Limit CWD PWD DIRS READ>
          AllowUser user
        </Limit>
    
        <Limit ALL>
          DenyUser user
        </Limit>
      </Directory>
    

    What if you want to prevent a certain directory from being deleted, but you do want to allow sub-directories in that directory to be deletable? Using two <Directory> sections with <Limit> sections, you can do this, e.g.:

      <Directory /path/to/dir>
        <Limit RMD XRMD>
          DenyAll
        </Limit>
      </Directory>
    
      <Directory /path/to/dir/*>
        <Limit RMD XRMD>
          AllowAll
        </Limit<
      >/Directory>
    
    Note the trailing "/*" suffix in the second <Directory> section; this means that the second <Directory> section configuration applies to the sub-directories, but not to the parent directory itself (which is covered by the first <Directory> section).

    What if you want to make sure the directory cannot be renamed, in addition to ensuring that it cannot be deleted? Simply include the RNFR and RNTO FTP commands in the list of denied commands, e.g.:

      <Directory /path/to/dir>
        <Limit RMD RNFR RNTO XRMD>
          DenyAll
        </Limit>
      </Directory>
    


    Last Updated: $Date: 2013/05/23 15:43:47 $

    proftpd-dfsg-1.3.5~rc3/doc/howto/Timestamps.html0000644000175000017500000001553411763714743021513 0ustar frankiefrankie ProFTPD mini-HOWTO - ProFTPD and Timestamps

    ProFTPD and Timestamps


    There have been various reports that timestamps displayed in various ProFTPD log files, such as an ExtendedLog or TransferLog, or even in directory listings, are not as expected. Other applications (e.g. sshd) on the same machine do not exhibit the same problem. So is proftpd having issues with timestamps?

    If the timestamps in question are those displayed in directory listings, then you need to check your TimesGMT configuration. Otherwise, depending on the logs at which you are looking, the timestamps will be correct until the user logs in. After that, the timestamps are wrong. This is one clue. The other clue is that these wrong timestamps go away when the DefaultRoot directive is removed from the proftpd.conf file.

    The answer turns out to be the chroot(2) system call, which proftpd uses to restrict users to certain directories, usually their home directory. There are two configuration directives which tell proftpd to use the chroot(2) system call:

      <Anonymous>
      DefaultRoot 
    
    The system libc library is responsible for generating times, based on timezone settings and such. The GNU libc library (called glibc for short), used on all Linux systems changed in later versions, and now makes some assumptions. Specifically, glibc assumes the location of the system timezone files. But once a process has been chrooted, those assumptions break. The fallback behavior of glibc, when it cannot find the system timezone files, is to use GMT.

    The good news is that the above behavior does not happen if the TZ environment variable is set explicitly, to the required timezone. That is, if glibc needs to detect the timezone and it finds that TZ is set, then glibc will use that TZ setting, rather than falling back to GMT.

    Affected Library Functions
    Once a process has chrooted, the following libc function calls will have possibly-bad side effects, with regard to timezone detection: localtime(3), ctime(3), and mktime(3). As documented in the man pages for these functions, each of them will set the tzname global variable to the "current" timezone. This "current" timezone is what changes, once the process has become chrooted. (For more information on the tzname global variable, read the tzset(3) man page.)

    Solutions
    Recent releases of ProFTPD attempt to work around these issues by preserving the tzname global variable after calling localtime(3), and by automatting setting the TZ environment variable, is not already set, before calling chroot(2). These measures are defensive at best, though.

    The best way to deal with this issue, which is especially prominent on systems running glibc-2.3 or later, is to set the TZ environment variable explicitly, before starting proftpd. This can be done in an init script for proftpd, for example.

    You can also use the SetEnv configuration directive within the proftpd.conf file to set the TZ environment variable, e.g.:

      # Set the TZ environment variable to be Pacific Standard Time (PST)
      SetEnv TZ PST
    
    Obviously you will need to set the timezone to whatever is appropriate for your site. For example, some systems expect different values for the TZ environment variable, e.g.:
      SetEnv TZ :/etc/localtime
    
    Note: Using a filesystem location such as ":/etc/localtime" for the TZ environment variable can still result in log timestamp issues, e.g. when the MFMT/MFF FTP commands are used. The best solution is to always specify the timezone name, rather than a file, whenever possible.

    These are provided as examples; please consult your system documentation for the proper syntax to use for the TZ value.

    Frequently Asked Questions

    Question: Why is the timestamp on my newly uploaded file wrong?
    Answer: If by "wrong" you mean "different from the timestamp of that file on my client machine", then that is the expected behavior.

    The modification timestamp on a file is not part of the data uploaded over the data connection when uploading a file. Timestamps like that are metadata for that file, not part of the bytes of the file itself. FTP does not supporting sending of timestamps as part of the upload transfer process. See below for a common follow-up question.

    Question: Does ProFTPD support changing the timestamp on a file using the MDTM command? That's what my client does.
    Answer: No.

    Why not? For several reasons:

    In short, it is a royal mess. ProFTPD supports MDTM for retrieving the modification time, in GMT. Period.

    If you want to set the modification time, you can use the MFMT command supported by the mod_facts module, or the mod_site_misc module's SITE UTIME command.

    Question: I thought that the TimesGMT directive was affected the timestamps that proftpd uses?
    Answer: No. The TimesGMT directive only affects the timestamps as displayed to FTP clients in directory listings; it does not affect the timestamps used in log files.


    $Date: 2012/06/06 17:56:51 $
    proftpd-dfsg-1.3.5~rc3/doc/howto/Globbing.html0000644000175000017500000001325311662547623021103 0ustar frankiefrankie ProFTPD mini-HOWTO - Globbing

    Globbing


    What is Globbing?
    Globbing is a common Unix shell mechanism for expanding wildcard patterns, for matching multiple filenames. From the glob(7) man page:

      A string is a wildcard pattern if it contains one of the characters
      `?', `*' or `['. Globbing is the operation that expands a wildcard pattern
      into the list of pathnames matching the pattern. Matching is defined by:
    
        A `?' (not between brackets) matches any single character.
    
        A `*' (not between brackets) matches any string, including the empty
        string.
    
    The RFCs that define FTP do not explicitly mention globbing; this means that FTP servers are not required to support globbing in order to be compliant. However, many FTP servers do support globbing (including ProFTPD), as a measure of convenience for FTP clients and users.

    The mget ftp(1) command commonly uses globbing to retrieve multiple files, e.g.:

      ftp> mget *.gz
    
    or:
      ftp> mget pub/music/*.mp3
    
    Other FTP clients may have similar client-side commands for listing and retrieiving multiple files based on globbing expressions.

    Why Globbing is an Issue
    In order to search for and match the given globbing expression, the code has to search (possibly) many directories, examine each contained filename, and build a list of matching files in memory. This operation can be quite intensive, both CPU- and memory-wise. This intense use of resources led to the original posting of possible Denial of Service (DoS) attacks against proftpd (later, when the culprit was tracked to the underlying library globbing code, other applications were found to be vulnerable as well):

      http://bugs.proftpd.org/show_bug.cgi?id=1066
    
    The above bug report shows an example of a globbing expression that was used to attempt a DoS by means of many directory levels.

    Some servers (e.g. wu-ftpd) come with their own custom code for handling globs; others (including proftpd) make use of the system's C library routines for globbing. The GNU globbing code, bundled with proftpd, was updated to match the current GNU implementation of globbing in their C library (glibc), and proftpd was changed to always use that bundled GNU code, rather than the host system's globbing functions (as the host code might possibly be unsafe).

    Every now and then, this issue is reported on various mailing lists. As some system resources are needed when handling globbing expression, some users report this as a DoS possibilty. Which is why proftpd supports a few ways to restrict how globbing is handled, according to the needs of the site.

    Globbing Restrictions
    ProFTPD has several mechanisms in place for limiting, or disabling entirely, support for globbing. If your site does not require globbing, it is highly recommended that globbing be disabled altogether, by adding this to your proftpd.conf:

      UseGlobbing off
    

    If, on the other hand, your site does need to support globbing (many FTP users will assume that globbing is supported), there are other ways of limiting the amount of resources used when globbing: the RLimitCPU and RLimitMemory configuration directives. In proftpd-1.2.7, these directives were enhanced so that they could be applied strictly to session processes (rather than the daemon process):

      RLimitCPU session ...
      RLimitMemory session ...
    
    And, for the paranoid system administrator, a way of limiting the number of directories supported in a globbing expression was added in 1.2.8rc1: PR_TUNABLE_GLOBBING_MAX_RECURSION. By default, the maximum number of levels supported is 8 (this is the hardcoded default in the GNU library implementation of globbing). To change this to a lower number, compile proftpd using a configure line that looks something like this:
      ./configure CFLAGS="-DPR_TUNABLE_GLOBBING_MAX_RECURSION=3" ...
    
    A globbing expression that contains more than the maximum number of supported levels is not executed, but instead an error code signalling "out of memory" is immediately returned, which is GNU's way of saying that it will not handle the expression.

    There is a similar limit on the maximum number of files that will be checked for a glob expression. By default, this limit is 100000 (the hardcoded default in the GNU library glob(3) implementation). In the 1.3.3rc1 ProFTPD release, a way of altering this limit was added: PR_TUNABLE_GLOBBING_MAX_MATCHES. For sites which really do require a higher number of files to be matched for their glob expressions, the following configure command can be used:

      ./configure CFLAGS="-DPR_TUNABLE_GLOBBING_MAX_MATCHES=200000UL" ...
    
    A globbing expression that needs to examine more files than this limit will have the number of matches silently truncated to the limit (or just below).


    Last Updated: $Date: 2011/11/21 22:24:19 $

    proftpd-dfsg-1.3.5~rc3/doc/howto/Authentication.html0000644000175000017500000003655111320426111022320 0ustar frankiefrankie ProFTPD mini-HOWTO - Logins and Authentication

    ProFTPD Logins and Authentication


    Logging into proftpd and being successfully authenticated by the server involves a lot of different modules and different checks. This document aims to discuss the sort of checks and configuration involved, and hopefully provide a better idea of how proftpd authenticates users.

    PAM
    PAM, which stands for Pluggable Authentication Modules, is an API intended to make it easy to replace the old Unix-style DES password hashes stored in /etc/passwd with a flexible system that allows system administrators to use MD5 checksums, SQL tables, LDAP servers, RADIUS servers, etc in place of that password check. However, what PAM does not provide is the rest of the user account information in /etc/passwd, i.e. the user's UID and GID, home directory, and shell. This means that PAM cannot be used as a drop-in replacement for user information stored in /etc/passwd. NSS (Name Service Switch) modules, supported by some operating systems, are a complementary API to PAM which can be used to supply the rest of this user information. proftpd uses the normal libc functions for looking up user information, and those libc functions typically read /etc/passwd. NSS is an abstraction layer within some libc implementations that causes those functions to read other sources rather than /etc/passwd. Regardless of NSS support, proftpd has support for "virtual" users via its authentication modules.

    When configuring proftpd, the configure script will automatically try to determine whether your operating system supports PAM. If it does, the mod_auth_pam module will automatically be compiled into your proftpd. If you explicitly do not want PAM support, you can use the --disable-auth-pam configure option to disable this automatic detection. The point of using PAM is that it can provide an extra authentication step during a login. By "authentication", I mean that PAM answers a yes/no question: "Is this user who they say they are?". PAM modules are configured either in /etc/pam.conf or /etc/pam.d/, depending on your operating system. However, many of the PAM modules provided by vendors are not designed to work well with some of the authentication modules supported by proftpd. If PAM is not a necessity for you, and you plan to use one of the authentication modules (other than mod_auth_unix), then you need do nothing. By default, proftpd uses PAM as an additional check during logins, but if that check fails, the login may still succeed. If you do need the PAM check to be authoritative, then you need to use the AuthOrder directive, e.g.:

      AuthOrder mod_auth_pam.c* ...
    
    To disable use of PAM entirely, use:
      <IfModule mod_auth_pam.c>
        AuthPAM off
      </IfModule>
    

    Configuration Directives
    There are several configuration directives that can cause login problems. The most common one is
    RequireValidShell, so common that it is a FAQ. If proftpd does not actually use the shell configured for a user, why does it check to see if the shell is valid by looking in /etc/shells? Certain other FTP servers (e.g. wu-ftpd, pure-ftpd) do check for invalid shells and deny logins based on this criterion; proftpd follows this pattern so as not to surprise too many system administrators. Use of invalid shells is a common sysadmin trick for denying shell-based login access (e.g. ssh logins); many sites use other means, however, and so use of the RequireValidShell directive is also frequently seen.

    Another reason why a client cannot login might be if the login user is root (or has a UID of zero, and hence has root privileges). Logging in as root is dangerous, and should be avoided if possible. If you do find it absolutely necessary to login as root, please use SSL/TLS, or at least tunnel your FTP connection using SSH. The RootLogin configuration directive is needed in your proftpd.conf in order for proftpd to explicitly allow root logins.

    One uncommon obstacle that you might encounter to allowing a user to login is the possibility that that user is listed in an /etc/ftpusers file. This is another legacy check, courtesy of wu-ftpd. Any user that is listed in /etc/ftpusers is not allowed to login via FTP. A little backwards from what might be expected from the file name, I agree. proftpd was made to similarly honor any /etc/ftpusers file by default in order to ease the pain for sites migrating from wu-ftpd to proftpd. Disabling proftpd's check for this file is as simple as using the UseFtpUsers configuration directive, like so:

      UseFtpUsers off
    
    in your proftpd.conf file.

    The PersistentPasswd configuration directive can be necessary in some environments, particularly those that use NIS/YP, NSS modules, or (in the case of Mac OSX) the netinfo service. In order to be able to lookup and map UIDs and GIDs to names, as when listing directories and files, proftpd tries to keep the /etc/passwd file open. This is particularly relevant if the DefaultRoot directive is in effect, for once chrooted, proftpd cannot open /etc/passwd. However, services such as NIS, NSS, and netinfo function very differently while providing a file-like interface, and they do not function properly if proftpd keeps them open. Using:

      PersistentPasswd off
    
    in your proftpd.conf should cause name lookups to work properly if you use NIS, NSS, or netinfo.

    If you feel your logins are slow, then you might be encountering another FAQ. The timeouts when performing RFC931 ident lookups, and DNS reverse resolutions, add a noticeable delay to a login.

    Anonymous Logins
    Anonymous logins are allowed by defining an
    <Anonymous> section, or context, in your proftpd.conf. No <Anonymous> contexts mean that proftpd will not allow anonymous logins. As the documentation describes, proftpd knows to treat a given login name (given to the server by the client via the USER FTP command) by seeing if the login name is the same as the User name in an <Anonymous> context. For example:

      <Anonymous /var/ftp/anon/dave>
        User dave
        Group ftpanon
        ...
      </Anonymous>
    
    would cause any client logging in as dave to be treated as an anonymous login, and to be handled using the <Anonymous> context above. This structure allows for multiple login names to be treated as anonymous logins, and for each anonymous login to have its own specific anonymous configuration. Some administrators use <Anonymous> contexts to define "virtual" users directly in their proftpd.conf, but this practice is discouraged. Virtual user accounts are discussed next.

    Resolving ~
    The DefaultRoot directive is commonly used to restrict or "
    jail" users into specific directories, usually their individual home directories. This is done via:

      DefaultRoot ~
    
    where the tilde (~) is expanded to the home directory of the logging in user. Now, when proftpd is resolving the tilde, it switches to the privileges of the logging-in user and attempts to resolve the home directory. This ensures that the user will, once restricted to that directory, will have the ability to see files and move around. So if using the tilde does not appear to be working in your configuration, double-check that the permissions on the home directory of the user in question at least allow that user to change into the directory (which requires execute permission on the home directory). If proftpd finds that the permissions are too restrictive, an error message like:
      chroot("~"): No such file or directory
    
    will be logged.

    Virtual Users
    One question that often arises is "How do I create a proftpd user?" proftpd uses your system's /etc/passwd file by default, and so proftpd users are the same as your system users. "Virtual" users, sometimes described as FTP-only user accounts, are users that can login to proftpd, but who are separate from the normal system users, and who do not have entries in /etc/passwd. proftpd does not care how or where user information is defined. The daemon is designed with an abstraction layer on top of user information sources, and that abstraction is responsible for supplying that data that is required for every user: a name, a UID, a GID, a home directory, and a shell. A user's shell will not be used except in RequireValidShell checks, but it must still present. The code that is responsible for supplying this data, reading it from whatever storage format is supported, lies in proftpd's various configurable authentication modules.

    Authentication Modules
    proftpd uses authentication modules for accessing user account information. These modules implement an API that that daemon uses to lookup account information by name or by ID, to authenticate a user using the provided password, and to resolve names to IDs or IDs to names. The following authentication modules are all provided with proftpd:

    Note that mod_auth_pam is not on this list because it cannot provide the necessary user account information. It can be used to supplement other auth modules by adding its PAM checks, however.

    Since proftpd supports multiple authentication modules at the same time, how does it know which authentication module to use? What if you want to tell proftpd which modules to check, and in which order? What if you want some authentication modules to be used in one <VirtualHost>, and different authentication modules in another?

    By default, proftpd will ask every configured authentication module about a given user, until it finds an authentication module that knows about that user, or until an authentication module signals an unrecoverable error. The order in which these modules are asked depends on the order of modules in the --with-modules option used when configuring proftpd.

    Some modules can be figured to not "play nice" and allow other authentication modules a chance at providing user information. That is, some modules can be "authoritative", and if that module does not know about the user, it will signal an error and prevent proftpd from asking other modules. mod_auth_pam's AuthPAMAuthoritative directive, and the * syntax in the SQLAuthenticate directive of mod_sql, are examples of this authoritativeness. In general, it is best to avoid using such mechanisms, and to use the AuthOrder configuration directive instead.

    The following illustrates a situation where AuthOrder is useful. The default build of proftpd has two authentication modules included: mod_auth_file and mod_auth_unix. proftpd will consult both modules when authenticating a user: first mod_auth_file, then mod_auth_unix. (Note: versions of proftpd before 1.2.8rc1 would only support either AuthUserFile or /etc/passwd, but not both at the same time.) If any authentication module can authenticate a user, then authentication succeeds. This holds true of other authentication modules like mod_ldap, mod_sql, mod_radius, etc.

    However, if you only want proftpd to use your AuthUserFile and no other authentication modules, then you would use the AuthOrder directive like this:

      AuthOrder mod_auth_file.c
    
    Or, if you use mod_sql and wanted proftpd to check your SQL tables first, and then default to system users:
      AuthOrder mod_sql.c mod_auth_unix.c
    
    Note that the mod_auth.c module should never be used in an AuthOrder directive.


    Last Updated: $Date: 2010/01/04 17:58:33 $

    proftpd-dfsg-1.3.5~rc3/doc/howto/FXP.html0000644000175000017500000001323410121156603017773 0ustar frankiefrankie ProFTPD mini-HOWTO - FXP

    ProFTPD and FXP


    FXP
    What is FXP? FXP is part of the name of a popular Windows FTP client:

      http://www.flashfxp.com
    
    This client has made the name "FXP" commonly used as a synonym for site-to-site FTP transfers, for transferring a file between two remote FTP servers without the transfer going through the client's host. Sometimes "FXP" is referred to as a protocol; in fact, it is not. The site-to-site transfer capability was deliberately designed into FTP.

    Site-to-site Transfers
    In a site-to-site transfer, the client logs in to two servers (server A and server B). It then arranges for a file transfer, telling one server (server A) that it will be a passive transfer, and the other server (server B) that it will be an active transfer. For a passive transfer, server A will return an address/port (via response to the PASV command) to which the client is to connect. The client then passes that address/port in a PORT command to server B. Then, the client sends a RETR to one of the servers and a STOR to the other, thus starting the transfer. The data does not pass to the client machine at all.

    Any firewalls protecting either (or both) servers involved may need to allow active and passive FTP data transfers, depending on which server is told to be active, which is told to be passive.

    Example Site-to-site Transfer
    In the example below, italicized represent responses to the given FTP commands. Lines in blue show communications to server A, while those in red are to server B. Black lines are informational messages displayed by the FXP client.

      TYPE I
      200 Type set to I.
      TYPE I
      200 Type set to I.
      PASV
      227 Entering Passive Mode (1,2,3,4,130,161).
      PORT 1,2,3,4,130,161
      200 PORT command successful
      STOR file.mp3
      150 Opening BINARY mode data connection for file.mp3
      RETR file.mp3
      150 Opening BINARY mode data connection for file.mp3 (15000000 bytes)
      226 Transfer complete.
      226 Transfer complete.
      Transferred: file.mp3 14.31 MB in 2.38 (6,147.06 KBps)
      TYPE A
      200 Type set to A.
      PASV
      227 Entering Passive Mode (5,6,7,8,168,183).
      LIST
      150 Opening ASCII mode data connection for file list
      226 Transfer complete.
      TYPE A
      200 Type set to A.
      PASV
      227 Entering Passive Mode (1,2,3,4,130,162).
      LIST
      150 Opening ASCII mode data connection for file list
      226 Transfer complete.
      Transfer queue completed
      Transferred 1 file totaling 14.31 MB in 3.42 (6,147.06 KBps)
    
    The client instructs server A to expect a passive data transfer, and server B to initiate an active data transfer. The address and port returned in server A's response to the PASV command is passed to server B as arguments in the PORT command. The transfer is then started by telling server A to expect a file to be uploaded, and server B to download the file. The following PASV/LIST sequences are the client confirming that the file was transferred successfully.

    This example also illustrates that site-to-site transfers use both active and passive data transfers; for sites that operate behind firewalls and NAT, passive transfers may require extra configuration to operate properly (i.e. use of the MasqueradeAddress and PassivePorts configuration directives).

    "FTP Bounce" Attacks and AllowForeignAddress
    So, what does this mean for ProFTPD? By default, ProFTPD does not allow site-to-site transfers, for by allowing them, the server also allows a type of attack known as the "FTP bounce" attack:

      http://www.cert.org/advisories/CA-1997-27.html
    
    The protection against this attack is to enforce the requirement that, from the server's point of view, the remote address of a control connection matches the remote address of a data connection. If the addresses do not match, the data connection is treated as from a foreign client, and thus rejected.

    However, some site administrators do want to allow their servers to support site-to-site transfers. ProFTPD must be explicitly configured to allow these by using the AllowForeignAddress configuration directive.

    Note that even if AllowForeignAddress is enabled, you may still encounter trouble with site-to-site transfers involving your server. These issues usually arise from firewall configurations, or with upstream ISPs performing filtering on the FTP port.


    Last Updated: $Date: 2004/09/12 23:36:35 $

    proftpd-dfsg-1.3.5~rc3/doc/howto/ConfigFile.html0000644000175000017500000002561011250312051021337 0ustar frankiefrankie ProFTPD mini-HOWTO - Configuring ProFTPD (via proftpd.conf)

    Configuring ProFTPD
    (via proftpd.conf)


    The Configuration File
    The first step in configuring a proftpd daemon is knowing where the configuration file, usually named proftpd.conf, is located. The default location for this file is /etc/proftpd.conf or /usr/local/etc/proftpd.conf, depending on your installation. When starting the daemon, the exact path to the configuration file to be used can always be specified using the -c command-line option.

    The idea behind proftpd's handling of the configuration file is that a blank file can be used, and the daemon will still operate. This means that, unlike Apache, there is a "default" server configuration in every proftpd.conf; ProFTPD does not require that all server configurations be explicitly written in the proftpd.conf file. This default server attempts to bind to the IP address of the hostname indicated by the hostname(1) command.

    Configuration Format
    The format of the proftpd.conf file is deliberately designed to resemble the format used by Apache: lines of configuration directives contained with different contexts. A list of the configuration directives for ProFTPD is available here:

      http://www.proftpd.org/docs/
    
    When reading the description for the configuration directives, this key might be useful:
      http://www.castaglia.org/proftpd/doc/contrib/configuration-directive-key.html
    
    It describes the description format, and lists the different contexts in the configuration file. The "server config" context is the one in which most of your configuration directives will most likely be placed.

    Two new configuration directives were introduced in 1.2.6rc1: <IfModule> and <IfDefine>. These work exactly like Apache's directives of the same names, providing the ability to have conditional sections in the configuration file.

    Starting the Daemon
    One of the first decisions you will need to make is whether you will be running your ProFTPD server as an inetd service, or as a standalone server. This is controlled in the proftpd.conf using the ServerType configuration directive (see the ServerType page).

    Server Identity
    The daemon must be started with root privileges in order to do things like binding to port 21 and chrooting FTP sessions. However, it is not a good idea to leave a long-lived process running as root. The User and Group configuration directives are thus recommended. These directives configure the identity to which the daemon will switch, after accomplishing its startup tasks. The daemon will switch to the configured User and Group in the "server config" context. (Note that this switch uses the effective UID/GID, not the real UID/GID. Some programs, such as top, will continue to report proftpd as running as root; this is because the program displays the real UID/GID of processes. The proftpd daemon retains root privileges for operations such as chroots and binding to port 20 for active data transfers. If you wish proftpd to drop all root privileges, use the RootRevoke configuration directive.)

    For this reason, it is recommended that a non-privileged identity be used. Many sites choose to use user nobody. Historically, this role account was used by NFS-related processes; over time, many other applications default to using user nobody. This has the side-effect of adding to the "privileges" held by user nobody, in terms of files owned and/or accessible by that user. Instead, I personally recommend that a new role account be created for use specifically by the daemon, a user ftpd, and perhaps even a group ftpd. Many systems that run Apache have a user www or user apache for use by the httpd daemon; similarly, a separate user should be created for the proftpd daemon.

    In the default configuration file that accompanies the proftpd source code, there appears:

      User nobody
      Group nogroup
    
    When trying to start the daemon, many users encounter the "no such group 'nogroup'" error message. There are really no reasonable defaults for those directives. The error message is a way of telling you to create the role accounts mentioned above.

    For every connection, proftpd creates a new process to handle that client/connection. Once that client has successfully authenticated, then that process switches to the identity/privileges (e.g. UID, primary and supplemental GIDs, etc) of the authenticated user. Thus all browsing, uploads, and downloads that clients do happen as the user as which they are logged in.

    Logging in
    By default, the proftpd daemon reads the host's /etc/passwd file for logging in users. This means that to add FTP users, you simply need to create new system accounts for those users in your /etc/passwd file.

    Sometimes, though, sites want "virtual", FTP-only users. In order to support such configurations, the AuthUserFile configuration directive can be used (see here for details).

    For the purpose of authenticating users using other means, there are various authentication modules: mod_sql, mod_ldap, mod_radius, etc. Authentication and the login process is discussed here in more detail.

    For setting up anonymous logins, there is the <Anonymous> configuration context. If there are no <Anonymous> sections in your proftpd.conf, then no anonymous logins will be allowed - simple. As mentioned in the description, the User directive in an <Anonymous> context determines what username is treated as an anonymous login. The main other thing to know about anonymous logins is that ProFTPD automatically chroots anonymous logins.

    For normal, non-anonymous logins, jails/chroots are configured using the DefaultRoot directive. This is the configuration directive used to restrict users to their home directories, to keep them from browsing around the site. There is a page covering chrooting here.

    If you use <VirtualHost> sections, and it seems that your server configuration is not being seen by connecting clients, you might need to check that, if using a DNS name instead of an IP address in your <VirtualHost> line, that name resolves to an IP address different from that of the "default" server. Many people new to ProFTPD get the impression that since the configuration syntax looks similar to Apache's, things like name-based virtual hosting will work as well. Unfortunately, this is not possible. It is not a limitation in ProFTPD, but rather in the RFCs that define FTP. See the virtual server page for more information.

    As a workaround, some sites configure virtual servers to run on non-standard ports, using the Port configuration directive. As long as the clients are aware of the non-standard port, this scheme works well. One minor little caveat to keep in mind, when using this approach, is the numbers used: the RFCs mandate that the daemon, for the purposes of active data transfers (as opposed to passive) use port L-1 as the source port for the data connection, where L is the port number at which the client contacted the server. This means that servers that use the standard port 21 for FTP will use port 20 as the source port for their active data transfers. Passive data transfers do not have this restriction. The restriction comes into play when choosing non-standard port numbers for virtual hosts. For example, this configuration would cause problems for clients of the second virtual server that wanted to use active data transfers:

      <VirtualHost a.b.c.d>
        Port 2121
        ...
      </VirtualHost>
    
      <VirtualHost a.b.c.d>
        Port 2122
        ...
      </VirtualHost>
    
    The second virtual would attempt to use port 2121 as the source port for an active data transfer, but would be blocked, as the first virtual server is already using that port for listening.

    Access Restrictions
    Many sites like to have specific directories for uploads, and other directories only for downloads; some sites like to allow downloads, but no browsing of directories or their contents. For configurations to achieve this, use combinations of the <Directory> and <Limit> configuration directives. There are separate pages that cover these configuration sections:

    Further Questions
    Hopefully this document answers some of your questions, or at least enough to get you started. In addition, you should take a look at some of the example configuration files. Once you are comfortable with the configuration file format, a reading of all the configuration directives' descriptions is recommended, especially if you plan on having more complex configurations. When trying to figure out why something is not working, make use of server debugging output.

    If you still have questions, the users mailing list is the best place to post them.


    Last Updated: $Date: 2009/09/04 22:26:49 $

    proftpd-dfsg-1.3.5~rc3/doc/howto/SSH.html0000644000175000017500000001237310035652602020002 0ustar frankiefrankie ProFTPD mini-HOWTO - Configuring ProFTPD for FTP over SSH

    Configuring ProFTPD for FTP over SSH


    IMPORTANT NOTICE: the original instructions listed on this page, based on http://www.proftpd.org/proftpd-l-archive/98-11/msg00066.html were incorrect, and did not lead to the proper encryption of the FTP control channel. Many, many thanks to Michael Jochimsen for pointing out the incorrect use of ssh port forwarding!

    Premise
    The File Transfer Protocol is an old protocol, and like many of the older protocols it was developed in a time when security was not of such a paramount concern. One aspect of FTP that reflects this is the transmission of passwords, used to prove to the server that the client is who they say they are, "in the clear", unencrypted, visible to any packet sniffer. Protocols like SSH, and its scp program, are replacing FTP as a means to securely transfer files among hosts.

    However, many people still prefer to use their standard FTP clients. What would be easiest would be a way to allow such clients to function while transparently providing the encryption necessary for today's networks. Can this be done? Yes - after a fashion. This document aims to describe how to tunnel FTP over an SSH channel, providing for secure transmission of the user's password.

    Client Configuration
    The trick to encrypting the password is to make use of ssh's local port forwarding capability. It works by creating a sort of proxy on the local host that listens to some high-numbered port. Any traffic sent to that port is encrypted, and forwarded to the configured remote address and port. (Note: the prior instructions' flaw was that the local port forwarding request was sent to localhost, rather than to the remote server, which effectively set up the encrypted channel between localhost and itself). Here's how to set up a local port forward:

      ssh -Llocal-port:remote-addr:remote-port user@host
    
    This says to listen on port local-port on localhost, and to send that encrypted traffic to host's remote-addr at port remote-port. To use this trick to secure an FTP session (to be specific, the control channel, through which passwords are transmitted, will be encrypted; the data channel will not), it would look like:
      ssh -f -L3000:ftpserver:21 ftpserver 'exec sleep 10' && ftp localhost 3000
    
    Note that the choice of local-port is arbitrary. Using port 3000 is not a requirement. This trick also requires that the ftp client use passive mode data transfers, so make sure to use a client that understands FTP passive mode.

    Remember that only the control connection is encrypted, not the data connection: any data you transfer (e.g. directory listings, files uploaded or downloaded) are still sent "in the clear". Your password (and the other FTP commands sent by the client) is not.

    Server Configuration
    The server side of the connection needs some configuration to make the ssh tunneling work as well. First, the client need a valid account on the remote host is necessary in order to support the ssh tunnel. A valid shell is not strictly necessary for these ssh tunnels, though; something like:

      #!/bin/sh
      sleep 10
    
    would suffice. This would prevent the FTP users from logging in, yet give them enough time to establish a port forwarded ssh connection. With this sort of quasi-shell (although, strictly speaking, there are better, more restrictive shells than this example, as it could be escaped from), one can ssh over any command:
      ssh -l test -f -L3000:ftpserver:21 ftpserver true && ftp localhost 3000
    
    You'll also need to use the AllowForeignAddress configuration directive in your configuration file:
       AllowForeignAddress on
    
    or proftpd will reject the passive transfer connections and log:
      SECURITY VIOLATION: Passive connection from {host} rejected
    

    Note that the use of the server host's DNS name, or its IP address, in the setting up of the ssh tunnel assumes that the routing of traffic to the host's own IP address will be short-circuited in the kernel and thus not actually be transmitted on the wire. On modern kernels this is a fair assumption, but may not always be the case. For the truly paranoid, use of localhost or 127.0.0.1 as the remote-addr parameter in the ssh tunnel command would cause traffic on host to be sent over its loopback address, and not over the network. However, this will prevent data transfers from working altogether. The author has a patch for scenarios like this; if interested, please contact him directly via email.


    Last Updated: $Date: 2004/04/10 02:01:38 $

    proftpd-dfsg-1.3.5~rc3/doc/howto/ASCII.html0000644000175000017500000000743111160745472020204 0ustar frankiefrankie ProFTPD mini-HOWTO - ASCII Transfers

    ProFTPD and ASCII Transfers


    Like most FTP servers (and clients), proftpd contains code specifically for handling files that are transferred in ASCII mode. RFC959 requires that when sending a file transferred in ASCII mode, the server (or client) must ensure that every carriage return (CR) character is followed by a line feed (LF) character. The receiving program then checks the file for these CRLF sequences and re-translates them into the native line-ending format for the host machine. This allows clients on platforms whose ASCII line ending is CRLF (e.g. Windows) to send those files to platforms whose ASCII line ending is LF (e.g. Unix), at the cost of complex handling of ASCII data in FTP.

    The FTP TYPE command is used by the client to tell the server which transfer type is to be used: A for ASCII, I for binary. For the LIST and NLST FTP commands, the data transfer is always done in ASCII mode. The other FTP commands are unaffected by the transfer mode, with two notable exceptions: REST and SIZE.

    Why should REST (for resuming a transfer) and SIZE (for determining the size of a file on the server) be affected? The REST command tells the server at which byte to begin transferring a file. Recall that since the server may have altered the bytes received from the client in ASCII mode, the offset used by the client may be in a different position of the file on the server. Similarly, in ASCII mode, the size of the file that the client will receive may be different than the actual size of the file on the server. For example, a Unix FTP server transferring a file in ASCII mode to a Windows FTP client will need to add CR characters, increasing the size of the file (from the server's point of view).

    Properly handling the SIZE command would require the server to scan the file in question and perform the translation logic, which is resource-intensive. It is an easy way for a malicious client to try a "denial of service" attack on the server, forcing the server to perform many time-consuming calculations needlessly. The REST command can be abused in the same fashion. ProFTPD thus does not perform ASCII translation when handling the REST and SIZE commands.

    An FTP client will usually use SIZE when it wants to resume downloading file. However, clients in general should not be resuming downloads in ASCII mode. Resuming downloads in binary mode is the recommended way.

    Frequently Asked Questions

    Question: The SIZE used to work, regardless of the ASCII/binary mode, in 1.2.10. Why was it changed?
    Answer: The restriction on the SIZE command first appeared in 1.3.0rc1.

    Prior to the restriction, the file size reported by proftpd via SIZE did not take into account any possible CRLF translation (as mandated by RFC959 for ASCII mode transfers); this means that the reported size could be misleading. The reported size might not match the actual number of bytes that a client might download. Now, proftpd would rather provide no answer at all to a SIZE over providing a wrong answer.


    $Date: 2009/03/20 16:58:34 $
    proftpd-dfsg-1.3.5~rc3/doc/howto/Debugging.html0000644000175000017500000003103712056517610021242 0ustar frankiefrankie ProFTPD mini-HOWTO - Debugging

    Debugging Problems


    Users of ProFTPD will often encounters problems. It happens with all software, not just ProFTPD. How, then, does the user track down the cause of the problem, and fix it? This is the art of debugging. When users post these problems are the mailing lists, it is extremely helpful to include the following bits of information to help find the answer. Even better is when the user follows these steps and determines the solution for themselves.

    Keep in mind that proftpd runs on quite a few different platforms, including Linux (and its various distributions), Solaris, Mac OSX, various BSDs, etc. So please, when reporting issues, include as much information as you can. Saying something like "latest Ubuntu/CentOS/Fedora", or "stable Debian", or "FreeBSD ports", does not mean that much to those of us who don't run/use those platforms.

    We want to help you, but to do that, we need to know as many details as possible. One goal is for us to be able to reproduce the issue locally. That's why providing the `proftpd -V' output, and the proftpd.conf, the debug logging, and a description of the behavior you expect (as well as what you actually observed) is so important. These things help us to recreate the setup, and the circumstances, locally. And once we can see the same issue on our machines, we can help that much more rapidly with the solution.

    You will hear requests for these details come up quite a bit. It's worth pointing out why that is.

    Know the Version
    Various problems afflict various versions of the code, so when tracking down problems, it is good to know the version being used:

      proftpd -V
      proftpd -vv
    
    When reporting issues, please include the output from both of these commands.

    It is possible that the problem you are encountering is due to some bug that may already be fixed in a more current version, fixed in the CVS repository, or has a bug report with an attached patch. Searching http://bugs.proftpd.org will often yield useful information, depending on the keywords used in the search.

    Know the Modules
    System administrators who compile and install the server from the souce code distribution will probably already know this, but administrators who install using RPMs or other package formats may not know the specifics of the contained pre-built binary. To list the modules compiled into the server:

      proftpd -l
    
    Knowing the modules helps to pinpoint the source of error messages (e.g. mod_tls and certificate files).

    Perform Configuration Check
    When making changes to the configuration file, it is often helpful to make sure that your changes are valid. The easiest way to do this is to do an informative syntax check:

      proftpd -td10
    
    The -t option directs the server to only do a syntax check, to parse the configuration file but stop before actually starting its operations as a server. The -d10 will cause the server to display debugging messages during this testing of the configuration file. Another useful command is:
      proftpd -c /path/to/new/config/file -td10
    
    which lets you test the syntax of some new configuration file before it is put into production. If you are still having problems, and you have verified that your proftpd.conf is correct, the next step is see what debugging messages are generated during an FTP session, as described next.

    Collect Debug Information
    proftpd has built-in debug information reporting capabilities - the trick is in enabling that reporting, and tracking down where it is sent. The easiest way to get the debugging information is to start the server from the command line using:

      proftpd -nd10
    
    Note: make sure that no other proftpd instances are running before using this command, otherwise you will see:
      Failed binding to 0.0.0.0, port 21: Address already in use
    
    This message means that some other program is already bound to the socket at that address/port. This message will also appear if you attempt the debugging command with a ServerType of inetd; this is described below.

    Once working, the above debugging command will display lots of information on the connected terminal's screen, both as the server starts up and during the servicing of any clients. If clients are having trouble logging in or authenticating, the debug messages reported by the server when a client connects are much more useful than knowing the messages displayed by the client, as the client does not know why it cannot log in. If asked to send debugging information to the mailing list, you can send the relevant snippets (if you know what the relevant debug messages are), or you can capture the debug output to a file:

      proftpd -nd10 2>&1 >& /path/to/debug/file
    
    and send that file, compressed, along with your post.

    The above method works if you have ServerType standalone in your configuration file. If you run the server in inetd mode instead, and are unable or unwilling to make the changes necessary to run the server in standalone mode for the sake of debugging, then use of the SystemLog configuration directive is necessary for capturing the debug information. Add this directive to your configuration file, and add -d5 to your /etc/inetd.conf's ftp line, or to the server_args tag in your xinetd configuration file for the server. Be sure to restart inetd/xinetd so that your configuration changes will take effect.

    Note that use of the SystemLog directive is not necessarily confined to inetd mode servers. If you are interested in letting your standalone server run unattended and want to have that debugging information in the log file, use SystemLog and add -d5 (or whatever your preferred debug level is) to the server startup script.

    As of version 1.2.8rc1, ProFTPD supports a DebugLevel configuration directive. This lets you set a debugging level in your proftpd.conf file, without needing to edit inetd.conf or xinetd configuration file.

    Locate Log Files
    A common response on the mailing lists to a posted question is: "What do your server logs say?" Locating the server's log files can be troublesome, depending on your configuration. If the SystemLog configuration directive is in effect, you know exactly where the server's log file is. If not, then by default the server uses syslog for logging. The location of syslog'd log files is set in your system's /etc/syslog.conf file. You may need to read your system's man pages for syslog.conf or syslogd to understand the format of that file. Note that the server will log using a syslog facility of daemon (and level debug when debugging) for most of its messages; during authentication, messages are logged using the authpriv facility.

    Debugging Segfaults
    If you see a message like the following in your logs:

      golem.castaglia.org (127.0.0.1[127.0.0.1]) - ProFTPD terminating (signal 11)
    
    then you have most likely encountered a segfault. This is a particular bad error, and can be hard to track down.

    In version 1.3.1rc1, ProFTPD gained the ability to provide better logging to help track down these sorts of bugs. To enable this ability, you will need to configure proftpd with something like:

      ./configure --enable-devel=stacktrace ...
    
    and run your proftpd like normal. If a segfault occurs, the logs should show something like this:
      golem.castaglia.org (127.0.0.1[127.0.0.1]) - ProFTPD terminating (signal 11)
      golem.castaglia.org (127.0.0.1[127.0.0.1]) - FTP session closed.
      golem.castaglia.org (127.0.0.1[127.0.0.1]) - -----BEGIN STACK TRACE-----
      golem.castaglia.org (127.0.0.1[127.0.0.1]) - [0] ./proftpd [0x809b1e1]
      golem.castaglia.org (127.0.0.1[127.0.0.1]) - [1] ./proftpd(call_module+0x53) [0x8072c63]
      golem.castaglia.org (127.0.0.1[127.0.0.1]) - [2] ./proftpd(strftime+0x14cf) [0x8051bef]
      golem.castaglia.org (127.0.0.1[127.0.0.1]) - [3] ./proftpd(pr_cmd_dispatch+0x167) [0x8051f2f]
      golem.castaglia.org (127.0.0.1[127.0.0.1]) - [4] ./proftpd(strftime+0x1fd3) [0x80526f3]
      golem.castaglia.org (127.0.0.1[127.0.0.1]) - [5] ./proftpd [0x8053e12]
      golem.castaglia.org (127.0.0.1[127.0.0.1]) - [6] ./proftpd [0x805484d]
      golem.castaglia.org (127.0.0.1[127.0.0.1]) - [7] ./proftpd [0x8057975]
      golem.castaglia.org (127.0.0.1[127.0.0.1]) - [8] ./proftpd(main+0x9d1) [0x8058625]
      golem.castaglia.org (127.0.0.1[127.0.0.1]) - [9] /lib/i686/libc.so.6(__libc_start_main+0x93) [0x40076507]
      golem.castaglia.org (127.0.0.1[127.0.0.1]) - [10] ./proftpd(strcpy+0x31) [0x8051001]
      golem.castaglia.org (127.0.0.1[127.0.0.1]) - -----END STACK TRACE-----
    
    These stack symbols are generated automatically by glibc, and may or may not contain the function names.

    The key here for tracking down the location of the segfault is that [0] frame, and the memory address: 0x809b1e1. Using that address and a very handy command called addr2line, you can determine the location of that address in the source code:

      addrline -e ./proftpd 0x809b1e1
    
    In this example, I saw:
      golem/tj>addr2line -e ./proftpd 0x809b1e1
      /home/tj/proftpd/cvs/proftpd/modules/mod_auth.c:1723
    
    which is the location of test code added to trigger the segfault.

    This feature is specific to glibc systems, so keep that in mind. Other things to mention about this feature: it disables the changing of the process title that proftpd normally does. The obtaining of the stack symbols that glibc does uses the process title, and if this feature did not disable that process title changing, the output would be much less legible. Also, it does not work if the process which receives the SIGSEGV signal is chrooted. (Blame glibc for its bad handling of being chrooted.) To work around this, I would recommend using the mod_vroot module, just for a short period of time, in order to get a useful automatic stack trace.

    Common Problems
    One common question is: "I changed the configuration file, but the new configuration is not being seen!" The solution depends on your configured ServerType. Almost certainly it will be standalone, as inetd-mode servers pick up configuration changes almost instantly (the server is started from the ground up for each connection). For configuration changes to be seen by a standalone server, you need to either stop, then start the server (the hard way), or to send the HUP signal the the daemon process.

    Another common question involves use of ProFTPD's <Limit> directive to restrict certain FTP commands. These limits always function in addition to the normal filesystem permissions, not instead of them. If having problems writing, deleting, or updating files, check your directory and file permissions first.

    Once you have the debug output and various other information, and are still in need of help, search the FAQ, Userguide, and mailing list archives for material related to the problem. If you're unable to find anything helpful in these sources, post your question to the appropriate mailing list. Be sure to include the version used, your proftpd.conf, and possibly any debug information.

    The following document describes how to ask good questions that are likely to be answered:

      http://www.catb.org/~esr/faqs/smart-questions.html
    


    Last Updated: $Date: 2012/12/02 00:23:36 $


    proftpd-dfsg-1.3.5~rc3/doc/howto/DSO.html0000644000175000017500000003566012035677237020013 0ustar frankiefrankie ProFTPD mini-HOWTO - Dynamic Shared Objects

    Dynamic Shared Objects


    What are DSOs?
    DSOs (Dynamic Shared Objects) are specially built binary files that can be loaded by an application while it is running, extending the functionality of the application on-the-fly. One of the best known applications that makes use of DSOs is the Apache web server; see the Apache documentation for an in-depth description of DSOs:

      http://httpd.apache.org/docs/dso.html
    

    DSOs and ProFTPD
    ProFTPD gained the ability to use DSOs starting with the 1.3.0rc1 release. To make sure the compiled proftpd binary can load DSO modules, use the --enable-dso configure option:

      ./configure --enable-dso ...
    
    This causes the build system to build the libltdl supporting library, which is used to handle OS-specific ways of loading and unloading DSO files, and also to include the mod_dso module in the compiled proftpd. The mod_dso module provides the LoadModule configuration directive, for loading modules via the proftpd.conf configuration file.

    The contrib modules that are distributed with the ProFTPD source, e.g. mod_ldap, mod_sql, mod_quotatab, mod_ifsession, etc, can easily be built as DSO modules, rather than statically linked into the proftpd binary. Instead of using the normal --with-modules configure option, you use the --with-shared option:

      ./configure --enable-dso --with-shared=mod_sql:mod_sql_mysql --with-includes=... --with-libraries=...
    
    These DSO modules will be installed under the libexec/ directory of your ProFTPD install location. To control the location of this libexec/ directory from which the mod_dso module will load modules, you can use the --libexecdir configure option, e.g.:
      ./configure --libexecdir=/path/to/custom/libexec --enable-dso ...
    

    Note that ProFTPD uses the GNU libtool utility for creating shared modules. This tool creates files with .la file extensions. It is these .la files that will be installed into the libexec/ directory. This differs from the .so files that Apache's DSO support generates, so do not be surprised.

    Loading Modules
    There are two ways to load DSO modules into proftpd: the LoadModule configuration directive, and the insmod ftpdctl action. Note that the latter possibility is only available if your proftpd has been built with Controls support.

    Loading a module using LoadModule is quite simple. Simply use the directive at the top of your proftpd.conf file, which makes sure the module is loaded by proftpd before it processes other directives:

      LoadModule mod_sql.c
      LoadModule mod_sql_mysql.c
      ...
    
      <IfModule mod_sql.c>
        ...
      </IfModule>
    
    If a module fails to load properly, you might see messages like:
      Fatal: unknown configuration directive 'SQLConnectInfo' on line 86 of '/usr/local/proftpd/etc/proftpd.conf'
    
    This can happen if you forget to use the LoadModule directive in your proftpd.conf prior to using directives from the module. If you are using LoadModule, the error message may look like:
      LoadModule: error loading module 'mod_sql_mysql.c': permission denied on line 65 of proftpd.conf
    
    Check the libexec/ directory where you installed proftpd, to see if the appropriate .la and/or .so files are present. Then check your dynamic loader configuration file (e.g. /etc/ld.so.conf on Linux) and make sure that the libexec/ directory is configured, so that the dynamic loader knows to look in the correct locations. Note that the LD_LIBRARY_PATH and/or LD_RUN_PATH environment variables may also be used to inform the dynamic loader of proftpd's libexec/ directory.

    Using ftpdctl insmod to load modules is tricky, as the loading of a module directly into the running proftpd, without restarting the server, can cause unexpected behavior. Many modules are not designed to handle being loaded directly, and may cause bugs or unexpected crashes. Support for this mode of loading modules will stabilize as the modules are updated properly.

    Module Ordering
    Is the order in which your LoadModule directives appear in proftpd.conf important? The short answer is: maybe. It depends on the modules. Some modules are self-sufficient, do not make use of any other modules, and so can appear in any orders. Others, like mod_sql_mysql or mod_quotatab_sql, require that the frontend module (e.g. mod_sql or mod_quotatab) be loaded first. Still others, like mod_ifsession, do not directly require other modules, yet they have effects that are dependent on the order; mod_ifsession works best when it is the last module loaded.

    To achieve the necessary module order, you can make sure that your LoadModule directives appear in the correct order, or you can use the ModuleOrder directive. Note that using ModuleOrder can be difficult, as it is very easy to use ModuleOrder to configure a nonfunctional proftpd.

    Compiling Custom Modules as DSOs
    The --with-shared configure option can be used to build DSOs from the modules already distributed with ProFTPD, but what about building a custom ProFTPD module as a DSO? Right now, this requires the ProFTPD source, and not just an installed ProFTPD.

    Once you have your custom module written (e.g. mod_custom.c), you create the Makefile that will be used to compile it as a DSO module. The following can be used as a template for the Makefile:

      PROFTPD_INSTALL=/usr/local/proftpd
    
      top_srcdir=$(PROFTPD_INSTALL)
      srcdir=$(PROFTPD_INSTALL)
      VPATH=$(PROFTPD_INSTALL)
    
      MODULE_NAME=
      MODULE_CFLAGS=
      MODULE_DEFS=
      MODULE_LDFLAGS=
      MODULE_LIBS=
    
      CC=gcc
      DEFS=-DPR_SHARED_MODULE $(MODULE_DEFS)
      CFLAGS=$(DEFS) -I. -I$(PROFTPD_INSTALL)/include/proftpd $(MODULE_CFLAGS)
      LDFLAGS=-L$(PROFTPD_INSTALL)/lib $(MODULE_LDFLAGS)
      LIBEXEC_DIR=$(PROFTPD_INSTALL)/libexec
      LIBS=$(MODULE_LIBS)
    
      INSTALL=/usr/bin/install -c
      INSTALL_BIN=$(INSTALL) -s -m 0755
    
      LIBTOOL=$(SHELL) /usr/bin/libtool
      LTDL_FLAGS=-avoid-version -export-dynamic -module
    
      # Targets
    
      all: $(MODULE_NAME).la
    
      $(MODULE_NAME).lo:
              $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c $(MODULE_NAME).c
    
      $(MODULE_NAME).la: $(MODULE_NAME).lo
              $(LIBTOOL) --mode=link $(CC) -o $(MODULE_NAME).la -rpath $(LIBEXEC_DIR) $(LDFLAGS) $(LTDL_FLAGS) $(MODULE_NAME).lo $(LIBS)
    
      install: $(MODULE_NAME).la
              if [ -f $(MODULE_NAME).la ] ; then \
                      $(LIBTOOL) --mode=install $(INSTALL_BIN) $(MODULE_NAME).la $(DESTDIR)$(LIBEXEC_DIR) ; \
              fi
    
      clean:
              $(LIBTOOL) --mode=clean $(RM) $(MODULE_NAME).la $(MODULE_NAME).lo config.*
    
      distclean:
              $(RM) Makefile config.*
              $(RM) -r autom4te.cache
    
    Fill in MODULE_NAME with the name of your module:
      MODULE_NAME=mod_custom
    
    The remaining MODULE_ variables are used to specify additional compiler and linker flags. If, for example, your mod_custom.c module relied on a header file <custom.h> as well as a library libcustom.so, you might have the following:
      MODULE_CFLAGS=-I/path/to/custom/include
      MODULE_DEFS=-DUSE_LIBCUSTOM
      MODULE_LDFLAGS=-L/path/to/custom/lib
      MODULE_LIBS=-lcustom
    
    Place the Makefile in a directory with your mod_custom.c source file, then do:
      make
      make install
    
    The make install step will install the DSO module into the libexec/ directory of your ProFTPD install location.

    Once installed, update your proftpd.conf to make sure your module is loaded:

      LoadModule mod_custom.c
    
    Then restart proftpd, and your custom module will be in use.

    Using prxs
    You may find yourself wanting to compile some third-party module, for which you have the source code, as a DSO module for proftpd. But you may not have the source code for proftpd, e.g. you might have installed proftpd as a binary package. The build system for proftpd would let you compile your third-party module as a DSO module, but what do you do if you don't have access to the proftpd build system?

    The answer is to use the prxs script, which comes with proftpd. The prxs (PRoFTPD EXtensionS) tool will compile and install third-party modules, from source code, as DSO modules for your installed proftpd.

    The prxs tool supports the following actions:

     -c, --compile          Compiles the listed .c source files
                            into a proftpd DSO module.
    
     -i, --install          Installs a compiled proftpd DSO module into the
                            directory where proftpd expects to find loadable
                            DSO modules.
    
     -d, --clean            Removes any generated files, returning the build
                            directory to a clean state.
    
    At least one of the above actions must be specified when using prxs. More than one action can be specified at the same time.

    To use prxs all in one step, you could do:

      # prxs -c -i -d mod_custom.c
    
    which will do the compile, install, and clean actions in order. Once installed, update your proftpd.conf to make sure your module is loaded:
      LoadModule mod_custom.c
    
    Then restart proftpd, and your custom module will be in use.

    For example, you might use prxs to compile the mod_sql_sqlite module like so, from the top level of the ProFTPD source directory:

      # prxs -c -i -d contrib/mod_sql_sqlite.c
    

    The following options are also supported:

     -n, --name             Tells prxs the name of the module being compiled.
                            By default, prxs determines the module name from
                            the list of .c files listed, expecting to see a
                            "mod_name.c" file.
    
     -D key                 Passes these macros through to the compilation step.
     -D key=value           Note that the space before the key is important.
    
     -I includedir Specify additional include file search directories.
                            Note that the space before the directory is important.
    
     -L libdir     Specify additional library file search directories.
                            Note that the space before the directory is important.
    
     -l library    Specify additional libraries for linking.
                            Note that the space before the library name is important.
    

    Using prxs, the above mod_custom example would become:

      # cd /path/to/mod_custom/dir
      # prxs -c -i -D USE_CUSTOM -I /path/to/custom/include -L /path/to/custom/lib -l custom mod_custom.c
    
    That's it! No need for a special Makefile, and no need to edit/replace any variables.

    The prxs tool uses the libtool command that your system should support. If you need to tell prxs to use a different libtool for any reason (such as using a specially installed libtool), you can use the LIBTOOL environment variable to point prxs to the libtool to use. For example:

      # LIBTOOL=/path/to/custom/libtool prxs -c -i -d mod_custom.c
    

    When should you use prxs for compiling DSO modules, and when should you use a Makefile? In general, if the third-party module comes with its own configure script and Makefile, then you should use those. Otherwise, prxs should suffice.

    Frequently Asked Questions
    Question: My installed proftpd does not include mod_sql_passwd (or some other module). How can I get proftpd to use this module without recompiling?
    Answer: First, see if your proftpd package came with the
    prxs tool; by default, this tool is installed as /usr/local/bin/prxs. If you do not find prxs anywhere on your system, you will have to recompile proftpd in order to add new modules.

    Second, you will need the source code for mod_sql_passwd (or whatever other module you want to add to your proftpd). Assume, then, that you have found the mod_sql_passwd.c source file. The next step is to use prxs to build that module as a DSO module:

      # /usr/local/bin/prxs -c -i -d mod_sql_passwd.c
    
    If the above fails with this error message:
      Your installed proftpd does not support shared modules/DSOs.
      Make sure the --enable-dso configure option is used when
      compiling proftpd.
    
    It means that your proftpd does not have DSO support -- and that means that you will have to recompile proftpd to add the new module.

    If, on the other hand, your prxs succeeded, the last steps are to update your proftpd.conf to load the new module, and then restart proftpd so that it reads the updated configuration. Continuing with the example of mod_sql_passwd, you would add the following line near the top of your proftpd.conf:

      LoadModule mod_sql_passwd.c
    
    and later in the config file, configure your newly added module:
      <IfModule mod_sql_passwd.c>
        SQLPasswordEngine on
        ...
      </IfModule>
    
    Last, restart proftpd, and enjoy your new module's functionality, all without needing to recompile/reinstall proftpd itself.


    $Date: 2012/10/12 02:21:19 $
    proftpd-dfsg-1.3.5~rc3/doc/howto/Regex.html0000644000175000017500000005405210322030553020411 0ustar frankiefrankie Regular Expressions Tutorial

    Found at: http://publish.ez.no/article/articleprint/11/

    Regular Expressions Explained



    This article will give you an introduction to the world of regular expressions. I'll start off with explaining what regular expressions are and introduce their syntax, then some examples with varying complexity.

    Concept

    A regular expression is a text pattern consisting of a combination of alphanumeric characters and special characters known as metacharacters. A close relative is in fact the wildcard expression which are often used in file management. The pattern is used to match against text strings. The result of a match is either successful or not, however when a match is successful not all of the pattern must match, this is explained later in the article.

    You'll find that regular expressions are used in three different ways: Regular text match, search and replace and splitting. The latter is basicly the same as the reverse match i.e. everything the regular expression did not match.

    Regular expressions are often simply called regexps or RE, but for consistency I'll be referring to it with its full name.

    Due to the versatility of the regular expression it is widely used in text processing and parsing. UNIX users are probably familiar with them through the use of the programs, grep, sed, awk and ed. Text editors such as (X)Emacs and vi also use them heavily. Probably the most known use of regular expressions are in the programming language Perl; you'll find that Perl sports the most advanced regular expression implementation to this day.

    Usage

    Now you're probably wondering why you should bother to learn regular expressions. Well if you're a normal computer user your benefits from using them are somewhat small, however if you're either a developer or a system administrator you'll find that knowing regular expressions will make your (professional) life so much better.

    Developers can use them to parse text files, fix up code and other wonders. System administrators can use them to search through logs, automate boring tasks and sniff the network traffic for unauthorized activity.

    Actually I would go so far as to say it's a crime for a System Administrator not to have any knowledge of regular expressions.

    Quantifiers

    The contents of an expression are, as explained earlier, a combination of alphanumeric characters and metacharacters. An alphanumeric character is either a letter from the alphabet:

    abc

    or a number:

    123

    Actually in the world of regular expressions any character which is not a metacharacter will match itself (often called literal characters), however a lot of the time you're mostly concerned with the alphanumeric characters. A very special character is the backslash \, as this turns any metacharacters into literal characters, and alphanumeric characters into a sort of metacharacter or sequence. The metacharacters are:

    \ | ( ) [ { ^ $ * + ? . < >

    With that said normal characters don't sound too interesting so let's jump to our very first metacharacters.

    The punctuation mark, or dot, . needs explaining first since it often leads to confusion. This character will not, as many might think, match the punctuation in a line. It is instead a special metacharacter which matches any character. Using this where you wanted to find the end of the line, or the decimal in a floating number, will lead to strange results. As explained above, you need to backslashify it to get the literal meaning. For instance take this expression:

    1.23

    will match the number 1.23 in a text as you might have guessed, but it will also match these next lines:

    1x23
    1 23
    1-23

    to make the expression only match the floating number we change it to:

    1\.23

    Remember this, it's very important. Now with that said we can get the show going.

    Two heavily recurring metacharacters are:

    * and +

    They are called quantifiers and tell the engine to look for several occurrences of a character; the quantifier always precedes the character at hand. The * character matches zero or more occurrences of the character in a row, the + character is similar but matches one or more.

    So if you decided to find words which had the character c in it you might be tempted to write:

    c*

    What might come as a surprise to you is that you will find an enormous amount of matches, even words with no c in them will match. "How is this so?" you ask. Well, the answer is simple. Recall that the * character matches zero or more characters, and that's exactly what you matched, zero characters.

    You see, in regular expressions you have the possibility to match what is called the empty string, which is simply a string with zero size. This empty string can actually be found in all texts. For instance the word:

    go

    contains three empty strings. They are contained at the position right before the g, in between the g and the o and after the o. And an empty string contains exactly one empty string. At first this might seem like a really silly thing to do, but you'll learn later on how this is used in more complex expressions.

    So with this knowledge we might want to change our expression to:

    c+

    and voila we get only words with c in them.

    The next metacharacter you'll learn is:

    ?

    This simply tells the engine to either match the character or not (zero or one). For instance the expression:

    cows?

    will match any of these lines:

    cow
    cows

    These three metacharacters are simply a specialized scenario for the more generalized quantifier:

    {n,m}

    the n and m are respectively the minimum and maximum size for the quantifier. For instance:

    {1,5}

    means match one or up to five characters. You can also skip m to allow for infinite match:

    {1,}

    which matches one or more characters. This is exactly what the + character does. So now you see the connection, * is equal to {0,}, + is equal to {1,} and ? is equal to {0,1}.

    The last thing you can do with the quantifier is to also skip the comma:

    {5}

    which means to match 5 characters, no more, no less.

    Assertions

    The next type of metacharacters is assertions. These will match if a given assertion is true. The first pair of assertions are:

    ^ and $

    which match the beginning of the line, and the end of the line, respectively. Note that some regular expression implementations allows you to change their behavior so that they will instead match the beginning of the text and the end of the text. These assertions always match a zero length string, or in other words, they match a position. For instance, if you wrote this expression:

    ^The

    it would match any line which began with the word The.

    The next assertion characters match at the beginning and end of a word; they are:

    < and >

    they come in handy when you want to match a word precisely. For instance:

    cow

    would match any of the following words:

    cow
    coward
    cowage
    cowboy
    cowl

    A small change to the expression:

    <cow>

    and you'll only match the word cow in the text.

    One last thing to be said is that all literal characters are in fact assertions themselves. The difference between them and the ones above is that literal characters have a size. So for cleanliness sake we only use the word "assertions" for those that are zero-width.

    Groups and Alternation

    One thing you might have noticed when we explained quantifiers is that they only worked on the character to the left. Since this pretty much limits our expressions I'll explain other uses for quantifiers. Quantifiers can also be used on metacharacters; using them on assertions is silly since assertions are zero-width and matching one, two, three or more of them doesn't do any good. However the grouping and sequence metacharacters are perfect for being quantified. Let's first start with grouping.

    You can form groups, or subexpressions as they are frequently called, by using the begin and end parenthesis characters:

    ( and )

    The ( starts the subexpression and the ) ends it. It is also possible to have one or more subexpressions inside a subexpressions. The subexpression will match if the contents match. So mixing this with quantifiers and assertions you can do:

    ( ?ho)+

    which matches all of the following lines:

    ho
    ho ho
    ho ho ho
    hohoho

    Another use for subexpressions are to extract a portion of the match if it matches. This is often used in conjunction with sequences, which are discussed later.

    You can also use the result of a subexpression for what is called a back reference. A back reference is given by using a backslashified digit, a single non-zero digit. This leaves you with nine back references (0 through 9). The back reference matches whatever the corresponding subexpression actually matched (except that {article_contents_1} matches a null character). To find the number of the subexpression, count the open parentheses from the left.

    The uses for back references are somewhat limited, especially since you only have nine of them, but on some rare occasion you might need it. Note some regular expression implementations can use multi-digit numbers as long as they don't start with a 0.

    Next are alternations, which allow you to match on any of many words. The alternation character is:

    |

    A sample usage is:

    Bill|Linus|Steve|Larry

    would match either Bill, Linus, Steve or Larry. Mixing this with subexpressions and quantifiers we can do:

    cow(ard|age|boy|l)?

    which matches any of the following words but no others:

    cow
    coward
    cowage
    cowboy
    cowl

    I mentioned earlier in the article that not all of the expression must match for the match to be successful. This can happen when you're using subexpressions together with alternations. For example:

    ((Donald|Dolly) Duck)|(Scrooge McDuck)

    As you see only the left or right top subexpression will match, not both. This is sometimes handy when you want to run a complex pattern in one subexpression and if it fails try another one.

    Sequences

    Last we have sequences, which define sequences of characters which can match. Sometimes you don't want to match a word directly but rather something that resembles one. The sequence characters are:

    [ and ]

    Any characters put inside the sequence brackets are treated as literal characters, even metacharacters. The only special characters are - which denotes character ranges, and ^ which is used to negate a sequence. The sequence is somewhat similar to alternation; the similarity is that only one of the items listed will match. For instance:

    [a-z]

    will match any lowercase characters which are in the English alphabet (a to z). Another common sequence is:

    [a-zA-Z0-9]

    Which matches any lowercase or capital characters in the English alphabet as well as numbers. Sequences are also mixed with quantifiers and assertions to produce more elaborate searches. Example:

    <[a-zA-Z]+>

    matches all whole words. This will match:

    cow
    Linus
    regular
    expression

    but will not match:

    200
    x-files
    C++

    Now if you wanted to find anything but words, the expression:

    [^a-zA-Z0-9]+

    would find any sequences of characters which do not contain the English alphabet or any numbers.

    Some implementations of regular expressions allow you to use shorthand versions for commonly used sequences, they are:

    \d, a digit ([0-9])
    \D, a non-digit ([^0-9])
    \w, a word (alphanumeric) ([a-zA-Z0-9])
    \W, a non-word ([^a-zA-Z0-9])
    \s, a whitespace ([ \t\n\r\f])
    \S, a non-whitespace ([^ \t\n\r\f])

    Wildcards
    For people who have some knowledge with wildcards (also known as file globs or file globbing), I'll give a brief explanation on how to convert them to regular expressions. After reading this article, you probably have seen the similarities with wildcards. For instance:

    *.jpg

    matches any text which end with .jpg. You can also specify brackets with characters, as in:

    *.[ch]pp

    matches any text which ends in .cpp or .hpp. Altogether very similar to regular expressions.

    The * means match zero or more of anything in wildcards. As we learned, we do this is regular expression with the punctuation mark and the * quantifier. This gives:

    .*

    Also remember to convert any punctuation marks from wildcards to be backslashified.

    The ? means match any character but do match something. This is exactly what the punctuation mark does.

    Square brackets can be used untouched since they have the same meaning going from wildcards to regular expressions.

    These leaves us with:

    • Replace any * characters with .*
    • Replace any ? characters with .
    • Leave square brackets as they are.
    • Replace any characters which are metacharacters with a backslashified version.

    Examples

    *.jpg

    would be converted to:

    .*\.jpg

    ez*.[ch]pp

    would convert to:

    ez.*\.[ch]pp

    or alternatively:

    ez.*\.(cpp|hpp)

    Example Regular Expressions

    To really get to know regular expressions I've left some commonly used expressions on this page. Study them, experiment and try to understand exactly what they are doing.

    Email validity: will only match email addresses which are valid, such as "user@host.com":

    [a-z0-9_-]+(\.[a-z0-9_-]+)*@[a-z0-9_-]+(\.[a-z0-9_-]+)+

    Email validity #2: matches email addresses with a name in front, like "John Doe <user@host.com>":

    ("?[a-zA-Z]+"?[ \t]*)+\<[a-z0-9_-]+(\.[a-z0-9_-]+)*@[a-z0-9_-]+(\.[a-z0-9_-]+)+\>

    Protocol validity: matches web based protocols such as "htpp://", "ftp://" or "https://":

    [a-z]+://

    C/C++ includes: matches valid include statements in C/C++ files:

    ^#include[ \t]+[<"][^>"]+[">]

    C++ end of line comments:

    //.+$

    C/C++ span line comments (it has one flaw, can you spot it?):

    /\*[^*]*\*/

    Floating point numbers: matches simple floating point numbers of the kind 1.2 and 0.5:

    -?[0-9]+\.[0-9]+

    Hexadecimal numbers: matches C/C++ style hex numbers, e.g. 0xcafebabe:

    0x[0-9a-fA-F]+
    proftpd-dfsg-1.3.5~rc3/doc/howto/DisplayFiles.html0000644000175000017500000001536211750547225021747 0ustar frankiefrankie ProFTPD mini-HOWTO - Display Files


    ProFTPD's Display Files


    ProFTPD supports a number of configuration directives that specify a file whose contents should be displayed to connected clients at various times:

    • DisplayConnect
      Displayed to clients as soon as they connect
    • DisplayLogin
      Displayed to clients once they have logged in using the USER and PASS commands
    • DisplayChdir
      Displayed to a client whenever it changes into a directory
    • DisplayFileTransfer
      Displayed to the client whenever a file is successfully transfer, either uploaded or downloaded
    • DisplayQuit
      Displayed to a client when the session ends via the QUIT command

    Note the subtle difference between DisplayConnect and DisplayLogin. A DisplayConnect file will be displayed to all clients; this makes it suitable for server banners, messages of the day, etc. A DisplayLogin file will only be displayed once the client has logged in.

    The configured file paths can be either relative or absolute (except in the case of DisplayConnect, which always requires absolute paths). In the case of a relative path, the file is assumed to be in the starting directory a user, i.e. the <Anonymous> directory for anonymous logins, and the user's home directory for non-anonymous logins. Note: If DefaultRoot is in effect, then the file must reside inside the chrooted directory. If the configured file cannot be found or accessed, no error occurs and nothing is logged or displayed to the client.

    Display Variables
    The following table contains the variables that can be used in Display files. Be aware that not all of these may have a rational value, depending on the context in which they are used (e.g., %u if IdentLookups are off).

    Other contrib modules may provide additional variables for use as well; please consult their documentation for more information.

    Variable Meaning
    %C Current working directory
    %E Server admin's email address
    %F Available space on file system, in bytes
    %f Available space on file system, with units
    %i The number of files uploaded (input) in this session
    %K Total number of bytes transferred
    %k Total number of bytes transferred, in units
    %L Local hostname
    %M Maximum number of connections
    %N Current number of connections
    %o The number of files downloaded (output) in this session
    %R Remote hostname
    %T Current time
    %t The number of files transferred (uploaded and downloaded) in this session
    %U Username originally used to login
    %u Username reported by ident protocol
    %V ServerName of virtual host, if any
    %x The name of the user's Class, if any
    %y Current number of connections from the user's Class
    %z Maximum number of connections from the user's Class
    %{total_bytes_in} The number of bytes uploaded (input) in this session
    %{total_bytes_out} The number of bytes downloaded (output) in this session
    %{total_bytes_xfer} The number of bytes transferred (uploaded and downloaded) in this session
    %{total_files_in} The number of files uploaded (input) in this session
    %{total_files_out} The number of files downloaded (output) in this session
    %{total_files_xfer} The number of files transferred (uploaded and downloaded) in this session
    %{env:name} The value of the environment variable name
    %{time:format} Uses format (as per the strftime(3) function) to format a timestamp

    Frequently Asked Questions

    Question: I configured a path which contains spaces for DisplayLogin, and it doesn't work. Why not?
    Answer: If using paths/files which contains spaces, make sure that you enclose the path in quotation marks, e.g.:

      DisplayLogin "/path/to/display login.txt"
    
    Otherwise, the configuration file parser will treat the space-separated portions of the path as separate directive parameters.

    Question: I configured a DisplayLogin file which uses the %F variable, but it is not showing me the correct amount of bytes available on my system. Why not?
    Answer: ProFTPD determines the available bytes for the %F/%f variables based on the filesystem containing the Display file.

    For example, if your Display file is in /etc/proftpd,, and the /etc directory is mounted on a small disk, then %F/%f will only report on the bytes available in the /etc filesystem, not on other filesystems (e.g. not the /home filesystem).


    $Date: 2012/05/03 18:29:41 $
    proftpd-dfsg-1.3.5~rc3/doc/howto/Chroot.html0000644000175000017500000003332411547151252020606 0ustar frankiefrankie ProFTPD mini-HOWTO - Symlinks and chroot()

    DefaultRoot, Symlinks and chroot()


    Restricting Users' Directories
    One of the most common questions for new users of ProFTPD is "How do I restrict my users to only certain directories?" or, phrased another way, "How can I put my users in a chroot jail?" As a common question, it definitely has a place in the
    FAQ. Many users, I fear, do not read the FAQ carefully, and so miss that section. The answer is ProFTPD's DefaultRoot configuration directive, which accomplishes this functionality by using the chroot(2) function.

    This configuration directive may appear in the <VirtualHost>, <Global>, and the "server config" (meaning not in any <VirtualHost> or <Global> sections) configuration contexts. The most common configuration requested is to restrict users to their home directories, which can be done simply by adding the following line to your proftpd.conf:

      DefaultRoot ~
    
    The ~ (tilde) is a Unix-ism that is expanded to the logging-in user's home directory. For slightly more complex setups, administrators may want to restrict only a subset of their users into home directories (or some other directory), but leave some privileged users unrestricted. For example, say you have your privileged users all as members of a group called ftp-special. The DefaultRoot's optional second parameter, a group-expression, can then be used, like so:
      DefaultRoot ~ !ftp-special
    
    This says to chroot() every user who is not a member of group ftp-special to their respective home directory, and:
      DefaultRoot /path/to/dir group1,group2
    
    will chroot() users who are members of both group1 and group2 into /path/to/dir. More complex group-expressions can be used as needed.

    Note that the execute bit (--x) must be on in order to chroot() a user into that directory. This bit is also needed for a user to be able to chdir into that directory.

    Symlinks
    There have been many questions on the ProFTPD user mailing list about why symlinked directories are not visible to chrooted users (this includes <Anonymous> users as well as users restricted using DefaultRoot. This document is intended to clarify the issues and discuss some ways of achieving what is commonly desired.

    These issues are not specific to ProFTPD, but rather to the workings of a Unix system. First, a brief review of how links work, and why chroot(2) poses such a problem. Then a look at ways around the issue.

    How Links Work
    There are two types of links in Unix: hard and symbolic.

    A hard link is a file that is, for all intents and purposes, the file to which it is linked. The difference between a hardlink and the linked file is one of placement in the filesystem. Editing the hardlink edits the linked file. One limitation of hard links is that linked files cannot reside on different filesystems. This means that if /var and /home are two different mount points in /etc/fstab (or /etc/vfstab), then a file in /var/tmp cannot be hardlinked with a file in /home:

      # pwd
      /var/tmp
      # ln /home/tj/tmp/tmpfile tmplink
      ln: cannot create hard link `tmplink' to `/home/tj/tmp/tmpfile': Invalid cross-device link
    
    A symbolic link (also referred to as a "symlink") is a file whose contents contain the name of the file to which the symbolic link points. For example:
      lrwxrwxrwx   1 root     root           11 Mar  2  2000 rmt -> /sbin/rmt
    
    The file rmt contains the nine characters /sbin/rmt. The reason symbolic links fail when chroot(2) is used to change the position of the root (/)of the filesystem is that, once / is moved, the pointed-to file path changes. If, for example, if chroot(2) is used to change the filesystem root to /ftp, then the symlink above would be actually be pointing to /ftp/sbin/rmt. Chances that that link, if chroot(2) is used, now points to a path that does not exist. Symbolic links that point to nonexistent files are known as dangling symbolic links. Note that symbolic links to files underneath the new root, such as symlinks to a file in the same directory:
      # pwd
      /var/ftp
      # ls -l
      -rw-r--r--   1 root     root            0 Jan 16 11:50 tmpfile
      lrwxrwxrwx   1 root     root            7 Jan 16 11:50 tmplink -> tmpfile
    
    will be unaffected; only paths that point outside/above the new root will be affected.

    Link Creation Tricks
    Knowing the above, it is now possible to demonstrate how some symlinks can work within a chrooted session, depending on how you create them.

    Here is an example to demonstrate this point. Assume the following directory structure:

      /path/to/ftp/
      /path/to/ftp/folders/
      /path/to/ftp/folders/incoming/
      /path/to/ftp/incoming --> /path/to/ftp/folders/incoming/ (symlink)
    
    And assume that you have the following in your proftpd.conf:
      DefaultRoot /path/to/ftp/
    

    If the symlink is created using:

      # ln -s /path/to/ftp/folders/incoming /path/to/ftp/incoming
    
    then that symlink will not work in the chrooted session; the path you gave ("/path/to/ftp/folders/incoming") is an absolute path, and will not exist after the chroot.

    Instead, if you create the symlink using:

      # cd /path/to/ftp
      # ln -s folders/incoming incoming 
    
    then that symlink should work within the chroot; the key is to use relative paths which do not go above your DefaultRoot directory.

    If your symlink does need to go above the DefaultRoot directory, then you need to use one of the other tricks described below.

    Filesystem Tricks
    A typical scenario is one where "DefaultRoot ~" is used to restrict users to their home directories, and where the administrator would like to have a shared upload directory, say /var/ftp/incoming, in each user's home directory. Symbolic links would normally be used to provide an arrangement like this. As mentioned above, though, when chroot(2) is used (which is what the DefaultRoot directive does), symlinks that point outside the new root (the user's home directory in this case) will not work. To get around this apparent limitation, it is possible on modern operating systems to mount directories at several locations in the filesystem.

    To have an exact duplicate of the /var/ftp/incoming directory available in /home/bob/incoming and /home/dave/incoming, use one of these commands:

    • Linux (as of the 2.4.0 kernel):
        mount --bind /var/ftp/incoming /home/bob/incoming
        mount --bind /var/ftp/incoming /home/dave/incoming
      
      or, alternatively:
        mount -o bind /var/ftp/incoming /home/bob/incoming
        mount -o bind /var/ftp/incoming /home/dave/incoming
      
    • BSD (as of 4.4BSD):
        mount_null /var/ftp/incoming /home/bob/incoming
        mount_null /var/ftp/incoming /home/dave/incoming
      
    • Solaris:
        mount -F lofs /var/ftp/incoming /home/bob/incoming
        mount -F lofs /var/ftp/incoming /home/dave/incoming
      
    The same technique can be used for <Anonymous> directories, which also operate in a chroot()ed environment. Also, it should be possible to mount specific files this way, in addition to directories, should you need to (a directory is just another file in Unix).

    As usual, more information can be found by consulting the man pages for the appropriate command for your platform. The commands for other flavors of Unix will be added as needed.

    In order to have these tricks persist, to survive a system reboot, the /etc/fstab (or /etc/vfstab) file may need to have these mounts added. Consult your local fstab(5) (or vfstab(4) for Solaris) man pages for more information.

    Chroots and Remote Filesystems
    If the chroot directories for your users happen to reside on an NFS partition, then you need to make sure that root privileges are not blocked (e.g. often referred to as "root squash") by the NFS mount. Otherwise, the chroot will fail.

    Frequently Asked Questions

    Question: I am using the DefaultRoot directive, but my logins are failing. The debug logging shows the following:

      USER user: Login successful.
      Preparing to chroot to directory '/home/users/user'
      user chroot("/home/users/user"): Permission denied
      error: unable to set default root directory
    
    I am starting proftpd with root privileges, so why is the chroot() failing with "Permission denied"?
    Answer: The above situation can happen in cases where even root privileges are insufficient. There have been reports of this happening for security-hardened systems (e.g. SELinux, OpenWall, etc); it can also happen when NFS is involved.

    If the DefaultRoot directory in question is mounted via NFS, make sure that the NFS configuration mounts the directory with root privileges. The chroot(2) system call requires root privileges; a no-root-privs mounted NFS directory does not allow the chroot(2) to succeed.

    Similarly, instead of "Permission denied", you might see "No such file or directory":

      user chroot("~"): No such file or directory
    
    The reasons for this error are explained here.

    Question: Is it possible to configure DefaultRoot for all users except some special users, which will have a different root directory?
    Answer: Yes, this is possible. ProFTPD supports having multiple DefaultRoot directives in the proftpd.conf at the same time; proftpd checks all of them in the order they appear. The first one which matches the logging-in user is applied.

    To illustrate, here's an example. Keep in mind that the optional parameters to the DefaultRoot directive are group names, not user names.

      DefaultRoot /path/to/admin/dir admin-group
      DefaultRoot /path/to/special/dir special-group
      DefaultRoot ~  # everyone else
    

    If the logging-in user is a member of group 'admin-group', then proftpd will chroot to the /path/to/admin/dir directory. If the logging-in user is not a member of group 'admin-group' but is a member of group 'special-group', then /path/to/special/dir is used for the chroot. And if the user is not a member of either of these groups, then the normal home directory is used for the chroot. It's always a good idea of have a "applies to everyone" DefaultRoot directive in your proftpd.conf, at the end of the list of DefaultRoots, as a catch-all.

    Question: Does DefaultRoot work properly if the path/home directory is a symlink?
    Answer: Yes.

    Question: I have configured DefaultRoot in my proftpd.conf, but my clients still see the root directory. Is it a bug?
    Answer. Usually not.

    First, make sure that you have restarted proftpd, so that the config changes you made (e.g. adding/modifying your DefaultRoot settings) are picked up by the running daemon.

    Second, make sure that you have cleared any client cache. Many FTP clients (especially browsers) will cache the directory listings that they have obtained from an FTP server. Thus once you have restarted proftpd and you still see the root filesystem displayed by your client, you need to make sure that that client is actually getting that listing from the FTP server, rather than showing you a stale/cached copy. The command-line ftp(1) client is good for testing this situation, as it is very simplistic and does not cache such things.

    Last, double-check the proftpd debug logging. It could be that proftpd is not using the configuration like you assume it is. Maybe a different config file is being used than the one you edited, or maybe the DefaultRoot directive is not in a <Global> section and you are using <VirtualHost> sections, etc.


    Last Updated: $Date: 2011/04/06 20:52:58 $

    proftpd-dfsg-1.3.5~rc3/doc/howto/AuthFiles.html0000644000175000017500000002327010361207131021222 0ustar frankiefrankie ProFTPD mini-HOWTO - Using AuthUserFiles

    Using AuthUserFiles


    The FTP protocol is old, stemming from the days of Telnet, before security came to be the relevant issue it is today. One of the protocol's biggest flaws, in today's security-conscious world, is the transmission of passwords "in the clear", unencrypted, easily visible to network sniffers. There are several ways of attempting to deal with this flaw.

    ProFTPD allows for the definition of "virtual" users: users who do not have accounts on the host machine, whose account information is defined in other sources. The passwords for these users are then specific only to FTP access, and thus do not expose shell access (ssh, hopefully) to unauthorized users. These alternative account information sources include SQL tables (via mod_sql), LDAP servers (via mod_ldap), CDB files (via mod_auth_cdb), and other system files (via the AuthUserFile and AuthGroupFile configuration directives). The proftpd server can be configured to use multiple account information sources simultaneously as well, allowing for flexible support of a range of environments.

    This document focuses on the use of the AuthUserFile and AuthGroupFile directives. Several questions often arise about the use of these directives. In general, the answers to those questions apply to other authentication/account sources, too.

    Formats
    Any configured AuthUserFile is used in addition to /etc/passwd, not instead of it (prior to 1.2.8rc1, however, an AuthUserFile was used instead of /etc/passwd); similarly for AuthGroupFile and /etc/group. The AuthOrder directive can be used if you want proftpd to use only the AuthUserFile. The format of an AuthUserFile is the same as /etc/passwd (man passwd(5)), and the format of an AuthGroupFile is the same as /etc/group (man group(5)). There is an ftpasswd script available that can be used to create and update these files.

    It is important to note here that not all flavors of Unix use these formats; one notable exception is FreeBSD. With FreeBSD, user account information is stored in binary database files as opposed to ASCII files. The C library on this platform also lacks the functions necessary for making the AuthUserFile and AuthGroupFile directives work properly. In this case, proftpd uses an internal implementation of the missing functions to read AuthUserFiles and AuthGroupFiles. This internal implementation requires that AuthUserFiles have the traditional passwd(5) format:

      username:password:uid:gid:gecos:homedir:shell
    
    and that AuthGroupFiles have this format:
      groupname:grouppasswd:gid:member1,member2,...memberN
    
    The ftpasswd script mentioned creates files in these required formats.

    Choice of IDs
    The choice of IDs for your users is important; the operating system does not deal with user processes in terms of their user names, it knows only of the numeric identity of a process. In general, it is best if each user has a unique positive user ID (negative IDs are an ugly hack, and proftpd will complain if they are used).

    However, in some mass-hosting environments such as ISPs, the number of users is greater than the number of IDs available. In these cases, you can give each user the same ID; additional steps should then be taken to make sure that each user is isolated from affecting other users' files. These additional steps are to make sure each user has a unique home directory, and then to restrict each user to their respective home directories by having

      DefaultRoot ~
    
    in your proftpd.conf.

    Shadow passwords
    There really is no need for an AuthShadowFile directive. The purpose of a shadow file is separate sensitive information (e.g. passwords) from other account information (username/UID/GID, etc). Programs like /bin/ls often reference the passwd file in order to display user/group names rather than numbers; these programs do not really need that sensitive information. Rather than relying on programs like /bin/ls to ignore the sensitive information, libraries were developed to split the information into /etc/passwd, /etc/shadow (and similarly for /etc/group, but very few administrators use group passwords anymore). Some operating systems, most notably FreeBSD, though, chose a different form of information separation. Since FreeBSD maintains account information in binary database files, the shadow libraries mentioned above are not used. Instead, FreeBSD returns the sensitive information to the calling program only if it has sufficient (i.e. superuser) privileges.

    When proftpd uses an AuthUserFile, it is looking for all of the account information, including the password. And since AuthUserFiles are specific to proftpd, there is no need to split any passwords out of an AuthUserFile into an AuthShadowFile. As the documentation states, an AuthUserFile need not reside inside a chroot() filesystem, which means that users can be effectively isolated from having access to that AuthUserFile. At that point, the only consideration is making sure that the permissions on the AuthUserFile are sufficient for the server to have access, but no other users.

    Permissions
    As the AuthUserFile and AuthGroupFile files are meant to be drop-in replacements for their system cousins, there are a few caveats. /etc/passwd and /etc/group are normally world-readable on modern Unix systems. This allows programs like /bin/ls to map system ID numbers to more legible names; sensitive information in the /etc/passwd and /etc/group is normally stored elsewhere, in restricted shadow files. The proftpd server thus assumes that it will not need special privileges to read an AuthUserFile or an AuthGroupFile. The process will access any AuthUserFiles and AuthGroupFiles with the credentials of the user and group configured via the User and Group directives. The files may contain sensitive information, so they should not have as open of permissions as /etc/passwd and /etc/group. The most paranoid setting will have user-read-only permissions for those files, and have the files be owned by the user configured for the relevant server via the User directive. Hopefully the server administrator has created a new account on the system just for the ftpd daemon.

    ID-to-name mapping
    A consequence of which to be aware when using an AuthUserFile is the difference between that AuthUserFile's mapping of system IDs to names, and the mapping in /etc/passwd. This may catch some system administrators unawares when they go to check the ownership of files uploaded by some user whose account is defined in an AuthUserFile, and find those files being reported as being owned by different users and/or groups by /bin/ls. Keep in mind that /bin/ls is using /etc/passwd, not the AuthUserFile. This issue crops up with any alternative account information source, not just AuthUserFiles.

    If you are using the same UID/GID for your users, e.g. in a mass hosting environment, one trick you might like to do is make all of the files, as listed by the server, appear to be owned by the logged in user. This is done using the DirFakeUser and DirFakeGroup directives, like this:

      # make listed files appear to be owned by the logged-in user
      DirFakeUser on ~
      DirFakeGroup on ~
    
    As noted in the documentation, these directives are purely cosmetic, and in no way change the real ownership of files. This may cause some confusion on the client side in some cases, if the user sees a file that is reported to be owned by them, and the permissions on the file show user access is allowed, and yet the client is unable to access the file. HideNoAccess can help in situations like this.


    proftpd-dfsg-1.3.5~rc3/doc/howto/ServerType.html0000644000175000017500000002504312056520717021461 0ustar frankiefrankie ProFTPD mini-HOWTO - ServerType

    ServerType


    The ServerType configuration directive for ProFTPD can cause confusion for those just starting with this server. What is the purpose for this directive? What are these "inetd" and "standalone" types, and why does one need to choose one or the other?

    The purpose of this directive is to choose between the two operating modes for almost all Unix network servers: does the server listen on its port for client requests itself, or does the server let some other process do the listening, and call the server when needed? Traditionally, that "other process" has been inetd, a "super server" that listens on all interfaces, all ports on a Unix machine, and calls the appropriate server based on the port contacted. A more modern replacement for inetd is found in the xinetd server; this server functions much the same way. The other mode of operation is to have the server listen on the port(s) itself, and handle client requests accordingly. The latter mode is the standalone ServerType, the former is the inetd mode (which covers both the inetd and xinetd processes).

    This directive is mandatory, and must be set to one mode or the other. The two modes are incompatible (two processes cannot be bound to the same interface/port combination simultaneously), and thus the proftpd must be told in which mode it is to operate.

    Inetd Mode
    In inetd mode, the proftpd server expects to be started by the inetd (or xinetd) servers. It is these servers, inetd/xinetd, that listen on the FTP port (usually 21) for connection requests, then start proftpd and pass the connection off. This mode is usually best suited for low traffic sites, for sites that do not handle many FTP sessions.

    Example /etc/inetd.conf entry:

      ftp    stream  tcp     nowait  root    /usr/sbin/tcpd  /usr/sbin/proftpd
    
    The inetd.conf man pages discuss these fields in greater detail.

    An example xinetd configuration is:

      service ftp
      {
            disable = no
            flags			= REUSE
            socket_type             = stream
            wait                    = no
            user                    = root
            server                  = /usr/sbin/proftpd
            server_args             = -c /etc/proftpd.conf
      }
    
    The xinetd configuration is usually found in /etc/xinetd.conf or in the /etc/xinetd.d/ directory.

    Note: Solaris users may find that their /etc/inetd.conf file ships with an ftp entry that looks similar to the above, except that it has "tcp6" rather than "tcp". For proftpd to function properly in such cases, that "tcp6" will need to be changed to "tcp". Solaris uses the tcp6 keyword to have its inetd pass IPv6 sockets to the called program; proftpd must have been configured with the --enable-ipv6 option to handle such sockets.

    Inetd Mode and Non-standard Ports
    A note about using non-standard ports in your configuration via the Port configuration directive: making these work while in inetd mode and using inetd (as oppposed to xinetd) is problematic. The first column of an /etc/inetd.conf entry lists a protocol name. The port for that protocol is listed in the /etc/services file. For services that run on non-standard ports, however, /etc/services has no entry, and inetd is programmed so as to always reference that file. This means that if use of non-standard ports and use of inetd are required, the /etc/services file will need to be edited. Avoid this situation if possible.

    Compared to inetd, xinetd's configuration format is more flexible: it can be configured to use non-standard ports using the port attribute:

           port             determines  the  service  port.  If  this
                            attribute  is  specified  for  a  service
                            listed in /etc/services, it must be equal
                            to the port number listed in that file.
    
    as described in the xinetd.conf(5) man page.

    If your proftpd server is running in this mode, you do not need to worry about restarting any servers whenever changes are made to the proftpd.conf configuration file. Since proftpd is started for each new FTP session by inetd/xinetd, and part of that startup process includes reading the configuration file, any changes will be seen by any new FTP sessions once the changes are made.

    If you attempt to start a proftpd server configured with a ServerType of standalone, and already have inetd/xinetd also configured to handle FTP connections, this kind of error message will appear in your proftpd logs:

      golem.castaglia.org - Failed binding to 127.0.0.1, port 21: Address already in use
      golem.castaglia.org - Check the ServerType directive to ensure you are configured correctly.
    
    More information might be found by debugging your configuration.

    Standalone Mode
    In this mode, the proftpd listens for incoming FTP session requests itself, and forks off child processes to handle those requests. This mode is best suited for high traffic, popular sites; the overhead of having to parse the configuration file each time, as is done for inetd-handled sessions, is avoided in this mode. Also, there is no need to change any other configuration files other than the proftpd.conf, for ports, virtual servers, or anything else.

    When running in this mode, the server will need to be restarted whenever changes are made to the configuration file. There is a page that describes how this can be done.

    Many administrators are accustomed to using tcpwrappers to secure their network servers; indeed, this is a good practice to get into. However, the most common way this is done is through inetd. When running a proftpd server in standalone mode, then, it is not quite as straightforward; however, it is not hard, either. The mod_wrap module can be compiled into your proftpd. This module allows a standalone proftpd server to use the normal /etc/hosts.allow, /etc/hosts.deny files, in addition to other files (something that normal tcpwrappers configurations cannot do).

    If you try to start a proftpd server configured with a ServerType of inetd from the command line (or from some shell wrapper script), this kind of error message will appear in your proftpd logs:

      golem.castaglia.org - Fatal: Socket operation on non-socket
      golem.castaglia.org - (Running from command line? Use `ServerType standalone' in config file!)
    
    More information might be found by debugging your configuration.

    Switching Modes
    Changing from one ServerType mode to the other is a simple process, as long as the few steps involved are followed.

    To change from inetd to standalone, make sure to remove any FTP configurations from /etc/inetd.conf, /etc/xinetd.conf, /etc/xinetd.d/, or wherever your superserver's configuration file(s) reside. Once this is done, make sure those changes are seen by restarting inetd/xinetd. Then, make sure

      ServerType standalone
    
    is in your proftpd.conf. Start the proftpd server from the command line, to make sure all is working. You can then easily start server from an init.d script such as the one mentioned here.

    To change from standalone to inetd, make sure your proftpd is stopped completely. Add a configuration entry for FTP into your inetd/xinetd configuration (mentioned above), then restart inetd/xinetd to have those configuration changes seen. Check your proftpd.conf to see that

      ServerType inetd
    
    is there.

    Frequently Asked Questions
    Question: I have configured:

      IdentLookups off
      ServerIdent off
    
    in my proftpd.conf, but my logins are still slow. Why?
    Answer: Another source of slow logins can be xinetd, or tcpwrappers compiled for reverse DNS lookups (i.e. with the -DPARANOID option).

    If you are using ServerType inetd, and you are using xinetd to run proftpd, then you should check your /etc/xinetd.conf (or /etc/xinetd.d/proftpd or similar) file for the USERID parameter, e.g.:

      log_on_success          += DURATION USERID
      log_on_failure          += USERID
    
    As per the xinetd.conf documentation, the use of USERID in your configuration causes xinetd to do an IDENTD lookup:
            USERID      logs the user id of the remote user  using
                        the   RFC  1413  identification  protocol.
                        This option is available only  for  multi-
                        threaded stream services.
    
    Removing USERID from your xinetd configuration for proftpd often suffices to fix the slow logins.

    Another solution is simply to switch your ServerType to "standalone".


    Last Updated: $Date: 2012/12/02 00:33:19 $

    proftpd-dfsg-1.3.5~rc3/doc/howto/index.html0000644000175000017500000002335112142631120020443 0ustar frankiefrankie ProFTPD mini-HOWTO Index

    ProFTPD mini-HOWTO Index


    The following is a collection of mini-HOWTOs that cover most of the common questions asked about ProFTPD and how to configure it.

    Recommended order of reading:

      On how to compile ProFTPD
      Covers the various options to the configure script used by ProFTPD's build system
      The proftpd.conf file
      Covers the location and format of ProFTPD's configuration file, and some of the basic functionality

      On configuring the ServerType
      Covers how to configure ProFTPD to operate as a standalone daemon or one run via inetd/xinetd

      On how clients are authenticated
      Covers the steps taken in authenticating a user, and how authentication involves PAM, chroots, shells, etc.

      On DefaultRoot and chroots
      Covers the DefaultRoot configuration directive, chroots, and why symlinks do not work as expected when chroots are in effect

      On AuthUserFiles
      Covers the use of AuthUserFile and AuthGroupFile

      On the Umask directive
      Covers how Umask works, including a basic introduction to Unix filesystem permissions

      On debugging
      Covers how to configure the daemon so that it produces debugging output, which greatly helps in diagnosing problems

      On ProFTPD release versioning
      Covers the version naming convention used for ProFTPD releases

      On <VirtualHost> sections
      Covers how to configure virtual servers, listening on only one IP address, and how the daemon handles client connections to its virtual servers

      On virtual users
      Covers what virtual users are, how proftpd can be configured to handle virtual users from various sources (i.e. SQL, flat files, LDAP, etc).

      On <Directory> sections
      Covers how <Directory> sections should be configured, and how the configured paths are matched

      On <Limit> sections
      Covers how <Limit> sections should be configured, and how different <Limit>s interact

      On using proftpd in a firewall/NAT environment
      Covers how NAT and passive FTP data transfers work, how to configure proftpd to operate in such environments

      On ProFTPD quotas
      Covers how the mod_quotatab module can be used for implementing quotas

      On ProFTPD and timestamps
      Covers the situation where the timestamps which appear in log files and directory listings may change, or not be what you expect

      On the ListOptions directive
      Covers how the ListOptions directive can be used to specify the directory listing options for clients, including showing hidden files and disabling recursive directory listings

      On upgrading
      Covers the best way to perform an upgrade of ProFTPD

      On DSO modules
      Covers what DSO modules are, and how to use them properly

      On connection ACLs
      Covers implementing connection ACLs, and some of the performance concerns related to the different mechanisms

      On ASCII transfers
      Covers ASCII mode for data transfers, and the affected FTP commands

      On FXP, also known as site-to-site transfers
      Covers why allowing site-to-site transfers is considered a bad idea, and how to configure proftpd to allow them

      On DNS usage
      Covers when and how proftpd uses the DNS

      On sendfile support
      Describes what the sendfile(2) function does, and some cases where it should not be used

      On the FTP commands supported
      Provides descriptions of the FTP commands supported by the daemon, including some common SITE commands

      On the various forms of logging
      Covers the various log files that ProFTPD can generate, and how logging capabilities can be extended

      On SQL configurations
      Covers configuring mod_sql and how to set up your SQL tables, and some of the common questions about using mod_sql

      On memcache support
      Covers configuring and using memcache by various modules

      On TCP/FTP/SSH keepalive functionality
      Covers keeping long-lived connections alive, using TCP, FTP, and SSH specific mechanisms

      On using FTP over SSH
      Covers tunneling FTP over SSH

      On SSL/TLS configurations
      Covers configuring the daemon to handle FTP over SSL/TLS (also known as FTPS), including some of the common questions about FTPS.

      On starting/stopping the daemon
      Covers how the daemon is commonly started, stopped, and restarted, and includes an example init script

      On the ScoreboardFile
      Covers what the scoreboard does, and some of the common questions about scoreboards

      On Classes
      Covers defining and using classes

      On Display files
      Covers the various Display directives

      On the CreateHome directive
      Covers how to configure the daemon to create home directories on-demand

      On Controls
      Covers Controls and mod_ctrls

      On rewriting commands using mod_rewrite
      Contains a collection of examples of mod_rewrite configurations that solve a variety of different problems

      On Tracing
      Covers trace logging

      On Filters
      Covers the various Filter directives, and how to write regular expressions that match what you want

      On configuration tricks
      Covers various ways that can be used to make the proftpd.conf work in conditional ways

      On Regular Expressions
      Covers POSIX regular expressions

      On running proftpd as a nonroot user
      Covers configuring proftpd to run as a nonroot user

      On globbing
      Covers what globbing is, how it can cause problems, and how to configure the daemon to defend against globbing attacks

      On testing of proftpd
      Covers functional, integration, and regression tests of proftpd, and how to run the testsuite

      On translations of proftpd into other languages
      Covers which parts of proftpd are translated, and how to add new translations

      On best common practices
      Covers some of the best common and recommended practices for configuring and running proftpd

    If your question or issue is not covered by any of these pages, please send a request to the ProFTPD documentation list. Directions for subscribing to the docs list, as well as the other ProFTPD mailing lists, are at:

      http://www.proftpd.org/lists.html
    
    If you are looking to see if ProFTPD supports a particular feature, the first place to look as the complete list of configuration directives:
      http://www.proftpd.org/docs/directives/linked/by-name.html
    
    The list may be intimidatingly long, but it is well worth scanning through all of the directives to see everything that ProFTPD is capable of supporting.


    Last Updated: $Date: 2013/05/09 05:21:20 $

    proftpd-dfsg-1.3.5~rc3/doc/howto/Filters.html0000644000175000017500000001504111674200164020752 0ustar frankiefrankie ProFTPD mini-HOWTO - Filters

    Using Filters


    ProFTPD supports the ability to "filter" the FTP commands it receives from the client. These filters are written as regular expressions. This means that while the filters can be very powerful, they can also be complex and harder to construct.

    First, there are the AllowFilter and DenyFilter configuration directives. These configuration directives are used to set filters on every FTP command. If an AllowFilter is used, the command parameters must match the given filter, otherwise the command will be denied. If a DenyFilter is used, the command parameters must not match the given filter, otherwise the command will be denied. If both AllowFilter and DenyFilter are used, then the AllowFilter will be checked first.

    Second, there are some special filter configuration directives aimed at those FTP commands that cause changes to files and directories on the server system: PathAllowFilter and PathDenyFilter. Like AllowFilter and DenyFilter, the Allow filter, if present, is checked first, then a DenyFilter, if present. PathAllowFilter and PathDenyFilter are checked after the AllowFilter and DenyFilter directives. These Path filters are only applied to the following FTP commands: DELE, MKD/XMKD, RMD/XRMD, RNFR, RNTO, STOR, STOU, and to the SITE commands CHGRP and CHMOD. Note that using both PathAllowFilter and PathDenyFilter at the same time is not a good idea; only one filter is generally needed.

    One property that often catches the unwary administrator is the fact that proftpd only operates on the first Filter directive defined in the configuration file; it does not cycle through multiple Filter directives. This is because multiple regular expressions can be combined into a single (albeit more complex) regular expression. The alternation metacharacter is helpful in creating such combined regular expressions. For example, if you had the following in your proftpd.conf:

      PathAllowFilter \.jpg$
      PathAllowFilter \.jpeg$
      PathAllowFilter \.mpeg$
      PathAllowFilter \.mpg$
      PathAllowFilter \.mp3$
    
    only the first PathAllowFilter would be enforced. To enforce all Filter simultaneously, use:
      PathAllowFilter \.(jpg|jpgeg|mpeg|mpg|mp3)$
    
    Matches are case-sensitive! Also note that if you surround your regular expression in quotation (") marks, any backslash will itself need to be escaped; ProFTPD's configuration parser interprets backslashes inside of quoted strings a little differently. Thus, the example above would look like this:
      PathAllowFilter "\\.(jpg|jpgeg|mpeg|mpg|mp3)$"
    
    if using quotation marks.

    Another characteristic to keep in mind is that Filters are only applied to FTP command parameters, not to the FTP command itself. Most of the time, this is not a problem. It would be useful sometimes, though, to be able to filter parameters of commands other than those filtered by the Path filter directives. It would be an easy change to the source code; however, there is no feature request for the ability to do this on bugs.proftpd.org with a good justification for such a feature. If you can think of one, please open such a request.

    When developing your Filter directives, it often helps to keep an eye on the server debugging output, to see how well your filters are being applied.

    Examples
    To prevent clients from using paths which may contain non-printable characters (e.g. CR, LF, VB, etc), you can use the following PathDenyFilter pattern:

      PathDenyFilter [^[:print:]]
    
    Alternatively, you could use a PathAllowFilter which only allows printable characters in paths:
      PathAllowFilter [[:print:]]
    
    And if you want to prevent spaces and tabs from appearing in paths, you can use:
      PathDenyFilter [[:blank:]]
    

    What if you want to prevent clients from uploading so-called "dot files", i.e. files whose names start with a period ('.'), so that they are "hidden"? To prevent uploading of all dot files, you can use the following PathDenyFilter configuration:

      PathDenyFilter \.[^/]*$
    

    In ProFTPD 1.3.3rc1 and later, you can use the AllowFilter and DenyFilter configuration directives inside of <Limit> sections, so that those Filter directives only apply to the FTP commands listed in the <Limit> section. This means you can specify regular expression filters for the arguments for specific commands. For example, you may want to configure a directory that only allows uploads of files with specific extensions. You could use PathAllowFilter for this -- but PathAllowFilter also applies to the MKD command, and you might want to allow users to create subdirectories in your special directory. Thus you only want your regular expression to apply to the STOR command in your directory. Below is an example of how to do this using AllowFilter:

      <Directory /path/to/dir>
        <Limit STOR>
          Order deny, allow
          AllowFilter \.ext$
        </Limit>
      </Directory>
    
    The key is the Order directive; without it, the configuration will not work as you expect.


    Last Updated: $Date: 2011/12/20 21:39:00 $

    proftpd-dfsg-1.3.5~rc3/doc/howto/Logging.html0000644000175000017500000004333012142621670020732 0ustar frankiefrankie ProFTPD mini-HOWTO - Logging

    Logging


    Logging
    Logging the activity of the server is an integral part of effective server administration. ProFTPD provides several different and flexing logging mechanisms. When examining the different logging mechanisms, have in mind the intended use of the logged data, the volume of data being logged, any post-processing that may need to be done, etc. Log files are more useful when they contain a complete record of server activity. It is often easier to simply post-process the log files to remove requests that you do not want to consider.

    Security Warning
    Anyone who can write to the directory where ProFTPD is writing a log file can almost certainly gain access to the UID that the server is started under, which is normally root. Do not give people write access to the directory where the logs are stored without being aware of the consequences: if the logs directory is writable (by a non-root user), someone could replace a log file with a symlink to some other system file, and then root might overwrite that file with arbitrary data. If the log files themselves are writable (by a non-root user), then someone may be able to overwrite the log itself with bogus data.

    When opening log files, proftpd will by default log a warning if the file being opened for logging is in a directory that does not exist, or is world-writable. The log file will not be written in world-writable directories; there are no exceptions. (If you have configured log files in your proftpd.conf that are not appearing, check for the warnings about world-writable directories.) The proftpd process will also, by default, log a warning if the file given is a symlink; this symlink check can be configured via the AllowLogSymlinks directive.

    In addition, log files may contain information supplied directly by the client, without escaping. Therefore, it is possible for malicious clients to insert control-characters in the log files, so care must be taken in dealing with raw logs.

    Unix syslog Logging
    By default, proftpd will log via syslog(3), using the daemon facility (auth for some logging), at various levels: err, notice, warn, info, and debug (debugging is done at this syslog level). The location of the server's log files in this case is determined by your /etc/syslog.conf configuration.

    You can fine-tune your proftpd's syslog-based logging via the SyslogFacility and SyslogLevel directives.

    Log Files
    There are three main types of logs that a proftpd daemon can generate: TransferLog, SystemLog, and ExtendedLog.

    A TransferLog is the most common log kept, recording file transfers. Its format is described in the xferlog(5) man page, also available here.

    If the site administrator wants to have proftpd log its messages to a file rather than going through syslogd, the SystemLog configuration directive is the one to use. There is only one such file kept for the entire daemon. See the ServerLog directive for keeping a similar log on a per-vhost basis. Note that the DebugLevel directive only applies to SystemLog files; it does not materially affect the syslog-based logging messages.

    The ExtendedLog directive is used to create log files of a very flexible and configurable format, and to have granular control over what is logged, and when. The format of an ExtendedLog is described using the LogFormat directive. Multiple ExtendedLogs can be configured, each with a different LogFormat.

    Use of syslog versus file logging
    Most sites will choose to have proftpd log via syslog (which is the default) or to a file (via the SystemLog directive). In either case, there is the question of logging verbosity, i.e. which messages to log. This verbosity is determined by the
    SyslogLevel directive. ProFTPD will log everything by default, meaning that the default SyslogLevel is effectively debug. If, however, you have your proftpd configured to log via syslog, then you should also check your /etc/syslog.conf file, to see what additional filtering of log messages is being applied by syslog. For example, if /etc/syslog.conf contained something like:

      # Log anything (except mail) of level info or higher.
      *.info;mail.none;authpriv.none;cron.none                /var/log/messages
    
    then ProFTPD's log messages below the info level would be filtered out by syslog. When you are using syslog logging, the SyslogLevel configuration directive applies only to the proftpd logging, and does not control the additional syslog filtering.

    For finer-grained control of the debug level log messages, ProFTPD internally implements different levels for its debug log messages. Currently ProFTPD has level 1 through level 10 debug messages. The DebugLevel directive is used control the verbosity/filtering of these messages. Since these different debug levels are purely a ProFTPD convention, the DebugLevel directive has no effect on syslog logging. Also, if your SyslogLevel configuration uses a level higher than debug, then the DebugLevel configuration will have no effect — your debug level messages are already filtered out by the SyslogLevel filtering.

    The last point to mention is that the SyslogFacility directive only applies to syslog logging; it has no effect on file logging.

    Log Analysis
    There are a variety of log analyzers available; these are just a few:

    Log Rotation
    On even a moderately busy server, the quantity of information stored in the log files is very large. It will consequently be necessary to periodically rotate the log files by moving or deleting the existing logs. This cannot be done while the server is running, because the daemon will continue writing to the old log file as long as it holds the file open. Instead, the server must be restarted after the log files are moved or deleted so that it will open new log files.

    Another way to perform log rotation is using FIFOs as discussed in the next section.

    FIFOs (a.k.a. named pipes)
    ProFTPD is capable of writing log files to FIFOs, from which another process can read. Use of this capability dramatically increases the flexibility of logging, without adding code to the main server. In order to write logs to a pipe, simply create the FIFO at the desired path (man mkfifo(1)), and use that path in the logging configuration directive.

    One important use of piped logs is to allow log rotation without having to restart the server. One such popular flexible log rotation program is cronolog; however, at present cronolog requires a small patch to enable it to read from a FIFO (by default, cronolog reads data from stdin). Please contact the author of this article for details concerning the patch.

    Here's an example of FIFO-based logging script, based on one posted by Michael Renner:

      #!/usr/bin/perl
    
      use strict;
    
      use File::Basename qw(basename);
      use Sys::Syslog qw(:DEFAULT setlogsock);
    
      my $program = basename($0);
    
      my $fifo = '/var/log/proftpd-log.fifo';
      my $syslog_facility = 'daemon';
      my $syslog_level = 'info';
    
      open(FIFO, "< $fifo") or die "$program: unable to open $fifo: $!\n";
    
      setlogsock 'unix';
    
      openlog($program, 'pid', $syslog_facility);
      syslog($syslog_level, $_) while (<FIFO>);
      closelog();
    
      close(FIFO);
      exit 0;
    
    More complex filtering can be added to such scripts.

    If using FIFOs, there are some caveats to keep in mind. If you use in init.d script to start standalone daemons, you can add commands to start the FIFO logging programs first, before the daemon. For inetd-run servers, consider wrapping up the necessary commands for starting a FIFO reader and the server into a simple shell script, or simply run the FIFO-reading program from an init.d script, and save the overhead of starting that process, in addition to the proftpd process, for each FTP session.

    FIFO-based log readers are a very powerful tool, but they should not be used where a simpler solution like off-line post-processing is available.

    Note: In ProFTPD 1.3.3, the code was changed to use nonblocking open(2) system calls when opening log files. This was done to prevent a proftpd process from blocking indefinitely (i.e. "hanging") if the log file was a FIFO, and there was no FIFO reader process running when the log file was opened. However, some sites do want this blocking open behavior, as their FIFO reader processes may be temporarily busy. To get the pre-1.3.3 blocking behavior, you will need to compile proftpd using the --disable-nonblocking-log-open configure option.

    SQL Logging
    The mod_sql module also enables some powerful and complex logging capabilities...

    Trace Logging
    ProFTPD also supports a much more verbose form of logging called "trace logging". This form of logging is covered in greater detail here.

    Pid File
    On startup, proftpd saves the process ID of the parent daemon process to the file var/proftpd/proftpd.pid. This filename can be changed with the PidFile directive. The process ID (aka PID) is for use by the administrator in restarting and terminating the daemon by sending signals to the parent process. For more information see the stopping and starting page.

    Scoreboard File
    The last type of "logging" is done via the scoreboard file. The scoreboard is binary-formatted file the server uses to store information about each session; it is this file that is read by ftptop, ftpwho and ftpcount. The location for the scoreboard file is determined by the ScoreboardFile directive.

    Frequently Asked Questions

    Question: How can I direct the TransferLog logging to syslog?
    Answer: It is not currently possible to configure proftpd to log TransferLog data to syslog. However, you can configure an ExtendedLog which logs to syslog, and which uses a LogFormat to log the data you wish. For example:

      LogFormat xfer "%h %l %u %t\"%r\" %s %b"
      ExtendedLog syslog:notice xfer
    
    tells proftpd to log that LogFormat via syslog at the "notice" syslog level.

    Question: I have SystemLog in my proftpd.conf, and when I use the SyslogLevel directive to try to filter the messages which proftpd logs to my SystemLog, it doesn't work. Why not?
    Answer: When ProFTPD is configured to log everything to a file via the SystemLog directive, it will do just that: log everything, without any filtering, regardless of any SyslogLevel directive. However, this changed in ProFTPD 1.3.4rc1: in that release, the SyslogLevel directive was made to apply to file-based logging as well.

    Question: I configured my ExtendedLog directive (or SystemLog, or other logs) to point to a FIFO. The FIFO path exists. But when I try to start proftpd, it fails to start with this error:

      unable to open ExtendedLog '/path/to/extlog.fifo': No such device or address
    
    Shouldn't this work?
    Answer: The "No such device or address" error occurs when you configure proftpd to log to a FIFO, and the FIFO reader process has not yet been started. In times past, proftpd would wait indefinitely on startup, waiting for the FIFO reader process to start; now, proftpd tries to open the FIFO in a nonblocking mode, so that it can fail immediately if there is no process on the other end of the FIFO.

    The "fix" is to make sure that any FIFO reader processes are started before starting proftpd.

    Question: How can I configure proftpd so that nothing is logged for certain clients/IP addresses?
    Answer: Using a combination of classes and the mod_ifsession module, this can be done using a configuration like this:

      <Class invisible>
        From 1.2.3.4
      </Class>
    
      <IfClass invisible>
        # Disable all logging of these clients
        SystemLog none
        ExtendedLog /path/to/ext.log NONE
        TransferLog none
      </IfClass>
    

    Question: How can I configure proftpd so that it does no logging at all? I have a very small embedded system for development/testing, and so do not need or want the logging.
    Answer: To do this, you will need to disable much of the builtin, default logging that proftpd does, e.g.:

      # Discard the normal logging
      SystemLog none
    
      # Disable xferlog(5) logging
      TransferLog none
    
      # Disable logging to b/u/wtmp files
      WtmpLog off
    
    In addition, you may need to go through your proftpd.conf file (as well as any Include config files), and remove all ExtendedLog and TraceLog directives. Also remove any per-module *Log directives like BanLog, SFTPLog, SQLLogFile, TLSLog, etc.

    You might be tempted to symlink the log files configured to /dev/null, rather than changing the proftpd.conf. This approach can work, if you also use the AllowLogSymlinks directive, i.e.:

      # Allow proftpd to write logs to symlinks; note that this is insecure,
      # as the symlinks might be changed to point to other files such that
      # proftpd will overwrite them.
      AllowLogSymlinks on
    

    Question: I see:

      wtmp /var/log/wtmp: No such file or directory
    
    in my logs. What is WtmpLog logging? The description in the documentation is quite vague.
    Answer: The wtmp logging support is not specific to proftpd, and instead is a more general Unix facility; this is why the ProFTPD documentation does not cover it in great detail. To learn more about wtmp (or any of its other incarnations: wtmpx, utmp, utmpx), please find their related man pages.

    Now to make the "No such file or directory" log message go away, simply tell proftpd to stop trying to use wtmp logging by using:

      WtmpLog off
    
    in your proftpd.conf.


    Last Updated: $Date: 2013/05/09 04:19:04 $

    proftpd-dfsg-1.3.5~rc3/doc/howto/Rewrite.html0000644000175000017500000004147112072663134020774 0ustar frankiefrankie ProFTPD mini-HOWTO - Using mod_rewrite

    Using the mod_rewrite Module


    The mod_rewrite module for proftpd is a powerful tool for rewriting FTP commands received from clients. It has been used to automatically append (or remove) domain names from logins, to translate Windows paths (using backslashes) to Unix paths (using slashes), to handle case-insensitive files, etc. One of the great things about mod_rewrite is that any modification made to the commands is transparent to the client; that is, FTP clients are completely unaware that their commands are being changed on-the-fly.

    The following is a collection of examples of how mod_rewrite has been used. If you use mod_rewrite and would like to contribute your recipe/configuration, please let us know!

    Since much of mod_rewrite's power is based on regular expressions and pattern matching, I highly recommend that you read through this introduction to POSIX regular expressions, and use the regex tool for testing out your regexes against paths/strings:

      http://www.castaglia.org/proftpd/doc/contrib/regexp.html
    

    Case Sensitivity
    The following example configuration shows how to configure mod_rewrite so that all files uploaded to the FTP server will have all-uppercase filenames:

      <IfModule mod_rewrite.c>
        RewriteEngine on
    
        # Have a log for double-checking any errors
        RewriteLog /var/log/ftpd/rewrite.log
    
        # Define a map that uses the internal "toupper" function
        RewriteMap uppercase int:toupper
    
        # Make the file names used by STOR be in all uppercase
        RewriteCondition %m STOR
    
        # Apply the map to the command parameters
        RewriteRule ^(.*) ${uppercase:$1}
      </IfModule>
    

    What if you wanted to make the filename always be uppercase for uploaded files, but not any directories in the path leading up the file name? Using the above, if you did:

      ftp> cd /upload
      ftp> put file1.txt
    
    The file would appear as "/upload/FILE1.TXT". But if you did:
      ftp> put /upload/file1.txt
    
    the file would appear as "/UPLOAD/FILE1.TXT", which may not be what you want. To handle this, you need to change the "^(.*)" pattern in the above RewriteRule directive. The "^(.*)" regular expression matches the entire parameter string. Instead, you might try this pattern:
      RewriteRule (.*/)?(.*)$ ${uppercase:$2}
    
    which tries to isolate into match group 2 (i.e. $2) the part of the argument string which is not followed by any slashes.

    Somewhat similar is the situation where the admin found, for case-sensitivity reasons, that it was easier to rewrite all FTP commands (except PASS, since passwords are case-sensitive) to be lowercase:

      <IfModule mod_rewrite.c>
        RewriteEngine on
    
        # Define a map that uses the internal "tolower" function
        RewriteMap lowercase int:tolower
    
        # Rewrite all commands except PASS
        RewriteCondition %m !PASS
    
        RewriteRule ^(.*) ${lowercase:$1}
      </IfModule>
    
    This means an FTP client can refer to "/DiR/Dir2/FiLe" when on the server the file is actually "/dir/dir2/file"; it works for uploads, too. (This works especially well for Windows clients.)

    Changing the Filenames
    One user had the following problem: Files uploaded via a web browser had their filenames changed by the browser. Specifically, the web browser changed any spaces in the filenames to "%20" (URL encoding for a space character). Fortunately, the user was able to use mod_rewrite to undo the change or, as shown below, to change that "%20" to an underscore:

      <IfModule mod_rewrite.c>
        RewriteEngine on
    
        # Define a map that uses the internal "replaceall" function
        RewriteMap replace int:replaceall
    
        # We only want to use this rule on STOR commands
        RewriteCondition %m STOR
    
        # Apply the map to the command parameters.  Use '!' as the delimiter,
        # not '/', as the path sent might contain slashes
        RewriteRule ^(.*) "${replace:!$1!%20!_}"
      </IfModule>
    

    Another site wanted to "tag" each uploaded file name with the current process ID (PID), to ensure some sort of file name uniqueness. Enter mod_rewrite!

      <IfModule mod_rewrite.c>
        RewriteEngine on
    
        RewriteCondition %m STOR
        RewriteRule (.*) $1.%P
      </IfModule>
    
    This appends the PID of the current session process to any uploaded filename. For more variables like %P, see the RewriteCondition and RewriteRule descriptions.

    Replacing Backslashes With Slashes
    Some sites have FTP clients which seem to send CWD and RETR/STOR commands which use Windows-style backslashes, e.g. "path\to\file". And ideally, these sites would like to work seamlessly with such clients, without having to get the clients to change. Can mod_rewrite be used to change those backslashes into more Unix-friendly regular slashes? Absolutely. The following mod_rewrite configuration should do the trick:

      <IfModule mod_rewrite.c>
        RewriteEngine on
    
        # Use the replaceall internal RewriteMap
        RewriteMap replace int:replaceall
    
        RewriteRule (.*) "${replace:!$1!\\\\!/}"'
      </IfModule>
    
    Yes, you will need the four consecutive backslashes there, in order to make it past proftpd's config file parser (which thinks backslashes are escape sequences) as well as the regular expression compiler.

    Modifying User Names
    Is there a way that I can transparently change the login name that the FTP client sends, from one set of known login names to the new set of names that should be used by the FTP server? But of course! For this example, let us assume that you have a text file which maps the old login names to the new login names. Using mod_rewrite's RewriteMap directive and that text file, this becomes simple:

      <IfModule mod_rewrite.c>
        RewriteEngine on
    
        # Tell mod_rewrite where to find the "usermap" text file
        RewriteMap usermap txt:/path/to/usermap.txt
    
        # For USER commands, use the "usermap" file to translate the login names
        RewriteCondition %m USER
        RewriteRule (.*) ${usermap:$1}
      </IfModule>
    

    Rather than having a fixed map of old-to-new login names, what if you wanted to always append the same prefix (or suffix) to every login name? For example, what if you wanted every login name on your FTP server to look like "user@domain.com", but the clients were sending simply "user". This solution does not need RewriteMap; instead, you simply use:

      <IfModule mod_rewrite.c>
        RewriteEngine on
    
        RewriteCondition %m USER
        RewriteRule (.*) $1@domain.com
      </IfModule>
    
    And if instead you wanted to use a fixed prefix, rather than a suffix, the only difference would be in the RewriteRule directive, e.g.:
      <IfModule mod_rewrite.c>
        RewriteEngine on
    
        RewriteCondition %m USER
        RewriteRule (.*) PREFIX$1
      </IfModule>
    

    Another interesting use case is where your clients might send the login name in a variety of constructions, e.g.:

    • user
    • user@domain.com
    • prefix#user@domain.com
    but you want the FTP server only to use the "user" parts. How can you configure mod_rewrite to strip off any potential prefix and suffix? Regular expressions can be tricky, but using the regex tool mentioned above, I worked out the following configuration that does the trick:
      <IfModule mod_rewrite.c>
        RewriteEngine on
    
        RewriteCondition %m USER
        RewriteRule ^(.*#)?([0-9A-Za-z]+)(@)? $2
      </IfModule>
    

    And if you simply wanted to have all user names be in lowercase, despite what the FTP clients send, it's merely a matter of:

      <IfModule mod_rewrite.c>
        RewriteEngine on
    
        RewriteMap lowercase int:tolower
        RewriteCondition %m USER
        RewriteRule (.*) ${lowercase:$1}
      </IfModule>
    

    Handling Clients' Bad PORT Commands
    A ProFTPD admin encountered a case where one of their customers refused to use anything but the standard command-line FTP client that comes with Windows. That FTP client does not support passive data transfers; it always uses the PORT command to do active data transfers. However, one issue with the PORT command is that the parameter contains an IP address. In this situation, the FTP client was behind a NAT, and the client was sending the internal LAN address in its PORT command. Could mod_rewrite be used to solve the problem, and allow that bad FTP client to use active data transfers despite its' sending of an unusable (to the FTP server) IP address? Yes!

    The solution was to use mod_rewrite to rewrite the address in the sent PORT command, replacing the internal LAN address with the IP address of the client that proftpd saw. Below is the configuation used to make this work:

      # This is necessary, to keep proftpd from complaining about mismatched
      # addresses in this situation
      AllowForeignAddress on
    
      <IfModule mod_rewrite.c>
        RewriteEngine on
    
        RewriteMap replace int:replaceall
    
        # Substitute in the IP address of the client, regardless of the address
        # the client tells us to use in the PORT command
        RewriteCondition %m ^PORT$
        RewriteRule ([0-9]+,[0-9]+,[0-9]+,[0-9]+)(.*) ${replace:/$1/$1/%a$2}
    
        # Replace the periods in the client address with commas, as per RFC959
        # requirements
        RewriteCondition %m ^PORT$
        RewriteRule (.*) ${replace:/$1/./,}
      </IfModule>
    

    SITE Commands
    The mod_rewrite module can also handle some SITE commands, specifically:

    • SITE CHGRP
    • SITE CHMOD
    These being supported by the mod_site module, which is part of the normal proftpd build.

    One site needed to make sure that any backslashes (e.g. used by Windows clients) were translated to slashes, including in these SITE commands. As of ProFTPD 1.3.2 (see Bug #2915), this can be accomplished using the following:

      <IfModule mod_rewrite.c>
        RewriteEngine on
        RewriteMap replace int:replaceall
        RewriteCondition %m "^SITE CHMOD$" [NC]
        RewriteRule "^(.*) +(.*)$" "$1 ${replace:!$2!\\\\!/}"'
      </IfModule>
    
    Notice how, for SITE CHGRP and SITE CHMOD commands, the %m parameter in the RewriteCondition must match the string "SITE CHGRP" or "SITE CHMOD", not just "SITE". This is important -- and it only works for the SITE CHGRP/SITE CHMOD commands. The use of the "[NC]" modifier helps to catch those cases where the client might send "SITE chmod", for instance.

    Redirecting FTP Requests
    One user wanted to know if mod_rewrite could be used to redirect a request, just like one might do using Apache's mod_rewrite, something like:

      RewriteRule /(.*) ftp://newname.domain.com/$1
    
    The above RewriteRule would work, but it would not actually redirect the FTP client to the URL. FTP unfortuntely does not support redirection of requests to other servers, at the protocol level, unlike HTTP.

    However, it is possible to redirect a request to some other directory on the same machine. For example, if you wanted to have any file uploaded by a client go into the "/Incoming/" directory, no matter where the client wanted to upload the file, you could use:

      <IfModule mod_rewrite.c>
        RewriteEngine on
        RewriteCondition %m STOR
        RewriteRule (.*/)?(.*) /Incoming/$2
      </IfModule>
    

    URL Encoded Characters
    On very rare occasions, you may find yourself dealing with URL-encoded characters in your FTP command parameters. If you have worked with web servers and URLs, you will accustomed to seeing sequences like "%20" in URLs; these are URL encoded characters (as per RFC2369). Unescaping these URL-encoded sequences is exactly what the "unescape" RewriteMap builtin function handles.

    Handling Non-ASCII Characters
    If you need to handle non-ASCII characters in your mod_rewrite rules, then you may need to generate your configuration using a scripting language, rather than using your editor. For example, my editor does not handle non-ASCII characters well; it displays them as ?.

    Here's an example, using Perl, to replace "ä" with "ae" in uploaded file names. Note that "ä" in hex notation is 0xE4:

      my $rewrite_rule = 'RewriteRule (.*) ${replace:/$1/' . chr(0xE4) . '/ae}';
    
      my $config = '/path/to/proftpd.conf';
      if (open(my $fh, "> $config")) {
        print $fh EOR;
    
      <IfModule mod_rewrite.c>
        RewriteEngine on
        RewriteLog /path/to/rewrite.log
    
        RewriteCondition %m ^STOR$
        $rewrite_rule
      </IfModule>
    EOR
      }
    

    Time-Related Content
    What if you find yourself wanting to serve different files based on the time of day, day of the month, etc? Or what if you wanted to put an automatic timestamp on the names of files being uploaded? Starting with proftpd-1.3.5rc1, these things are now possible using mod_rewrite; see the time-related variables in the RewriteCondition documentation.

    To demonstrate the concept of time-related content, let's assume that you have a two different files, one for "daytime" and one for "nighttime". Depending on when a client connects and requests this file, you can have mod_rewrite transparently point the client to the correct file. Let's show how this might work:

      <IfModule mod_rewrite.c>
        RewriteEngine on
        RewriteLog /path/to/rewrite.log
    
        # For requests of index.txt during the day, rewrite the command to
        # be for index.txt.day
        RewriteCondition %m RETR
        RewriteCondition %f index.txt$
        RewriteCondition %{TIME_HOUR}%{TIME_MIN} >0700
        RewriteCondition %{TIME_HOUR}%{TIME_MIN} <1900
        RewriteRule ^(.*) $1.day
    
        # For requests of index.txt during the night, rewrite the command to
        # be for index.txt.night
        RewriteCondition %m RETR
        RewriteCondition %f index.txt$
        RewriteCondition %{TIME_HOUR}%{TIME_MIN} <0700
        RewriteCondition %{TIME_HOUR}%{TIME_MIN} >1900
        RewriteRule ^(.*) $1.night
    
      </IfModule>
    

    Another use case involving time is the case where you might want to automatically timestamp every file being uploaded. To do this, you can use mod_rewrite like so:

      <IfModule mod_rewrite.c>
        RewriteEngine on
        RewriteLog /path/to/rewrite.log
    
        # Automatically timestamp all uploaded files with ".DD-MM-YYYY".
        RewriteCondition %m STOR
        RewriteRule (.*) $1.%{TIME_DAY}-%{TIME_MON}-%{TIME_YEAR}
      </IfModule>
    

    Or maybe you have a special file that should only be available for a month, and then be inaccessible? To do this, you would first give the special file a name that includes a timestamp, e.g. "special.bin-01-2013". Then have the following mod_rewrite configuration:

      <IfModule mod_rewrite.c>
        RewriteEngine on
        RewriteLog /path/to/rewrite.log
    
        RewriteCondition %m RETR
        RewriteCondition %f special.bin$
        RewriteRule (.*) $1-%{TIME_MON}-%{TIME_YEAR}
      </IfModule>
    
    Now, if the "special.bin" file is requested during January 2013, the RETR request will be rewritten and will match the name of the file on disk; the file is accessible, and the download succeeds. If the same file is requested any other time than during January 2013, then the mod_rewrite-rewritten path will not match the name of the file on disk, and the download will fail.
    proftpd-dfsg-1.3.5~rc3/doc/howto/KeepAlives.html0000644000175000017500000004740312120462723021377 0ustar frankiefrankie ProFTPD mini-HOWTO - ProFTPD KeepAlives

    ProFTPD KeepAlives


    Overview of KeepAlive
    Any discussion of so-called "keep-alive" functionality must start by answering the question: "What is does 'keep-alive' mean?" As one specification succintly states:

      A "keep-alive" mechanism periodically probes the other end of a connection
      when the connection is otherwise idle, even when there is no data to be sent.
    
    Keepalive mechanisms appear in many different protocols, under various names. Protocols may be layered over the top of another protocol; for example, HTTPS consists of HTTP layered over SSL/TLS, itself layered over TCP/IP. Each protocol layer may have its own form of such keepalive functionality.

    TCP KeepAlive
    For TCP, the definitive specification for keepalive functionality is
    RFC 1122, Section 4.2.3.6. While RFC 1122 includes a good discussion of why TCP keepalives are meant to be off by default, in practice TCP keepalives do have value, especially when dealing with network equipment (such as routers, firewalls, NATs) between the client and the server; such equipment might terminate the connection when the connection has been idle for too long. The use of TCP keepalives can help to prevent such network equipment from breaking the connection needlessly.

    How TCP KeepAlives Works
    OK, so you want to use the TCP keepalive functionality in your program. The question is "How exactly does the TCP keepalive feature work?" Good question. Answering this requires three different numeric values: the idle time, the number of probes to send (the probe count), and the interval time between each probe. Remember, though, that the SO_KEEPALIVE TCP socket option must be enabled on the socket in order for the TCP keepalive feature to be used.

    First, let's assume that you have created a TCP connection, and have transferred data back and forth on that connection. All of the data have been transferred, but you have not closed the connection, so now it is idle. How long does that connection sit idle, with no data transferred at the TCP layer, before one end of the connection or the other starts to wonder whether the connection is still alive? This amount of time where the connection sits idle is the TCP keepalive idle time; the default idle time is two hours (per RFC 1122).

    Our TCP connection has been sitting idle now for amount of time given by the idle time value; what happens then? At this point, the end of the TCP connection with TCP keepalive enabled sends out a "probe". This probe is just a small TCP packet which requires a response from the other side. Once the probe has been sent, the amount of time given by the interval time value passes. If we hear nothing back from the remote peer within the interval time, we send another probe. This process repeats until either a) we receive a response back from the peer, or b) the probe count value has been reached.

    Let us assume that our TCP connection was idle for so long that TCP keepalive probes were sent, and still no response was received. What happens then? At this point, the connection is broken. When the programs at either end of the connection next try to read or write data on that connection, the read/write attempts will fail.

    When To Use TCP KeepAlive
    When the TCP client is connected directly to the TCP server, it usually does not matter whether one end or the other uses TCP keepalive. As long as one of them does, a broken connection can be detected.

        client <-------------------------------> server
    
    However, if the TCP client connects to the TCP server via proxies/routers/firewalls/NAT, the picture changes. When this happens (and it is the common scenario), then both sides may need to use TCP keepalive to learn when their side of the proxied connection is broken:
        client <-----------> NAT <-------------> server
    
    In this situation, there are actually two different TCP connections involved: between the client and the NAT, and between the NAT and the server. Each TCP connection may break independently of the other, which is why both ends of the connection (client and server) may need to use TCP keepalives. Use of TCP keepalives also helps here because when the router/firewall/NAT receives the TCP keepalive probe, it may (depending on the network equipment in question) cause the router to reset any timers that were about to close the TCP connections on either side.

    Why are TCP KeepAlives Useful for FTP?
    "This is all very fascinating", you say, "but what does it have to do with proftpd and FTP?" If you have ever had an FTP download (or upload) take a very long time, only to have that transfer timed out in the middle, then TCP keepalives may prevent the timeout.

    Consider what happens for FTP transfers which take a long time (either due to very large file(s) being transferred, or a slow connection): you have one TCP connection for the control connection, and a separate TCP connection for the data transfer conenction. All of the bytes are being transferred over the data connection, so that data connection is certainly not idle -- but while the data transfer is occurring, the control connection is idle! And let's assume that your FTP connections are going through some NAT device in between the client and the server. That NAT may not be very smart; it may not know that the two different TCP connections of your FTP session are related to each other; it only sees one idle TCP connection, and one busy TCP connection. If that FTP control connection is idle for too long, then the NAT may close it (in order to keep valuable space in its state tables available for TCP connections that actually need to transfer bytes). (Some NATs have been known to close TCP connections that have been idle for only 5 minutes.) The FTP server sees that the FTP control connection is closed, and aborts the data transfer. What a mess!

    If either the FTP server or the FTP client had used TCP keepalives on the control connection, then maybe that NAT would have seen the TCP keepalive probes, and not closed the idle control connection. So how can we make sure that either the client or the server has TCP keepalives enabled?

    In proftpd-1.3.5rc1 and later, ProFTPD's SocketOptions directive supports a keepalive parameter for controlling whether the server uses TCP keepalives, e.g.:

      # Disable use of TCP keepalives
      SocketOptions keepalive off
    
      # Enable use of TCP keepalives (this is the default)
      SocketOptions keepalive on
    
    In addition, on some Unix platforms, the SocketOptions directive's keepalive parameter can do finer-grained tuning of the TCP keepalive values:
      # Enable use of TCP keepalives, with the given idle/count/interval values
      SocketOptions keepalive 7200:9:75
    
    In general, though, you should use the system-wide defaults unless you are running into data transfer timeout issues. If you are seeing timeouts, try using the keepalive parameter of SocketOptions to gradually reduce the idle timeout by small increments (e.g. 10-15 seconds), then if that does not help, increment the count by 1 at a time (remember that each probe is more extra data transfer), then if that still does not help, increase the interval time. Do not reduce the interval time, since that is the amount of time that you should wait to see if the other end responds, before sending another probe. Waiting less time before the other end responds means a greater chance of killing your TCP connection unnecessarily.

    Not all TCP stacks let the application control the TCP keepalive timeout after which the first probe will be sent, or the total number of probes sent, or how much time between probes will be used. That is, many TCP stacks only allow enabling/disabling of TCP keepalive. If TCP keepalive is enabled, then the standard values of 2 hours for the idle timeout, a count of 9 probes, with 75 seconds between probes, will be used.

    Since many platforms do not allow fine-grained tuning of TCP keepalive values, especially on a per-service basis, other means for checking whether the connection is still alive must be used. And that leads us to application-level keepalive mechanisms.

    FTP KeepAlive
    If tuning TCP keepalives does not work to keep your long-lasting data transfers from timing out, what can be done? Answer: use keepalive features at other layers in the protocol stack. FTP has its own ideas for doing keepalive checks, but they are not as elegant as that of TCP.

    The main issue with FTP keepalives is that they are all initiated by the client. FTP is a request/response model, and it does not allow for the FTP server to send arbitrary unrequested data to the FTP client via the control connection. Fortunately, there are many FTP clients which implement some sort of FTP keepalive feature.

    How FTP KeepAlive Works
    Since the FTP server cannot do anything to test whether the FTP session is alive, the FTP client must do the tests. The easiest way to test whether an FTP session is alive is to send an FTP command. And fortunately,
    RFC 959, Section 4.1.3 defines the NOOP ("No Operation") command whose sole purpose is to elicit the "OK" response from the FTP server. This makes the NOOP command the ideal way to test whether the FTP server is still alive and listening to the FTP client.

    Some firewalls/routers know about this NOOP trick, though, and may filter out/drop that FTP command. FTP clients, then, have been known to resort to a number of other FTP commands for use as FTP keepalives, including:

    • NOOP
    • LIST
    • STAT
    • CWD
    • REST 0
    • PWD
    • TYPE A
    Some FTP clients even choose a command at random from the above list, just to keep any interfering router/firewall/NAT guessing!

    Sadly, some FTP servers cannot handle receiving an FTP command on the control connection while they are in the middle of transferring data on the data connection (proftpd can handle this). But that may not matter, for the purposes of FTP keepalives; all that matters is that at the TCP level, the bytes were sent by the client and acknowledged by the server's TCP stack.

    FTP Client-Specific KeepAlive Settings
    Not every FTP client supports the FTP keepalive functionality. If you want to try out FTP clients which do support FTP keepalives, you might look into the ftp:nop-interval setting for lftp, or the control-timeout setting for ncftp.

    SSH KeepAlive
    The SSH2 protocol (and SFTP, which runs over SSH2) is more complex than FTP, and thus has much better support for application-level keepalive functionality. Either end of an SSH2 connection can send messages at any time.

    How SSH KeepAlive Works
    The usual mechanism used by SSH2 implementations for implementing an SSH2-level keepalive check is send either a CHANNEL_REQUEST or a GLOBAL_REQUEST message for a known unsupported command, and to request a response from the other side. It does not matter that the requested command is unsupported; all that matters is that the response comes back, signifying that the other end is still alive and listening. Both clients and servers use this technique.

    In the case of ProFTPD's mod_sftp module, the way to configure SSH2 keepalives is the SFTPClientAlive directive. When configured, the mod_sftp module sends CHANNEL_REQUEST/GLOBAL_REQUEST messages for "keepalive@proftpd.org" in order to solicit a response from the connected client.

    KeepAlive in Other Protocols
    Many application protocols end up reinventing the keepalive feature in some way, usually as a "ping/pong" mechanism where a "ping" is sent every so often by one side, with a "pong" response expected from the other end of the connection.

    HTTP
    Most HTTP connections have no need of a keepalive mechanism since HTTP connections are usually short-lived, and since there are usually data flowing in one direction or the other on the HTTP connection (thus an HTTP connection is usually not idle for long enough time to warrant a keepalive feature). HTTP long polling (i.e. RFC 6202) is an exception; and for HTTP long polling connections, use of TCP keepalives may be needed. But the HTTP protocol itself does not specifically define a way for either end to arbitrarily send data across the connection for the purpose of determining whether the connection is still alive. (HTTP keepalive refers to a different concept, i.e. that of telling the server to not close the connection after sending its response so that the connection can be reused, thus "kept alive".)

    LDAP
    For long-lived LDAP connections, keepalive functionality can be implemented by using the Abandon operation, as described here. The idea is to have the client send a request that it knows the server will ignore/discard; the act of transmitting the request over the connection acts to keep any intermediaries on the network (router/NAT/firewall) from closing an "idle" connection prematurely.

    WebSocket
    The WebSocket protocol, defined in RFC 6455, does have need of a keepalive mechanism, since it establishes a long-lived connection. Thus does the RFC define ping/pong messages; see Section 5.5.2 (PING), and Section 5.5.3 (PONG).

    Additional Reading

    Frequently Asked Questions

    Question: When should I use application-level keepalives like FTP or SSH2 keepalives instead of TCP keepalives? Or can I use them all at the same time?
    Answer: There is no issue with using the different types of keepalives at the same time; remember that each type of keepalive functions at a different protocol layer.

    That said, if you have to choose, I would recommend using the application-level keepalive feature when you can, as opposed to TCP keepalives. Why? First, you probably have more control over when the application-level keepalive feature is used than if you used TCP keepalives (e.g. you can use the application-level keepalive check more frequently than the TCP keepalive feature would detect a dead connection).

    Second, TCP keepalives may not cause a NAT to keep the TCP connection on each side open, but an application-level keepalive should do so, since the application-level keepalive data must traverse both connections:

               <------------ SSH2 REQUEST ----------->
               -------------- FTP NOOP -------------->
        client <---------------> NAT <---------------> server
               <-- TCP probe -->     <-- TCP probe -->
    

    Question: Why should I use SocketOptions to configure proftpd's TCP keepalive settings, as opposed to changing some of the sysctls on my machine that apply to TCP KeepAlives?
    Answer: Using the SocketOptions directive means that your TCP keepalive tunings will only affect the FTP/SFTP connections to proftpd, instead of applying to all TCP connections to your machine. FTP/SFTP sessions, being long-lived, probably have different keepalive timing needs than from other TCP connections, so it is best to tune their settings separately, without impacting all connections to that machine.

    Question: If TCP keepalives are so useful, why not tune them to be quite short? Why does RFC 1122 recommend a default of two hours before checking if the peer is still there?
    Answer: There are a couple of reasons why you might not want to tune your TCP keepalive settings to be shorter.

    First, keep in mind that TCP was designed to keep the TCP level connection "alive" even though various parts of the underlying hardware, such as routers, firewalls, etc might crash and be rebooted in the middle of things. This is why TCP retransmits lost packets, routes around unresponsive hops, etc. If, then, your TCP keepalive settings are aggressively short, your TCP connection may be shut down (due to not responding to TCP keepalive probes in time) because of a crashed network component. The recommended default of two hours allows for such network route changes without losing the TCP connection.

    Second, every TCP keepalive probe counts as more data transferred over your network link. Some links may have exorbitantly high rates for transferred bytes (think satellite links), so on such links, keeping the number of bytes transferred down amounts to cost savings. Tuning TCP keepalive to use shorter times on such links means more data transferred, thus higher costs. On other links, where data transfer rates are cheap, the additional bytes transferred due to shorter TCP keepalive settings may be neglible.

    Last, many people argue that use of TCP keepalives may consume unnecessary bandwidth. The question becomes "If no one is using the connection, who cares if the connection is still good?" (To be fair, this argument makes more sense when the connected peers are not separated by proxies, gateways, and NATs.)


    $Date: 2013/03/15 00:05:39 $
    proftpd-dfsg-1.3.5~rc3/doc/howto/Classes.html0000644000175000017500000001402011023525723020732 0ustar frankiefrankie ProFTPD mini-HOWTO - Classes

    Classes


    What are Classes?
    When configuring proftpd, it is sometimes nice, or even necessary, to tag or label a client as belonging to some group, based on that client's IP address or DNS hostname. A "class" is the name for such connection-based groupings in ProFTPD terms. A class is defined to have a name, and as having certain criteria such as IP addresses, IP subnets/masks, and DNS hostnames. A client that connects to the daemon that has matching characteristics is then labeled as belonging to that class. Note that a connecting client can belong to only one class; see the description below for how the winning class is selected for a session from among multiple possible matches.

    How are Classes Defined?
    To define a class, use a <Class> section in your proftpd.conf:

      <Class internal>
        From 192.168.0.0/16
      </Class>
    
    This defines a class named "internal"; any client connecting from 192.168.0.0/16 will belong to this class. And if you wanted to define a class for all clients not connecting from 192.168.0.0/16 address space:
      <Class external>
        From !192.168.0.0/16
      </Class>
    
    A more complicated class might include matching DNS names as well:
      <Class test>
        From 1.2.3.4
        From proxy.*.com
        From my.example.com
        From 5.6.7.8
      </Class>
    
    This "test" class will then be used for a client with any of the defined characteristics.

    Note that if your class rules use only DNS names, and proftpd is unable to resolve the IP address of a client to a DNS name, that class may not be matched as you might expect. This can be seen in the server debugging output, at level 10, as something like:

      comparing DNS name '1.2.3.4' to pattern 'proxy.*.com'
    
    Here you see the 1.2.3.4 IP address, where a DNS name should be. In order for DNS name based class rules to function properly, both a) DNS resolution is needed (i.e. UseReverseDNS must be on, which is the default), and b) the IP address of a connecting client must be resolvable to a DNS name.

    What if there are multiple classes defined, and the classes overlap, e.g. two classes both have:

      From *.example.com
    
    Which one will be used for the connecting client? This will depend on the order in which classes are defined in the proftpd.conf file. When searching the list of classes for the one that matches the client, proftpd checks each class in the order in which they are defined. The first class definition (in order of appearance in proftpd.conf) that matches is used.

    How do you define a class that includes all clients from a certain domain except one specific host in that domain? To define a class with these sorts of characteristics, use the Satisfy configuration directive:

      <Class foo>
        From *.example.com
        From !bad.example.com
        Satisfy all
      </Class>
    

    Using Satisfy
    The Satisfy directive, when used within a <Class> section, indicates whether any of the From rules in the section need to match, or whether all of the From rules in the section need to match. The default Satisfy setting for a <Class> section is "any".

    To illustrate, the following class definition will never match:

      <Class impossible>
        From 127.0.0.1
        From !127.0.0.1
        Satisfy all
      </Class>
    
    It is impossible to both an address and not match that same address, but that is what is demanded by the "Satisfy all" setting in the above class definition.

    Now, where the use of "Satisfy all" comes in handy is when you have a general rule with exceptions:

      <Class customers>
        From .domain.com
        From !host1.domain.com !host2.domain.com
        Satisfy all
      </Class>
    
    Specifically, the use of "Satisfy all" is necessary when you have multiple not matches (i.e. using the ! prefix), all of which need to be evaluated.

    How are Classes Used?
    By itself, a class does nothing. It is merely a way to define a set of clients and to give that set a name. Once that name is defined, though, it can be use as part of your configuration. There are a limited number of configuration directives that make use of classes directly:

    • AllowClass
    • DenyClass
    • DisplayGoAway
    • MaxClientsPerClass
    The AllowClass and DenyClass directives are the main directives to use, for example in <Limit> sections:
      <Limit ALL>
        AllowClass internal
        DenyAll
      </Limit>
    

    The mod_ifsession module also makes use of classes with its <IfClass> configuration section. Using classes and mod_ifsession, you can write a proftpd.conf that has specific configurations for specific classes of clients. Here's an example snippet demonstrating use of <IfClass>:

      <IfClass internal>
        MaxClients 100
      </IfClass>
    
      <IfClass !internal>
        MaxClients 25
      </IfClass>
    
    This allows clients from class "internal" to see an effective MaxClients limit of 100 simultaneous clients, and clients not in class "internal" to see an effective limit of only 25.


    Last Updated: $Date: 2008/06/10 16:29:07 $

    proftpd-dfsg-1.3.5~rc3/doc/howto/Memcache.html0000644000175000017500000002213112142631774021050 0ustar frankiefrankie ProFTPD mini-HOWTO - ProFTPD and Memcache

    ProFTPD and Memcache


    What is Memcache?
    Memcache (or "memcached") is an open-source, high performance memory object caching system. A simple (and effective) key/value store accessible, efficiently, over the network.

    How Can Memcache Be Useful for ProFTPD?
    Like any high-performance object store, memcached offers several possibilities to a server like proftpd. Many sites use memcached for caching; it can also be used as an efficient shared storage mechanism, for sharing data among many different servers. And for ProFTPD specifically, the shared storage aspect is what is most useful. Things like SSL/TLS sessions can be cached and shared across a pool of proftpd servers, as can ban lists for badly-behaved clients.

    Enabling Memcache Support for ProFTPD
    OK, so you are interested enough in the possibilities that memcached offers that you want to try it out. Excellent! To do this, you will first need to make sure to build your proftpd executable using the --enable-memcache configure option. The --enable-memcache configure option automatically adds the mod_memcache module to your proftpd build.

    The mod_memcache module uses the libmemcached library for talking to memcached servers. If your libmemcached library is installed in a non-standard location, you may need to tell the ProFTPD build system where to find the libmemcached header files and libraries using the --with-includes and --with-libraries configure options.

    There are other modules which make use of memcached support when available, such as mod_tls_memcache. Thus to take advantage of modules like this, putting everything together, your configure command might look like this:

      $ ./configure --enable-memcache \
        --with-modules=...:mod_tls_memcache:... \
        --with-includes=/path/to/libmemcached/include \
        --with-libraries=/path/to/libmemcached/lib
    

    Configuring mod_memcache
    Now that you have compiled proftpd with the mod_memcache module, you need to add the necessary mod_memcache directives to your proftpd.conf. The following example demonstrates this:

      <IfModule mod_memcache.c>
        # Enable mod_memcache
        MemcacheEngine on
    
        # Tell mod_memcache where to log its messages
        MemcacheLog /path/to/proftpd/memcache.log
    
        # Tell mod_memcache where to find the memcached servers
        MemcacheServers 192.168.0.10:11211 192.168.0.11:11211
      </IfModule>
    
    If you wish to see more detailed logging, at least while you are setting up your memcached servers for ProFTPD, you can enable trace logging for the memcache trace channel using e.g.:
      TraceLog /path/to/proftpd/trace.log
      Trace DEFAULT:10 memcache:20
    

    Using Memcache for Shared Storage
    You have now compiled support for memcached into proftpd, and you have told the mod_memcache module where to find your memcached servers. Is that all you need to do? No. Now you need to tell proftpd modules which bits of data to store in your memcached servers.

    Currently, only two modules can take advantage of memcached support: mod_ban and mod_tls_memcache.

    First, let us examine mod_ban and how it would use memcached. The mod_ban module manages ban lists, lists of clients/users which have been banned for various reasons. These lists are stored in shared memory by default; this works for a single proftpd server, but if a badly behaved client is banned by one proftpd server in pool of servers, that client can then connect to a different server which might not have a ban for that client -- and the client then gets another chance to be naughty. To configure mod_ban so that it stores its ban lists in memcached, simply use the following in your proftpd.conf:

      <IfModule mod_ban.c>
        BanEngine on
    
        # ...other mod_ban directives...
    
        # Tell mod_ban to store its ban lists using memcache
        BanCache memcache
      </IfModule>
    
    With this, mod_ban will use memcached (as well as shared memory) for reading/writing its ban lists. And this, in turn, means that other proftpd servers' mod_ban modules can see those bans, and reject the badly behaved clients across the pool/cluster.

    The mod_tls_memcache module uses memcached servers for storing SSL/TLS sessions; SSL/TLS session caching can greatly improve SSL/TLS session handshake times, particularly for data transfers using SSL/TLS. If you have a pool of proftpd servers, and you have FTPS clients which may connect to a different node every time, caching the SSL/TLS session data in a shared storage mechanism like memcached can be quite beneficial.

    To use memcached for SSL/TLS session caching, then, you use the TLSSessionCache directive of the mod_tls module, using something like this in your proftpd.conf:

      <IfModule mod_tls.c>
        TLSEngine on
    
        # ...other mod_tls directives...
    
        <IfModule mod_tls_memcache.c>
          # Tell mod_tls to cache sessions using memcached
          TLSSessionCache memcache:
        </IfModule>
      </IfModule>
    
    That's it. The mod_tls module now knows to give the SSL/TLS session data to mod_tls_memcache, and mod_tls_memcache knows how to talk to the memcached servers using mod_memcache.

    Frequently Asked Questions
    Question: If I don't use memcache, are there other ways for sharing data (such as ban lists) among different proftpd instances?
    Answer: Not really. It might be possible using mod_sql and some SQLLogInfo directives, but that would only work for very specific information. For sharing things like ban lists and SSL/TLS sessions across a cluster of proftpd servers, memcache support is required.

    Question: Can I use mod_memcache to cache rerequently accessed files, similar to nginx+memcache?
    Answer: No. And in reality, caching of files like that will probably not give you the same performance gain for FTP transfers as it can for HTTP transfers.

    Why not? Many HTTP transfers are for dynamically generated pages; the cost of generating each page is expensive, and the generated content may not change that frequently (relative to the rate of requests). FTP transfers, by contrast, are for static files; FTP servers do not (usually) dynamically generate the bytes of the files being downloaded. The cost of reading files from disk is probably less than reading files from memcached over the network, even a LAN.

    Now the above may not be true in all cases -- there may be FTP servers serving files from network-mounted filesystems (e.g. NFS, CIFS et al). And for these very specific cases, having a cache of frequently access files on closer storage such as local disk (or memcached) could make a big difference; please contact the ProFTPD Project if you find yourself in this situation, and we will see what can be done to help.

    Question: Why do I see the following error when proftpd starts up?

    mod_tls_memcache/0.1: notice: unable to register 'memcache' SSL session cache: Memcache support not enabled  
    
    Answer: This message means that your proftpd server has mod_tls_memcache built and loaded, but your proftpd server was not built with memcache support (i.e. the --enable-memcache configure option was not used when compiling proftpd).

    The above is not a fatal or worrisome error; it is merely pointing out that some of your modules want to use a feature that was not enabled.


    $Date: 2013/05/09 05:28:28 $
    proftpd-dfsg-1.3.5~rc3/doc/howto/Translations.html0000644000175000017500000000711111073163006022016 0ustar frankiefrankie ProFTPD mini-HOWTO - Translations

    Translations


    Translations
    ProFTPD has support for translating the messages sent to clients in the FTP responses. To enable use of these translations in your proftpd, you must compile proftpd using the --enable-nls configure option. This causes the mod_lang module to be compiled into your proftpd.

    ProFTPD uses the gettext code package for translation support.

    Adding a New Translation
    To add a new language translation to proftpd, first check to see if the language in question already has a translation. ProFTPD's translations are kept, in the source distribution, under the locale/ directory, e.g.:

      ls /path/to/proftpd-version/locale/*.po
    

    To create a new translation, you first initialize a .po file for your translation using the template PO file (proftpd.pot):

      cd proftpd-version/locale/
      msginit -i proftpd.pot -o lang.po -l lang
    
    Then you simply use an editor to edit the generated lang.po file, adding in the translated versions of the English messages. There are some good editors out there which greatly aid in editing .po files:

    Testing a Translation
    Once you think your .po file is ready, you should run some quick checks to make sure. First, compare your .po file against the template .pot file to see if you translated all of the messages in the template. This is accomplished using the msgcmp command:

      cd proftpd-version/locale/
      msgcmp lang.po proftpd.pot
    

    Finally, compile your .po file into the machine-specific .mo file; this is what the gettext library uses in the running code:

      msgfmt --check-format lang.po -o lang.mo
    
    The --check-format option checks that your .po is properly formatted, and can be compiled without errors.

    Submitting Translations
    Once your .po file has been tested and looks ready, simply open a feature request at:

      http://bugs.proftpd.org/
    
    to request that the new translation be added to ProFTPD. Upload your .po file as an attachment to the opened feature request.

    Keeping Translations Updated
    Note that as ProFTPD is developed, new messages may be added to the template .pot file, or existing messages may be changed slightly. It is important to keep ProFTPD's translations up-to-date. You can help by periodically checking the existing translations:

      cd proftpd-version/locale/
      make check
    
    If you see that a language translation is out of date and you can help, simply update the .po file that language, and open a bug request and attach the diff, or send the diff to the ProFTPD developers mailing list.


    $Date: 2008/10/08 16:55:34 $
    proftpd-dfsg-1.3.5~rc3/doc/howto/DNS.html0000644000175000017500000001603711145122634017772 0ustar frankiefrankie ProFTPD mini-HOWTO - DNS

    ProFTPD and DNS


    FTP, DNS Names, and IP Addresses
    FTP is an IP address-based protocol. FTP clients connect to specific IP address/port combinations; FTP servers handle client connections by listening on IP addresses. No DNS or host names are exchanged by clients and servers. FTP does not support name-based virtual hosts, as HTTP 1.1 does.

    The above may seem obvious, but it must be reiterated often. Users can become confused, since FTP clients and servers often use DNS names, rather than explicit IP addresses. This is not surprising, as DNS names are easier to use than IP addresses. The clients and servers resolve those DNS names to their IP addresses, behind the users' backs.

    All of this means that whenever proftpd is given a DNS name, it will resolve that DNS name to its IP address, and then use the IP address.

    When are DNS Names Resolved?
    When proftpd starts up and parses its configuration file, it expects to handle DNS names in the following configuration directives, if they are present:

      Allow
      DefaultAddress
      Deny
      From
      MasqueradeAddress
      <VirtualHost>
    
    Note that if a DNS name resolves to an IPv6 address (and proftpd has been compiled with IPv6 support via the --enable-ipv6 configure option), then proftpd will handle it properly. Otherwise proftpd will attempt resolutions to IPv4 addresses only.

    Even if none of the above configuration directives are used, proftpd will still perform at least one DNS lookup: it will resolve the hostname of the server on which the daemon is running, i.e. the name displayed by typing `hostname`. Why does proftpd need to know this? There is always at least one server that proftpd will handle: the "server config" server (see the virtual host howto). This "server config" server defaults to the IP address of the hostname of the machine.

    Once proftpd has the complete list of IP addresses with which it work will while running, it completes its startup, and is ready to handle connections from FTP clients. The running daemon will continue doing DNS lookups when necessary. For example, every time connection is made to a proftpd daemon, or proftpd connects back to a client (as when handling active data transfers), the remote IP address is resolved to its DNS name. In addition, once the DNS name is found, that name is resolved back to an IP address. Why the additional step, when we already have the original IP address? It is possible, either through ignorance or maliciousness, to configure DNS such that an IP address will map to a name, and that name will map back to a different IP address. Configurations such this can be used to foil some DNS-based ACLs. ProFTPD now deliberately checks for such configurations.

    DNS resolution from an IP address and back can add noticeable delays to the FTP session, particularly when there are many data transfers occurring and proftpd is performing the reverse DNS lookup for each one. This penalty can easily be removed by using the UseReverseDNS configuration directive:

      UseReverseDNS off
    
    However, you should do this only if you do not have ACLs that rely on DNS names. Otherwise, your ACLs will not work as you expect. Also, if UseReverseDNS is off, proftpd will log only IP addresses in its logs, rather than more legible DNS names.

    Clever users of ProFTPD know that you can use the Port directive to "disable" a given virtual host (including the "server config" host) by setting a port number of zero:

      Port 0
    
    By disabling the virtual host that way, can you prevent proftpd from resolving the IP address for that host? No. Using the Port 0 trick like this is a hack that affects the process used to lookup the configuration to use for a client connection; it does not affect the parser, which handles the address lookup when the daemon is starting up.

    Frequently Asked Questions
    Question: Why do I see the following when my proftpd starts up?

      getaddrinfo 'hostname' error: No address associated with hostname
      warning: unable to determine IP address of 'hostname'
    
    Answer: This error is ProFTPD's way of reporting that it was unsuccessful in resolving hostname to an IP address. Fixing this is a matter of configuring DNS for that hostname: properly set up an IP address for that DNS name in your DNS server, use a DNS name that has an IP address, or (as a quick fix/last resort) add that DNS name to your /etc/hosts file. The proper solution depends largely on the circumstances.

    Question: If proftpd resolves any DNS names to IP addresses when it starts up, and I am using dynamic IP addresses which change after my proftpd has started, will proftpd see my new IP addresses?
    Question: Unfortunately not. ProFTPD has no easy way of handling dynamic IP addresses by itself. One way of dealing with this situation is to restart proftpd periodically, which will force it to re-parse its configuration and thus re-resolve all IP addresses.

    Question: What if I do not want proftpd to use DNS to resolve the hostname to an IP address because I am in an environment where there is no DNS at all?
    Answer: In ProFTPD 1.3.3rc1, support for a new -S command-line option was added. This option can be used to specify the IP address of the host machine. By default, proftpd attempts to resolve the host IP address by using DNS resolution of the hostname. However, in cases where DNS is not configured for the host machine, this approach does not work.

    To specify the desired IP address, use -S when starting proftpd, e.g.:

      /usr/local/sbin/proftpd -S 1.2.3.4 ...
    
    And if you want proftpd to listen on all interfaces, you can specify a wildcard socket using an IP address of 0.0.0.0:
      /usr/local/sbin/proftpd -S 0.0.0.0 ...
    

    Note that will also mean that, in your proftpd.conf, any <VirtualHost> sections will need to use IP addresses, not DNS names.


    $Date: 2009/02/12 22:41:32 $
    proftpd-dfsg-1.3.5~rc3/doc/howto/Upgrade.html0000644000175000017500000000430011326110314020714 0ustar frankiefrankie ProFTPD mini-HOWTO - Upgrading ProFTPD

    Upgrading ProFTPD


    Upgrading proftpd is usually a straightforward process, but as with any upgrade, double-checking that the upgrade will not break anything is a Good Idea.

    Recent ProFTPD releases have a RELEASE_NOTES file in the source distribution that documents the changes in that release, including new configuration directives, new contrib modules, deprecated directives, special instructions, etc. In addition, the NEWS file contains a list of the bugs that have fixed, and comments about any changes the bugfix required. Please read these files carefully before starting your upgrade.

    One safe way to test the upgrade is to compile the new proftpd, and test it out on your existing configuration file before actually installing the new version into the "live" location:

      tar zxvf proftpd-version.tar.gz
      cd proftpd-version/
      ./configure ..
      make
      ./proftpd -t -d10 -c /path/to/proftpd.conf
    
    The "./proftpd" means to use the new proftpd binary compiled by make, but not yet installed. If the new binary reports errors, make a copy of your existing proftpd.conf file, keeping the old one as a backup:
      cp /path/to/proftpd.conf /path/to/proftpd.conf.new
    
    Make any needed changes to the proftpd.conf.new file, until the new proftpd binary reports a successful syntax check:
      ./proftpd -t -d10 -c /path/to/proftpd.conf.new
    

    Once everything is configured the way you like, install the new binary and configuration file:

      make install
      cp /path/to/proftpd.conf /path/to/proftpd.conf.old
      mv /path/to/proftpd.conf.new /path/to/proftpd.conf
    
    Now do a stop/start on proftpd, and the new version of ProFTPD will be running.


    $Date: 2010/01/21 17:37:16 $
    proftpd-dfsg-1.3.5~rc3/doc/howto/ConnectionACLs.html0000644000175000017500000001572511511142775022160 0ustar frankiefrankie ProFTPD mini-HOWTO - Connection ACLs

    Connection ACLs


    Many sites running proftpd have the need to limit/reject connections from known bad addresses, or to accept connections only from known good addresses. ProFTPD supports several different mechanisms for implementing FTP connection ACLs.

    However, there is one important thing to note: ProFTPD is not a firewall. Never forget this. You cannot prevent TCP connections from ever reaching proftpd in the first place by using proftpd itself. This means that for many sites with connection ACL needs, their system's firewall capabilities may be a better mechanism for implementing ACLs.

    <Limit LOGIN>, and Whitelists versus Blacklists
    The easiest way of accepting/rejecting connections is to use ProFTPD's
    <Limit> syntax, particularly <Limit LOGIN>.

    For example, you can simply reject all connections to your proftpd instance by using:

      <Limit LOGIN>
        DenyAll
      </Limit>
    
    A more practical example would look like:
      <Limit LOGIN>
        # These are trusted addresses
        Allow from 1.2.3.4 5.6.7.8
        Allow from trusted-domain.com
    
        # Everyone else is denied
        DenyAll
      </Limit>
    

    The above configuration demonstrates the concept of a whitelist: known trusted (i.e. "white") addresses are explicitly listed and allowed, and all others are denied. Conversely, you might use a blacklist, where known bad/malicious/untrusted (i.e. "black") addresses are explicitly listed and denied, and all others are allowed:

      <Limit LOGIN>
        Order deny,allow
    
        # These are known bad addresses
        Deny from 1.2.3.4 5.6.7.8
        Deny from evil-domain.com
    
        # Everyone else is allowed
        AllowAll
      </Limit>
    

    It is useful to know about whitelists versus blacklists, as it can affect how large your ACLs become. Sites which run publicly available FTP servers but which need to weed out bad clients tend to use blacklists; over time, these blacklists can become quite large. Sites which know who will be using their FTP server and only want those people to be able to connect will use whitelists; these whitelists tend to remain fairly small/short.

    Large Blacklists
    Let's assume that you are running a public FTP server, and that you are using a <Limit LOGIN> section to make a blacklist. Your site may even have some script which detects bad clients, and automatically adds them to your blacklist, e.g.:

      <Limit LOGIN>
        Order deny,allow
    
        # -- Add blacklisted addresses here --
        Deny from ...
        Deny from ...
        # Many more Deny from lines
    
        # Allow everyone not explicitly blacklisted
        AllowAll
      </Limit>
    
    Over time, your number of blacklisted IP addresses starts to become large and unwieldy. You might have thousands of such addresses; you notice that proftpd starts acting strangely, and starts slowing down.

    When this happens, you should start looking for ways to make your list shorter. If your list is comprised of entries for each individual IP address, you should think about using glob expressions and netmasks to reduce the number of entries. For example, rather than using something like this:

      Deny from 1.2.3.4
      Deny from 1.2.3.5
      Deny from 1.2.3.6
      Deny from 1.2.3.7
      Deny from 1.2.3.8
      Deny from 1.2.3.9
    
    you could (as of proftpd-1.3.4rc1 and later) use a range:
      Deny 1.2.3.[4-9]
    
    or even use a glob wildcard such as this, which makes for even fewer entries in your address lists:
      Deny 1.2.3.*
    
    Or you could use netmasks such as:
      Deny 1.2.3.0/8
    

    Using Classes
    Now let's assume that at this point you have used glob ranges and wildcards and netmasks to make your ACL shorter, but it is still large, and proftpd is still slow. It is time for you to use ProFTPD's connection classes.

    To do this, you would rewrite your large <Limit LOGIN> section to look something like this:

      <Class blacklist>
        # Put all of your blacklisted address/range lines here, as From lines
        From ...
        From ...
        From ...
      </Class>
    
      <Limit LOGIN>
        Order deny,allow
    
        # Rejected blacklisted clients
        DenyClass blacklist
    
        # Allow everyone else
        AllowAll
      </Limit>
    

    Why does using classes like this make things faster? When using classes, the label (i.e. the class name in the <Class> section, like "blacklist" in the above example) is determined when the client first connects to proftpd, before any comands are sent. That is when all of the various netmasks and such are checked -- and only at that time. After that, all of the configuration-based ACLs are evaluated just using that label.

    When you do not use classes, then proftpd scans each configuration, each netmask/address for each command. That's why things slow down so much.

    Alternatives
    There are a couple of other ways in which to implement connection ACLs; these alternatives may be more efficient and/or better suited to your site's needs.

    You can use a module like mod_wrap2, particular its support for storing ACLs in SQL tables. SQL lookups can be very quick, and can easily support large numbers of addresses efficiently.

    And if you find yourself starting to block large blocks of addresses from countries/regions, you should start thinking about connection ACLs in terms of geolocation information. For this, the mod_geoip module for proftpd is quite useful.

    Frequently Asked Questions

    Question: Is there a limit to how many addresses can appear in a single line in the config file?
    Answer: No. However, there is a maximum line length, which is determined by the buffer size used by the configuration file parser. That buffer size is usually 1024 bytes (1K).

    This 1024 byte length limitation can be worked around, however, by breaking a single line in the configuration file into multiple lines using the line continuation syntax, e.g.:

      Allow 1.2.3.4 5.6.7.8 9.10.11.12
    
    can also appear as:
      Allow \
        1.2.3.4 \
        5.6.7.8 \
        9.10.11.12
    


    Last Updated: $Date: 2011/01/05 19:26:53 $

    proftpd-dfsg-1.3.5~rc3/doc/howto/Versioning.html0000644000175000017500000001274111341344634021473 0ustar frankiefrankie ProFTPD mini-HOWTO - ProFTPD Release Versioning

    ProFTPD Release Versioning


    The names of ProFTPD releases, which indicate the version of ProFTPD, can be a little confusing to users new to the software. This document is a brief guide to the naming conventions used for ProFTPD release versions.

    Release Candidates
    Every development/release cycle of the ProFTPD software begins with series of release candidates (RCs), e.g. proftpd-1.3.2rc1. The "rc1" suffix in this example indicates that this is the first release candidate of the 1.3.2 development/release cycle. A suffix of "rc2" would be used for the second release candidate, and so on. The first release candidate (RC1) is where most of the new features of that development/release cycle tend to be added, including new core APIs, new modules, deprecated configuration directives are removed, etc. Subsequent release candidates tend to focus on stabilizing the new code and fixing bugs. There can be few or many release candidates, depending on the number of new features added and bugs encountered.

    Stable Release and Maintenance Branch
    Once the code base is considered stable, and the frequency of new bug reports has slowed down, then the "stable" release is cut. A "stable" release has no suffix in the name, e.g. proftpd-1.3.2. At the same time, the code is branched, creating a maintenance branch for that development/release cycle. The trunk continues on to become the basis for the next development/release cycle. At any given time, the ProFTPD Project team supports the most recent maintenance branch, and the current trunk. When a new maintenance branch is created, the previous maintenance branch is no longer supported. Thus when the 1.3.2 maintenance branch was created, the 1.3.1 series of releases became unsupported.

    Maintenance Releases
    During any given development/release cycle, bugs will be reported against older versions of ProFTPD. The fixes for those bugs will be developed using the current version of ProFTPD. If the bug is deemed to be serious enough, then the fix will be backported to the active maintenance branch as well. Serious bugs include security vulnerabilities, major bugs not found during the previous development/release cycle, and new translations. Thus there will continue to be releases for a given cycle after the "stable" release; these maintenance releases come from the maintenance branch. Maintenance release names use letters, rather than numbers, in the suffix portion of the release name/version. The first maintenance release will be "a" (e.g. proftpd-1.3.2a), the second will be "b", and so on.

    Using the 1.3.2 development/release cycle as an example, then, the releases for the cycle are:

    • proftpd-1.3.2rc1
    • proftpd-1.3.2rc2
    • proftpd-1.3.2rc3
    • proftpd-1.3.2rc4
    • proftpd-1.3.2
    • proftpd-1.3.2a
    • proftpd-1.3.2b
    • proftpd-1.3.2c
    • proftpd-1.3.2d
    • proftpd-1.3.2e

    Checking the Version
    If you are not sure of the version of ProFTPD you are running, the best way to check is to use the -V command-line option for proftpd. The -V option shows the various build-time options used for your proftpd; the version information is at the very beginning of that output:

      # proftpd -V 
      Compile-time Settings:
        Version: 1.3.2rc1 (devel)
    
    The above shows that the proftpd version on the machine is the first release candidate of the 1.3.2 development/release cycle. The portion of the version in parentheses, i.e. "(devel)" in the example above, is a version label. Version labels are intended to make it very clear which type of release that proftpd executable comes from, rather than having to figure it out based on the suffix of the version name. Release candidates always use a "devel" version label.

    If you are running a stable release, then you would see:

      # proftpd -V 
      Compile-time Settings:
        Version: 1.3.2 (stable)
    
    The version label for stable releases is always "stable", obviously. For completeness, here is what the -V output for a maintenance release looks like:
      # proftpd -V 
      Compile-time Settings:
        Version: 1.3.2a (maint)
    
    The version label for a maintenance is "maint".

    Finally, for developers and users who use the latest and greatest code from the trunk in CVS, you will see something like:

      # proftpd -V 
      Compile-time Settings:
        Version: 1.3.3rc1 (CVS)
    
    All code obtained from CVS reports a version label of "CVS".

    Frequently Asked Questions

    Question: When you say that older maintenance branches are no longer supported, what exactly does that mean?
    Answer: Support, in this case, refers to whether the ProFTPD Project team will provide patches for a bug that can be applied cleanly that version of the source code. Bugs can (and indeed should) be reported against that version, but the fixes will be applied in the newer, supported versions of ProFTPD instead of in the unsupported branches.


    $Date: 2010/02/25 00:51:40 $
    proftpd-dfsg-1.3.5~rc3/doc/howto/FTP.html0000644000175000017500000003664112067151505020005 0ustar frankiefrankie ProFTPD Supported FTP Commands

    ProFTPD Supported FTP Commands


    Supported FTP Commands

    • ABOR
    • ALLO
    • APPE
      Short for APPEnd.
    • AUTH
      Short for AUTHenticate (supported by mod_tls)
    • CDUP
      Short for Change Directory UP, this command is used to move the client's "location" on the server up one level in the filesystem hierarchy.
    • CWD
      Short for Change Working Directory.
    • DELE
      Short for DELEte, this command is used by the client to tell the server to delete a file.
    • EPRT
      Short for Extended PoRT, an enhanced version of the PORT command that can handle IPv6 addresses.
    • EPSV
      Short for Extended PaSsiVe, an enhanced version of the PASV command that can handle IPv6 addresses.
    • FEAT
      Short for FEATures, this command is used by the client to request a descriptive list of server-supported features.
    • HELP
    • LANG
    • LIST
    • MDTM
      Short for MoDification TiMe, this command is used by the client to request the modification time of a file on the server. This command is defined formally in RFC 3659, and is a commonly implemented FTP command. Note that this command cannot be used to change the modification time of the file on the server; it only reports on the file's modification time. The MFMT command is used to change a file's modification time.
    • MFMT
      Short for Modify Fact: Last Modified Time, supported by mod_facts. Some clients use this command to change the last modified timestamp on a newly uploaded file so that the timestamp on the server matches the timestamp of that file on the client.
    • MKD
      Short for MaKe Directory.
    • MLSD
      Short for Machine LiSting, Directory, supported by mod_facts. Unlike the LIST command, whose response format was never specified, the MLSD command has a strictly defined response format (see RFC 3659 for details). This format was designed to be easily machine parseable, for automated processing of directory listing formats; the format was also designed to be platform-agnostic, and thus portable.
    • MLST
      Short for Machine LiSTing, supported by mod_facts. This command is similar to MLSD in that it uses the same response format. Unlike MLSD, the response for a MLST is sent back on the control connection rather than using a data connection, and is for a single file only.
    • MODE
      There are three mode types defined by RFC 959; proftpd only supports one (i.e. Stream).
    • NLST
      Short for Name LiST.
    • NOOP
      Short for NO OPeration. This command has no functionality, and is often used as a session keepalive mechanism.
    • OPTS
      Short for OPTionS. This command is used to specify optional parameters for the command to follow the OPTS command, if that command supports such optional parameters.
    • PASS
      Short for PASSword, the client uses this command to convey the password of the user attempting to log into the server.
    • PASV
      Short for PASsiVe, the client uses this command to ask the server for a port to which the client should connect, indicating a passive data transfer.
    • PBSZ
      Short for Protection Buffer SiZe. Used to determine the size of a buffer needed for secure handshaking (supported by mod_tls)
    • PORT
      The client uses this command to tell the server to what client-side port the server should contact; use of this command indicates an active data transfer.
    • PROT
      Short for PROTection. Used to set the protection level on the data channel (supported by mod_tls)
    • PWD
      Short for Print Working Directory.
    • QUIT
    • REST
      Short for RESTart, this command is used by the client to tell the server that it would like to restart a previous data transfer, either upload or download.
    • RETR
      Short for RETRieve, this command is used by the client to inform the server of the file the client would like to download. On many FTP client, this is implemented using the client-specfic "get" command.
    • RMD
      Short for ReMove Directory, this command is used to have the server delete the requested directory from its filesystem.
    • RNFR
      Short for ReName FRom.
    • RNTO
      Short for ReName TO.
    • SITE
      This command is used for site-specific commands. See below for descriptions of proftpd's SITE commands.
    • SIZE
    • STAT
    • STOR
      Short for STORe, this command is used by the client to tell the the server that the client will be uploading data for a file to stored on the server using the filename given. On many FTP clients, this is implemented using the client-specific "put" command.
    • STOU
      Short for STOre Uunique, it requests that the file being stored on the server be given a unique filename. The server chooses the unique name for the stored file, and reports the name chosen back to the client. On some FTP clients, this ability is enabled using the client-specific "sunique" command.
    • SYST
    • TYPE
    • USER
      An FTP client uses this command to inform the server of the name of the user requesting an FTP session.
    • XCUP
      This is an X-variant of the CDUP command, and has the same functionality.
    • XCWD
      This is an X-variant of the CWD command, and has the same functionality.
    • XMKD
      This is an X-variant of the MKD command, and has the same functionality.
    • XPWD
      This is an X-variant of the PWD command, and has the same functionality.
    • XRMD
      This is an X-variant of the RMD command, and has the same functionality.

    Supported SITE commands

    • CHGRP
      Short for CHange GRouP.

      Example:

          SITE CHGRP ftpgroup script.cgi
      
    • CHMOD
      Short for CHange MODe.

      Example:

          SITE CHMOD 755 script.cgi
      
    • HELP
    • MKDIR
      Similar to the MKD command, this SITE can be used to create a directory. It will, unlike MKD, also create any directories in the path that do not exist.

      Example:

        SITE MKDIR /path/to/some/dir/that/is/not/there/
      
      Supported by the mod_site_misc module.
    • RMDIR
      Similar to the RMD command, this SITE can be used to remove a directory. It will, unlike RMD, also delete any files in the directory.

      Example:

        SITE RMDIR /path/to/some/dir/with/files/
      
      Supported by the mod_site_misc module.
    • SYMLINK
      Used to create a symbolic link (a.k.a. a symlink) from the source path (src) to the destination path (dest).

      Example:

        SITE SYMLINK src dest
      
      Supported by the mod_site_misc module.
    • UTIME
      Used to update the access and modification timestamps on a file.

      Example:

        SITE UTIME 200412312359 /path/to/some/file.txt
      
      Supported by the mod_site_misc module.

    Unsupported FTP Commands

    • ACCT
      Short for ACCounT
    • MACB
      Short for MACintosh Binary. This command is not defined in any RFC, and is something of a hack added by Apple in order to support transfers of the resource forks of Mac files.
    • REIN
    • SMNT
    • STRU
      Short for STRUcture. proftpd only supports a STRU parameter of type F (for "file"), and so does not support this command.

    Frequently Asked Questions

    Question: I can use the RNFR and RNTO commands to move a file, even across different disks/mount points. And I can use RNFR/RNTO to move a directory, but I cannot move a directory across different disks/mount points. Is this a bug?
    Answer: No, it is not a bug. Why not? Ultimately, it is because the FTP specifications do not guarantee (or even discuss) that an FTP implementation must support renaming of directories across mount points.

    ProFTPD implements the RNFR/RNTO functionality by using the rename(2) system call. And rename(2) is documented to not work across mount points.

    "But then why does it work when I rename a file across mount points?" you ask. Good question. The answer is that for files only, ProFTPD detects the rename(2) error for renaming across mount points, and then copies the file in question to the new location, deleting the old location when the copy completes successfully.

    "Great!" you say, "Now do the same thing for directories!" Unfortunately, for directories, the answer is not that simple. Here are some things to consider when copying directories: what if the directory contains sockets, FIFOs, devices, and other irregular file types which cannot be easily copied/moved? Should copying/moving of directories automatically use root privileges in order to preserve the ownership on files that do not belong to the logged-in user? What if the copying/deleting of files fails in the midde: what should then happen to the copied (and remaining) files/directories?

    Since there are no easy answers as yet to the above questions, ProFTPD now detects the rename(2) error for renaming across mount points for a directory, and rejects the RNTO command, showing something like:

      RNFR directory
      350 File or directory exists, ready for destination name
      RNTO /other/mount/directory
      550 Rename /other/mount/directory: Is a directory
    
    That "Is a directory" error indicates that ProFTPD cannot rename a directory across the mount points you requested. (That particular error message can, and will, be made more informative.)


    Last Updated: $Date: 2012/12/27 23:01:25 $
    proftpd-dfsg-1.3.5~rc3/doc/howto/VirtualUsers.html0000644000175000017500000002170710262530443022016 0ustar frankiefrankie ProFTPD mini-HOWTO - ProFTPD Virtual Users

    ProFTPD Virtual Users


    The core proftpd daemon access all user information via an Auth API. This API hides all of the details of where user information is stored, how to retrieve it, etc from the core engine and modules. This abstraction allows for multiple simultaneous different authentication layers or mechanisms to be configured. It is also because of this abstraction that proftpd does not "know" the difference between a system user and a virtual user; all users are the same.

    Frequently Asked Questions

    Question: What makes a user "virtual", then?
    Answer: A virtual user is, quite simply, a user that is not defined in the system /etc/passwd file. This file associates a user name, given by the system administrator, to a user ID (commonly shortened to UID) and a group ID (GID), among other details. The Unix kernel does not deal with users in terms of their user names; it only "knows" about UIDs and GIDs. This means that an application like proftpd can look up the IDs to use for a given user name however it sees fit. Using /etc/passwd is not strictly required.

    Defining users outside of /etc/passwd means that system utilities like ls and chown do not work as expected. When first setting up virtual users, most system administrators will experience this as permissions problems. Virtual users will not be able to login, or they can login but not upload or download files. Or when the administrator lists the files uploaded by virtual users, those files will have the wrong owner names.

    The permissions problems are almost always caused by ID mismatch. That is, the UID and/or GID of the virtual user will not match the UID and/or GID owner of their home directory (or whichever directory is having problems). The key here is to change the ownership of the virtual user's directories using chown and IDs, rather than names. The chown utility can set ownership by ID just as easily as by name. Most chown examples show setting ownership by name, but that means chown would look up the IDs for that name via /etc/passwd, which, as noted above, will not work for virtual users.

    By default, ls lists the names of file owners by looking up those names in /etc/passwd. This is why listing files of virtual users will often show incorrect names; ls has no knowledge of virtual user names. When working with files created by virtual users, use ls -n so that you can see the IDs, not the names, associated with those files. You will then need to manually make sure those IDs are the correct ones for the file.

    Question: Which IDs should I use for my virtual users?
    Answer: It does not matter. The only UID and GID which are special are UID 0 (zero) and GID 0 (zero). These IDs are used for user root and group root; do not assign these IDs to your virtual users unless you absolutely trust those users.

    Other than that, you are free to use any IDs you like. It is generally a good idea to use IDs for your virtual users that are not already in use in /etc/passwd, in order to keep the privileges of your system users separate from the privileges of your virtual users; privileges are determined by IDs. However, in some cases (such as using ProFTPD for FTP access to websites), you may want all of your virtual users to run as the web server user, e.g. user "www" or user "apache". Use the IDs that make the most sense for your site needs.

    One related question often asked is "Can I have my virtual users have the same IDs?" Yes, you can. This means that all of those virtual users would have the exact same privileges. If you use this approach, make sure those virtual users are all confined to separate home (or web site) directories by using:

      DefaultRoot ~
    
    in your proftpd.conf. This means that even though those virtual users would all have the same privileges, they would be unable to see and affect each others' files since they would all be separated in different directories.

    Question: If virtual users are not defined in the system /etc/passwd file, then where are they defined?
    Answer: There are several other locations where user information can be stored, e.g. AuthUserFiles, LDAP directories, SQL databases, and RADIUS servers. Note that virtual users are not defined in the proftpd.conf file directly.

    One of the simplest virtual user authentication mechanisms is the AuthUserFile, which is a flat text file in the same format as the system /etc/passwd file. For more information on the details, see the AuthFiles howto. The AuthUserFile configuration directive is handled by the mod_auth_file module, whose documentation can be found here.

    Once you have created your AuthUserFile and AuthGroupFile with the ftpasswd tool, you configure your proftpd to use those files by adding the following directives to your proftpd.conf:

      AuthUserFile /path/to/ftpd.passwd
      AuthGroupFile /path/to/ftpd.group
    
    The ftpasswd tool is a Perl script, distributed with the ProFTPD source code, under the contrib/ directory. A copy can also be found online:
      http://www.castaglia.org/proftpd/contrib/ftpasswd
    

    Another very popular authentication mechanism used for virtual users is a SQL database such as MySQL or Postgres. This mechanism is supported by ProFTPD's mod_sql module; more information on using mod_sql can be found in the SQL howto, and the mod_sql documentation.

    Some sites still experience permissions issues, even though everything appears to be configured properly. If this happens, define an SQLLogFile in your proftpd.conf:

      SQLLogFile /path/to/mod_sql.log
    
    This log file will show which IDs the mod_sql module is assigning to users/groups looked up by proftpd. If the IDs are not what you have in your SQL tables, then you need to use the following directives: SQLMinUserUID, SQLMinUserGID, and SQLMinUserID. The mod_sql module contains some default limits on the range of IDs it returns; the above directives are used to tweak those default limits.

    User documentation for the mod_ldap module (for virtual users via LDAP directories) and mod_radius module (for virtual users via RADIUS servers) is not yet complete.

    Important: proftpd will use all authentication mechanisms by default. This is why a user that does not appear in an AuthUserFile, but is defined in the system /etc/passwd file, can login by default. Use the AuthOrder configuration directive to change this. This directive is explained in more detail in the Authentication howto.

    Question: But I've seen examples that use the <Anonymous> section for virtual users. Why don't you mention this?
    Answer: The <Anonymous> context should never be used to define a virtual user. This type of configuration is a crude hack, leftover from ProFTPD's early days. Using an AuthUserFile is better supported, better documented, more flexible, and more in line with ProFTPD's design philosophy.

    Question: What about using PAM for virtual users?
    Answer: Please read the Authentication howto.


    Last Updated: $Date: 2005/07/05 16:11:15 $

    proftpd-dfsg-1.3.5~rc3/doc/howto/Nonroot.html0000644000175000017500000001056311271341266021006 0ustar frankiefrankie ProFTPD mini-HOWTO - Running by nonroot user

    Running ProFTPD as a Nonroot User


    Occasionally, one might want to run ProFTPD on a system where root privs are not available to you as a user. It is still possible to setup a functioning FTP server without root privileges. There are a few catches and special considerations for this, however.

    Here are the configuration directives that you will need to use in order to run the server without root privileges:

    • Port
      This needs to be a number greater than 1023. Lower number ports require root privileges in order for the process to bind to that address. This will also mean that clients wishing to contact your server will need to know the port on which it is listening. Most FTP clients connect to the standard FTP port (21).

      Example:

          Port 20021
      
    • AuthUserFile, AuthGroupFile
      In order to authenticate users, by default the server looks in /etc/passwd for account information, and in /etc/shadow for the password. Comparing stored passwords requires root privileges, which this nonroot-running daemon will not have. You can get around this requirement by supplying your own passwd (and possibly group) files via the AuthUserFile and AuthGroupFile directives. Make sure the permissions on your custom files allow for the daemon to read them (but hopefully not other users).

      Example:

          AuthUserFile /path/to/custom/ftpd.passwd
          AuthGroupFile /path/to/custom/ftpd.group
      
    • AuthPAM
      PAM authentication requires root privileges. This directive will need to be set off.

      Example:

          AuthPAM off
      
    • PidFile
      This directive will need to be used to cause the server to write its PID to some file writable by the user.

      Example:

          PidFile /home/bob/ftpd/proftpd.pid
      
    • ScoreboardFile
      This directive will need to be used to cause the server to write its scoreboard to some file writable by the user.

      Example:

          ScoreboardFile /home/bob/ftpd/proftpd.scoreboard
      
    • WtmpLog
      Logging to wtmp files requires root privileges. While it is not strictly necessary for this directive to be set to off, failure to do so will result in server log messages like:
        host.domain.net (localhost[127.0.0.1]) - wtmpx /var/adm/wtmpx: Permission denied
      

      Example:

          WtmpLog off
      
    • User, Group
      The ability to switch the identity of the server process to those configured by the User and Group directives requires, of course, root privileges. It is best to configure User to be your username, and Group to be the name of your primary group (which is usually the first group listed by the groups command).

      Example:

          User bob
          Group bob
      

    Note that other configuration directives will be affected by the lack of root privileges: DefaultRoot will not work, nor will <Anonymous> sections, nor UserOwner. Basically any operation that requires root privileges will be disabled.

    If using the SystemLog directive, make sure the file to which the server is to log can be written to by the configured daemon User or Group.

    The daemon should now start successfully. Complaints about not being able to switch UIDs and such will be logged, but the daemon should still function properly.


    proftpd-dfsg-1.3.5~rc3/doc/howto/NAT.html0000644000175000017500000002623311756737553020013 0ustar frankiefrankie ProFTPD mini-HOWTO - Firewalls, Routers, and NAT

    Firewalls, Routers, and NAT


    Basic NAT information
    NAT (Network Address Translation) is a system that acts like a proxy, but on a "packet" level. When a computer on your local network connects to a computer on the Internet, the NAT replaces the "from" information of packets with its own address, making your local network invisible to the Internet. Many firewalls perform NAT duties as well, so the following information is valid in firewalled environments as well.

    For server systems, NAT can improve security and enable multiple servers to be accessed using a single IP address. This is done by allowing certain ports forwarded "inward" to the local network. However, the part of the FTP protocol known as "passive" data transfers is not by default compatible with NAT solutions. But NAT functionality is possible with ProFTPD versions 1.2rc2 and later.

    Note: for details on NAT configuration for Linux, read the Linux IP-masq HOWTO at:

      tldp.org/HOWTO/IP-Masquerade-HOWTO/
    
    or search for information concerning your OS of choice.

    Configuring ProFTPD behind NAT
    First configure your installed proftpd so that it works correctly from inside the NAT. There are example configuration files included with the source. Then add the MasqueradeAddress directive to your proftpd.conf file to define the public name or IP address of the NAT. For example:

      MasqueradeAddress	ftp.mydomain.com  # using a DNS name
      MasqueradeAddress	123.45.67.89      # using an IP address
    
    Now your proftpd will hide its local address and instead use the public address of your NAT.

    However, one big problem still exists. The passive FTP connections will use ports from 1024 and up, which means that you must forward all ports 1024-65535 from the NAT to the FTP server! And you have to allow many (possibly) dangerous ports in your firewalling rules! Not a good situation. For a good description of active versus passive FTP data transfers, see:

      http://slacksite.com/other/ftp.html
    
    To resolve this, simply use the PassivePorts directive in your proftpd.conf to control what ports proftpd will use for its passive data transfers:
      PassivePorts 60000 65535	# These ports should be safe...
    
    Note that if the configured range of ports is too small, connecting clients may experience delays or be completely unable to operate when they request passive data transfers. When the daemon cannot use one of the ports in the configured range, it will fall back to using a kernel-assigned port, and log a message reporting the issue. The clients' ability to use this non-configured port will then depend on any NAT, router, or firewall configuration.

    Now start the FTP daemon and you should see something like:

      123.45.67.89 - Masquerading as '123.45.67.89' (123.45.67.89)
    
    in the log files.

    A Linux Example
    This example is for Linux kernel version 2.2.x with ipchains and ipmasqadm. The examples below assume that your FTP server has local address 192.168.1.2.

    First we need to enable NAT for our FTP server. As root:

      echo "1">/proc/sys/net/ipv4/ip_forward
      ipchains -P forward DENY
      ipchains -I forward -s 192.168.1.2 -j MASQ
    
    Now we load the autofw kernel module and forward ports 20 and 21 to the FTP server:
      insmod ip_masq_autofw
      ipmasqadm autofw -A -r tcp 20 21 -h 192.168.1.2
    
    Then we forward ports for passive FTP transfers. In our proftpd.conf file we restricted passive transfers to ports 60000-65535, so that is what we use here as well:
      ipmasqadm autofw -A -r tcp 60000 65535 -h 192.168.1.2
    

    If instead your Linux system uses IP Filters, then you might do something like the following. First, update your ipf.conf with:

      # Allow passive FTP transfers from ports 49152 to 65534, the IANA-registered
      # ephemeral port range.
      pass in quick proto tcp from any to any port 49151 >< 65535 flags S keep state
    
    Then make sure that the changes take effect by using:
      ipf -Fa -f /path/to/ipf.conf
    

    Double Checking
    Setting up proftpd that allows passive data transfers srequires that a range of ports be forwarded from the NAT to the local network. This could be a security hazard, but since you can specify what port range to use, you are still able to setup relatively tight firewalling rules. To be sure that you have no other processes listening on the ports you have specified for passive transfers, use a port scanner such as nmap:

      nmap -sT -I -p 60000-65535 localhost
    
    If the result says something like:
      All 5536 scanned ports on localhost (127.0.0.1) are: closed
    
    then you should be safe.

    Frequently Asked Questions

    Question: How do I know if my MasqueradeAddress and PassivePorts configuration is working?
    Answer: When performing a passive data transfer, an FTP client sends the PASV command to the FTP server. The server responds with the address and port to which the client should connect. For example:

      227 Entering Passive Mode (127,0,0,1,19,6).
    
    The address and port are contained in the parentheses, formatted as a1,a2,a3,a4,p1,p2, where the IP address is:
      a1.a2.a3.a4
    
    and the port number is:
      p1 * 256 + p2
    
    If the address seen in the server's response is not a public IP address or the port is not in the port range configured by your PassivePorts, double-check your proftpd.conf. Non-public IP addresses are defined by
    RFC 1918, and include 10.x, 172.16.x and 192.168.0.x.

    Question: I am using the PassivePorts directive, but my FTP client still doesn't work. In the proftpd debug logging, I see:

      May 20 17:00:55 www.example.com proftpd[10078] wwww.example.com (::ffff:1.2.3.4[::ffff:1.2.3.4]): Refused PORT 192,168,1,2,193,116 (address mismatch)
    
    Answer: The PORT there means that the FTP client is requesting an active data transfer; this means that proftpd is being asked to actively connect to the client (to the given address 192.168.1.2, port 49524).

    The first problem is, as the log message indicates, that the IP address given in the PORT command, 192.168.1.2, does not match the IP address from which the client connected (i.e. 1.2.3.4). By default, proftpd will refuse to create a data transfer connection to anywhere except back to the requesting client's IP address; see the AllowForeignAddress directive for more information.

    The next problem is that 192.168.1.2 IP address is not a publicly routable I address; specifically, it is part of an RFC 1918 address space. This means that is not possible for proftpd to connect to that address (unless proftpd is located in the same LAN).

    The solution for these situations is to a) configure proftpd to use both PassivePorts and MasqueradeAddress, and b) to configure your FTP client to request passive data transfers (via the PASV and EPSV commands), rather than active data transfers.

    Question: I am using MasqueradeAddress in my config, using the external DNS name for my site, but proftpd still returns the internal/LAN IP address in the PASV response. Is it a bug?
    Answer: Most likely not. If you use something like:

      MasqueradeAddress ftp.example.com
    
    and see the internal IP address in the PASV response, it suggests that proftpd, when starting up, resolves that DNS name from within your LAN, and gets that internal IP address. Rather than using the DNS name, you should explicitly use the external IP address in your MasqueradeAddress directive:
      MasqueradeAddress 1.2.3.4
    
    where "1.2.3.4" is your real external IP address.

    Question: Can I configure proftpd so that it refuses to handle passive transfers?
    Answer: If you are using a version of proftpd older than 1.2.10rc1, no. In 1.2.10rc1, support for placing limits on the PASV and PORT (and their IPv6 equivalents EPSV and EPRT) was added, so that you could do the following:

      <Limit EPSV PASV>
        DenyAll
      </Limit>
    

    Question: How can I make proftpd use a different MasqueradeAddress based on the address of the connecting client?
    Answer: This question usually arises in the case where FTP clients connecting from inside the LAN see the same MasqueradeAddress as external clients, which causes problems. That MasqueradeAddress may be necessary in order to allow external FTP clients to do passive data transfers. The internal clients do not need it. To handle this, create a <VirtualHost> section in your proftpd.conf to handle the LAN address of the FTP server, the address that the internal clients are contacting. In this <VirtualHost> section, make sure there is no MasqueradeAddress directive. This way, the external FTP clients "see" the configuration with the MasqueradeAddress they need, and the internal FTP clients "see" a different configuration, one with no MasqueradeAddress.

    For those that need to see a concrete example configuration of this:

      ServerName "Some Server Name"
      MasqueradeAddress my.domain.com
      PassivePorts 60000 65535
    
      # Note that your LAN address should be used here
      <VirtualHost 192.168.0.10>
        ServerName "Some Other Server Name"
    
        # Note that there is no MasqueradeAddress directive
        # used in this section!
      </VirtualHost>
    


    Contributor: Tobias Ekbom <tobias at vallcom dotcom>
    Last Updated: $Date: 2012/05/22 16:31:39 $
    proftpd-dfsg-1.3.5~rc3/doc/howto/BCP.html0000644000175000017500000003277210054702516017757 0ustar frankiefrankie ProFTPD mini-HOWTO - Best Common Practices

    Best Common Practices


    This document describes the best practices, common and recommended, when configuring and using proftpd servers. The first few recommendations are covered in detail elsewhere: role accounts, chroots, and logging directories.

    <VirtualHost>s
    When configuration a <VirtualHost>, it is best to use an IP address, and not a DNS name. Not only does this reduce network traffic a little when the daemon starts up (as it will not need to resolve the DNS name to its IP address), but it will also reduce confusion. Unlike HTTP, FTP does not support name-based virtual hosts; all contact to virtual hosts is done based on IP addresses (and ports). If a DNS name is used in a <VirtualHost> configuration, there is the possibility that that DNS name will resolve to an IP address of another virtual host in the configuration.

    Resource Limits
    One of the most common requests on the mailing list is to be able to limit the number of connections, in various ways, a given user may make to the proftpd daemon. There are different configuration directives for doing so, depending on the situation:

    • MaxInstances: Limits the overall number of connections

    • MaxClients: Limits the number of connections on a per-server/vhost basis

    • MaxClientsPerHost: Limits the number of clients that may be connecting from the same host

    • MaxClientsPerUser: Limits the number of clients that may be logged in at one time using the same username

    • MaxHostsPerUser: Limits the number of hosts from which clients may be logged in at one time using the same username

    If you are using a ServerType of inetd, then you should be aware of the default concurrency limits in inetd (see Bug#1243). For xinetd, the per_source and cps attributes can be used to configure concurrency limits. For a ServerType of standalone, the MaxConnectionRate configuration directive can be used to provide connection limitations.

    Intensive use of CPU and/or memory by FTP sessions can be restricted by use of RLimitCPU and RLimitMemory. Here's an example:

      RLimitCPU session 10
      RLimitMemory session 4096
    
    This applies CPU and memory resource limits to session processes. In order to limit the use of such resources by the daemon, should this be a concern, the directives can be used similarly:
      RLimitMemory daemon 8192 max
    
    In general, one should not set an RLimitCPU limit on the daemon, as a long-lived daemon (as all should be) will eventually encounter such a limit. Note: appropriate settings to use will vary from site to site - do not blindly copy these examples.

    One concern associated with unrestricted use of resources is globbing; the topic has been mentioned, in relation to FTP servers, in security forums in the past. This mini-HOWTO discusses, in-depth, the defenses against globbing attacks that ProFTPD provides.

    Some sites like to be able to restrict the size of files transferred, particularly uploaded files, as disk space is also a precious resource. For this purpose, the MaxRetrieveFileSize and MaxStoreFileSize configuration directives are provided.

    There are also several third-party modules that can add various resource limiting abilities to a proftpd server:

    Access Controls
    ProFTPD provides a <Limit> directive for configuring fine-grained access controls that can be applied to logins as well as FTP commands. The contributed mod_wrap module allows a proftpd daemon to use the standard /etc/hosts.allow and /etc/hosts.deny access control files. Of interest to some is the next generation of this module, mod_wrap-2.0, which allows for storing access control rules in SQL tables.

    Performance Tuning
    When configuring a proftpd for performance, here are some settings to try. First, make sure that you have ident and reverse DNS lookups disabled:

      IdentLookups off
      UseReverseDNS off
    
    By default, both are done for each new FTP session, and, depending on the response time from both identd and DNS servers, this can add a noticeable delay during the login process.

    Another possible source of delays during the login process is a very large /etc/passwd file (a large /etc/group file will have the same effect). The standard library functions used for doing user lookups scan these files line-by-line, which means that the scan time increases with the number of entries. If this is the case at your site, you might consider using a different storage format for your user account information. The mod_sql and mod_ldap modules provided with ProFTPD can be used for storing such information in SQL tables or LDAP servers.

    In some cases, it's also possible that PAM checks may introduce delays. If you suspect this to be happening, try adding the following to your proftpd.conf:

      <IfModule mod_auth_pam.c>
        AuthPAM off
      </IfModule>
    

    The listing of directories during an FTP session can impose quite a bit of disk I/O on a server machine. This is most often seen when site-mirroring scripts do recursive directory listings, and for deeply nested directory structures. To deal with the former, the following can be used:

      ListOptions +R strict
    
    This setting blocks the use of the -R option, which is how clients request recurse directory listings. The strict keyword prevents client options from overriding the proftpd.conf setting. Also, new in 1.2.9rc1 are some ListOptions options that allow recursive directory listings, but can be used to set limits on the recursion:
      ListOptions "" maxdepth 3
      ListOptions "" maxdirs 10
      ListOptions "" maxfiles 1000
    
    The first line above limits the directory depth of recursion; the second line does not limit the recursion depth, rather it limits the maximum number of directories that may be listed at one time; the third limit limits the maximum number of files that may be listed at one time.

    Another way to speed up directory listings to disable proftpd's checking for .ftpaccess files in every directory encountered. To do this, use:

      AllowOverride off
    
    This disable's proftpd's honouring of .ftpaccess files. How does this reduce disk I/O? In order to properly process .ftpaccess files, the daemon has to check for such a file in each and every directory when performing an operation in that directory, each time an operation is requested (it's possible for a .ftpaccess file to be added or updated after the daemon has already checked the directory). This constant checking is noticeable on heavily loaded servers. By disabling use of these files, the daemon no longer has to check each directory each time.

    The type of logging also has an impact, performance-wise. By default, a proftpd daemon logs using syslog; syslogd, however, is known to not scale well at all, and can break under heavy load. Directing logging to a file in such cases, using the ServerLog and/or SystemLog directives can reduce this bottleneck. Also, depending on the type of authentication done, disabling utmp/wtmp logging can reduce overhead:

      WtmpLog off
    
    for <VirtualHost>s that only allow anonymous logins, or that authenticate non-/etc/passwd accounts, helps to reduce the amount of unnecessary "clutter" in the utmp/wtmp log files.

    If your proftpd server is on a high-bandwidth Internet link, it may benefit from tuning the size of kernel-level (as opposed to application-level) socket buffers used when transferring data. The SocketOptions configuration directive can be used to specify larger buffer sizes:

      # The 'sndbuf' parameter tunes the size of the buffer used for sending
      # files to clients; the 'rcvbuf' tunes the buffer used for receiving
      # files uploaded by clients.
      #
      # This configures 16K buffers for both, which assumes a very
      # well-connected site.
      SocketOptions sndbuf 16384 rcvbuf 16384
    
    Again, these are example numbers, and should not be blindly copied.

    Finally, there are some configure options that can be used to tune your proftpd daemon. All of the --enable- options are available; of particular interest are --enable-tunable-buffer-size and --enable-sendfile. Use of the sendfile(2) function (via the latter configure option) may or may not increase download speeds, but it will reduce disk I/O: sendfile(2) implements zero-copy transfers, meaning that the kernel will read data directly from the file into the socket, all in kernel space; normal read() transfers spend time copying buffers from kernel space to application space (reading the file), and then back to kernel space (writing to the socket). By increasing the buffer size using the --enable-tunable-buffer-size option, proftpd reads and writes data in larger chunks, and makes fewer expensive system calls. Use of this option to set buffer sizes of 8K or more has been reported to drastically increase transfer speeds (depending on network configurations).

    Configuration Delegation
    A configuration is considered "delegated" when the Include configuration directive is used in proftpd.conf to specify a portion of the server configuration that may not be under the daemon administrator's control. This situation often arises for sites that have multiple virtual servers; the administrator for a given virtual server may be allowed to configure their particular server via an Included file. If possible, avoid this.

    Here's why: by delegating a configuration, you are trusting someone else with a great deal of possible control over the daemon. A given <VirtualHost> section can have an AuthUserFile. In that AuthUserFile, the virtual server administrator could define a user who has a UID of 0, thus basically giving herself root access. Most sites probably would not like this. The trouble here is the lack of control over the contents of AuthUserFiles (and AuthGroupFiles). There are a couple of ways of handling this situation. First, the daemon administrator can make sure that any Include directives occur as early as possible in the proftpd.conf file. Most configuration directives in the Included file can be overridden by setting the directive again, after the Include, in the main proftpd.conf.

    The mod_auth_file module, now part of the core distribution, was developed specifically to provide finer control over the contents of AuthUserFile and AuthGroupFile files. It does so by enhancing these configuration directives to support optional "filters" that restrict the UIDs, GIDs, user names, and/or home directories in such files.

    Miscellaneous
    For the security-wary administrator, there are a few more directives that may be of interest: AnonRejectPasswords, which configures a regular expression that matches and blocks scripted FTP clients that try to find and exploit ill-configured anonymous FTP sites, and RootRevoke, which causes proftpd to drop root privileges completely (read the description for details).


    Last Updated: $Date: 2004/05/25 17:41:34 $

    proftpd-dfsg-1.3.5~rc3/doc/howto/Directory.html0000644000175000017500000002562511120042517021307 0ustar frankiefrankie ProFTPD mini-HOWTO - Configuring a <Directory>

    Configuring a <Directory>


    Use of the <Directory> configuration directive is, in general, straightforward. However, there are a few caveats of which to be aware.

    First, it is not necessary to nest <Directory> sections, like:

      <Directory /path/to/dir>
        <Directory /path/to/dir/subdir>
          ...
        </Directory>
      </Directory>
    
    The daemon will not let one do this, in fact. The daemon will determine automatically the relations of <Directory> paths, depending on the path given and surrounding configuration context.

    Always use the normal, absolute path for a <Directory> section, regardless of whether that directory will eventually be accessed during a session which has been chroot'd, as for <Anonymous> or DefaultRooted sessions. There are two allowed exceptions to the rule of using absolute paths: if the path has a ~ prefix, or if the <Directory> occurs within a <Anonymous> section. In the latter case, the path may be relative (i.e. does not need to start with a /), in which case the path will be relative to the directory to which anonymous sessions are restricted.

    If the name of the directory contains spaces, you should enclose the entire directory name in quotations, e.g.:

      <Directory "/path/to/My Directory">
    

    Any configuration directives in a <Directory> section will apply to that directory and to all of the contents of that directory recursively. Thus if you use:

      <Directory /path/to/dir>
        Umask 022
      </Directory>
    
    Then that Umask value will be used within the "/path/to/dir/subdir/" directory as well.

    As noted in the documentation, use of a /* suffix on a path will change the effect of a <Directory> section slightly. For example:

      <Directory /path/to/dir>
    
    applies the section's configuration directives to the dir directory and its contents, while:
      <Directory /path/to/dir/*>
    
    applies the section's configuration directives only to the contents of dir, not to the directory itself. This is a small distinction, but it can often cause misconfigurations. In general, unless you know what you're doing, it's best not to use a /* suffix.

    Also, a * within a path, such as:

      <Directory /path/to/*/dir> 
    
    will only match that single directory level, and will not match multiple directory levels. This means that the above <Directory> will match:
      /path/to/a/dir
      /path/to/b/dir
    
    because * will match the a/ and b/, as they are on the same level in the path as *. However, the following paths will not match:
      /path/to/some/other/dir
      /path/to/some/other/level/dir
    
    since * does not expand to some/other/ or /some/other/level/; they cover multiple levels.

    There is another case about which the administrator should know: for the purposes of handling the APPE, RETR, RNTO, STOR, and STOU FTP commands, the daemon will match a <Directory> path with the filename appended. As above, in most cases this will not matter much. However, consider the case where the administrator specifically wants to use the trailing /*, as when she wants a particular <Limit> to apply to all subdirectories of a given directory, but not to that directory itself. For example, the administrators wishes to block anonymous uploads everywhere except for subdirectories of upload/:

      <Anonymous ~ftp>
        User ftp
        Group ftp
    
        UserAlias anonymous ftp
    
        <Limit WRITE>
          DenyAll
        </Limit>
    
        <Directory upload/*>
          <Limit STOR>
            AllowAll
          </Limit>
        </Directory>
      </Anonymous>
    
    This configuration looks like it should work, allowing files to be uploaded only to subdirectories of upload/, but not to the upload/ directory itself. As described above, though, the daemon will append the filename being uploaded via STOR to the path used when looking up <Directory>, meaning that upload/filename will match upload/*, and allow files to be uploaded into upload/. In this particular case, then, what is wanted is to use this <Directory> pattern:
        <Directory upload/*/*>
          <Limit STOR>
            AllowAll
          </Limit>
        </Directory>
    
    which will achieve the desired effect of allowing uploads only in subdirectories of the given directory, upload/.

    Also, it is good to keep in mind the similarity between a <Directory> section and a .ftpaccess file. In some cases, using .ftpaccess files might be more convenient. The AllowOverride configuration directive (which first appeared in the 1.2.7rc1 release) will provide fine-grained control over when .ftpaccess files will be honored.

    The fact that <Directory> sections can be used to refer to specific files, in addition to directories, is not obvious. However, there are some cases where it can be useful to use this feature. One proftpd user used this feature in the following way: the DirFakeMode was used to make all files look read-only (mostly so that FTP mirroring tools would create a read-only mirror of the site). However, a particular file on the site needed have execute permissions, even in the FTP mirrored site. A <Directorygt; section was used just for this one file, e.g.:

      # Make all files look read-only to clients, regardless of the actual
      # permissions on the filesystem
      DirFakeMode 0444
    
      <Anonymous /var/ftpd>
    
        # However, for this script, we need it to look like it is executable, too
        <Directory /var/ftpd/bin/script>
          DirFakeMode 0555
        </Directory>
    
      </Anonymous>
    

    Frequently Asked Questions

    Question: What happens if I configure two <Directory> sections for the exact same path?
    Answer: If you use explicit paths, then the config parser will choke on the duplicate <Directory> sections. For example, if you tried:

      <Directory /path/to/dir>
        <Limit ALL>
          DenyAll
        </Limit>
      </Directory>
    
      <Directory /path/to/dir>
        <Limit ALL>
          AllowAll
        </Limit>
    
        <Limit WRITE>
          DenyAll
        </Limit>
      </Directory>
    
    When starting proftpd, you would see something like:
     - Fatal: :  section already configured for '/path/to/dir' on line 39 of '/etc/ftpd/proftpd.conf'
    

    But what if you have the two <Directory> sections, but one of the sections uses a wildcard character which would still match the same path? For example:

      <Directory /path/to/dir>
        <Limit ALL>
          DenyAll
        </Limit>
      </Directory>
    
      <Directory /path/*/dir>
        <Limit ALL>
          AllowAll
        </Limit>
    
        <Limit WRITE>
          DenyAll
        </Limit>
      </Directory>
    
    This time, the config parser would not choke; proftpd would start up normally. When it came time to look up the <Directory> section to use, e.g. for uploading to "/path/to/dir/test.txt", the matching <Directory> section which appears later in the config file wins. In the above example, the upload to "/path/to/dir/test.txt" would be denied (because the wildcard-using <Directory> section appears later, and it has a <Limit WRITE> section denying writes).

    However, if you simply reversed the order of the above <Directory> sections and tried to upload to "/path/to/subdir/test.txt", e.g.:

      <Directory /path/*/dir>
        <Limit ALL>
          AllowAll
        </Limit>
    
        <Limit WRITE>
          DenyAll
        </Limit>
      </Directory>
    
      <Directory /path/to/dir>
        <Limit ALL>
          DenyAll
        </Limit>
      </Directory>
    
    the upload would succeed, since the non-wildcard-using <Directory> section appeared later in the config.

    Question: How can I prevent a specific directory from being renamed? I am currently trying:

      <Directory /dir/*>
        <Limit CWD XCWD RNFR RNTO>
          AllowAll
        </Limit>
    
        <Limit ALL>
          DenyAll
        </Limit>
      </Directory>
    
      <Directory /dir/subdir>
        <Limit WRITE>
          DenyAll
        </Limit>
      </Directory>
    
    to keep "/dir/subdir" from being renamed, but it doesn't work!
    Answer: The trick is to block the RNFR command within the <Directory> section for that specific directory, i.e.:
      <Directory /dir/subdir>
        <Limit RNFR WRITE>
          DenyAll
        </Limit>
      </Directory>
    

    The reason the original config did not work as expected is that proftpd, when handling the RNTO command (e.g. "RNTO subdir2"), would not match the <Directory /dir/subdir> section for the path "/dir/subdir2", but instead matches the <Directory /dir/*> section.

    Renaming of files via FTP is done by first sending the RNFR command (for the old filename), then sending RNFTO (with the new filename). By placing RNFR in the <Directory /dir/subdir> section's <Limit> list, we make sure that the RNFR does match the <Directory /dir/subdir> section, and is thus denied.


    Last Updated: $Date: 2008/12/10 22:40:15 $

    proftpd-dfsg-1.3.5~rc3/doc/howto/Vhost.html0000644000175000017500000002735011132752446020457 0ustar frankiefrankie ProFTPD mini-HOWTO - Virtual Servers

    ProFTPD and Virtual Servers


    What is a virtual server?
    A virtual server, also known as a virtual host (or vhost for short), refers to the practice of serving more than one address/site on a single host machine. The fact that these multiple sites are being served by the same physical machine is transparent to the end user.

    The definition of the File Transfer Protocol, unfortunately, does not (currently) support name-based virtual hosts, as HTTP1.1 supports. All FTP virtual hosts are based on unique IP address/port combinations, not on DNS names. The similarity of ProFTPD's configuration file syntax to Apache's sometimes leads users to assuming that proftpd will handle these the same way -- but more on this later. The bottom line is that ProFTPD does not support name-based virtual hosts; not because they are not implemented, but simply because the protocol itself does not support them.

    In some documents, one might see reference to both "daemon" and "server". Sometimes these words are used interchangeably; however, there is a slight difference. A "daemon" is a long-lived process on a host machine, and a "server" is a process that provides some service, typically to remote clients. A process, such as a standalone proftpd process, can be considered both a "daemon" and a "server". With this in mind, then, a "virtual server" is not a separate process itself; it just looks like one to the remote clients. Hence the "virtual".

    There are three "server" contexts (sometimes also called sections) in the proftpd.conf configuration file: <VirtualHost>, <Global>, and "server config".

    The <VirtualHost> context is used to define the configuration for a particular virtual host, bound to an IP address. For example:

      <VirtualHost 1.2.3.4>
        ...
      </VirtualHost>
    
    defines a configuration for a virtual server that proftpd should use whenever a remote client connects to the IP address 1.2.3.4. DNS names, too, can be used with the <VirtualHost> configuration directive, and this is where some of the name-based vhost support confusion creeps in:
      <VirtualHost ftp.mydomain.com>
        ...
      </VirtualHost>
    
    When proftpd parses this context on startup, it will resolve the given DNS name to its IP address and use that, just as if that IP address had been used in the first place. Use of DNS names like this, while convenient, can easily lead to confusion when multiple DNS names resolve to the same IP address. If this happens, proftpd will use the first context in the configuration file when serving that address.

    The <Global> context is provided as a convenience. Imagine that the administrator has many <VirtualHost> contexts in her proftpd.conf, and yet has a lot of the same configuration for each virtual host, such as common <Directory> sections, DefaultRoot settings, etc. Rather than including the same configuration over and over, she could use the <Global> context:

      <Global>
        ...
      </Global>
    
    Anything inside of a <Global> section is applied to every server configuration in the file, to every <VirtualHost> as well as the default "server config" server.

    Which brings us to the "server config" context. The name is ill-suited, and is really borrowed directly from Apache's naming conventions. The "server config" context refers to anything not in a <VirtualHost> or <Global> context in the proftpd.conf file. Unlike Apache's httpd.conf, ProFTPD's configuration is designed such that one should be able to use the simplest file as possible. In fact, proftpd will start if the proftpd.conf is completely empty; try it! This will cause the daemon to use all of the default settings, which in most cases is not what is wanted, but it is possible. With this in mind, there is always at least one server configuration present: the default server context, and it is this context that is known as the "server config". Just like the <VirtualHost> context, any configuration directives inside the "server config" context do not apply outside of the context. Many administrators often assume that this is the case. It is not. This is what the <Global> context is for.

    However, one particular drawback to the "server config" context was that it did not provide a way to specify to which IP address that configuration pertained. By default, when proftpd parses the proftpd.conf file, it will use the gethostname() function to determine the IP address to which the default server should listen. On a single address, single interface system, this default is fine. It is one a multiple address system that the default handling does not always work; the administrator may wish to explicitly specify to which address the default server should listen. This is what the DefaultAddress configuration directive provides: the ability to specify to which IP address the "server config" vhost should listen.

    By default, every server will listen to port 21, the IANA standard port for FTP. If you want to have server react to a different port, use the Port directive to change the port. As might be mentioned elsewhere, if you have many different <VirtualHost> contexts using the same address but different ports, you'll want to make sure that you leave each Port-1 number empty. RFC 959 specifies that the source port for an active data transfer (read here) must be L-1, where L is the port on which your server listens. Also, as mentioned in the Port documentation, using:

      Port 0
    
    in any server context will effectively "disable" that server. This is sometimes used to disable the "server config" configuration.

    There is another configuration directive that comes into play in all of this : DefaultServer. Here is why: when a client contacts proftpd, the server has to determine which configuration to use for handling the client. To do this, it searches its list of configured vhosts, searching for a vhost whose IP address matches the IP address that the client contacted. If there's a matching vhost for that IP address, simple: use that configuration. If not, proftpd will then resort to using the configuration that bears the DefaultServer directive, which says that the server configuration in which it appers should be used in cases like this. If there is no DefaultServer directive in the proftpd.conf file, and no matching configuration can be found, then the client will see a message such as "no server available to service your request". The DefaultServer can be used to say that a <VirtualHost> should be the default, and not necessarily the "server config" context, as is common.

    If you would like the same virtual host configuration to be used for multiple different IP addresses (or DNS names), the <VirtualHost> supports this:

      <VirtualHost 1.2.3.4 5.6.7.8>
        ...
      </VirtualHost>
    

    If, however, you want to specific the address to which the configuration of the "server config" context, use DefaultAddress (mentioned above).

    There is one last configuration directive about which an administrator should know: SocketBindTight. By default, the proftpd daemon will listen on all addresses, port 21, for the connection requests of remote clients. Sometimes, the administrator may wish to have the proftpd daemon listen only on the IP addresses for which it has been configured, and not every address. To accomplish this, simply use the SocketBindTight configuration directive:

      SocketBindTight on
    
    This configures the daemon to "bind tightly" only to those IP addresses to which it has been configured to listen, rather than every address. By default, the proftpd daemon will listen to every address on the host machine.

    Frequently Asked Questions

    Question: Why do I see the following when I start proftpd?

    - warning: "Virtual Server" address/port (1.2.3.4:21) already in use by "Main Server"
    
    Answer: This happens when a <VirtualHost> section is "hidden" behind the default server in the "server config" section (i.e. the context that is outside of all <VirtualHost> and <Global> sections). It is "hidden" because both the <VirtualHost> section and the "server config" section are using the same IP address and port.

    It is quite common to configure <VirtualHost> sections using DNS names, rather than IP addresses. And the "server config" section in the proftpd.conf file, by default, uses the IP address of the machine's hostname. This makes it quite easy to inadvertently have multiple sections trying to use the same IP address and port.

    The quick-and-easy fix is to place the following your "server config" section in your proftpd.conf:

      Port 0
    
    as mentioned above. You can also use the DefaultAddress directive in the "server config" section to explicitly tell the "server config" section to use a different IP address/DNS name.

    Question: How can I have my "server config" section (or a <VirtualHost> section) listen for multiple IP addresses/DNS names?
    Answer: In version 1.3.0rc1 and later, the <VirtualHost> configuration was enhanced so that it could handle multiple IP addresses/DNS names, e.g.:

      <VirtualHost 1.2.3.4 ftp.example.com>
        ...
      </VirtualHost>
    
    And for the "server config" context, you would use the DefaultAddress directive, which can also handle multiple IP addresses/DNS names:
      DefaultAddress 1.2.3.4 ftp.example.com
    

    Last Updated: $Date: 2009/01/12 23:41:26 $

    proftpd-dfsg-1.3.5~rc3/doc/howto/CreateHome.html0000644000175000017500000001753012021706035021356 0ustar frankiefrankie ProFTPD mini-HOWTO - CreateHome

    ProFTPD's CreateHome


    What is CreateHome?
    When a site has many user accounts, with users being added and removed constantly, there is always the associated procedure of creating and removing those user's home directories. And often, in such situations, the user account information is stored in a SQL database or an LDAP server. A proftpd daemon can be configured to authenticate against the SQL database or the LDAP server; this would still leave the task of creating the actual home directory for that user to be done.. What would help ease this particular burden on system administrators, though, is the ability to add the account information and have the new user's home directory created on demand. That is, to have a daemon such as proftpd create the home directory for the user, if that directory did not already exist.

    Now, proftpd already has some modules, such as mod_sql and mod_ldap that already support this home-on-demand creation capability. Each module implements it slightly differently, though. And other authentication modules, such as mod_radius, do not support it at all. It was decided then, rather than having authentication modules have largely duplicated code for this feature, to have home-on-demand creation in the core daemon itself. And so it is. As of 1.2.8rc2, proftpd has the CreateHome configuration directive.

    How to use CreateHome
    The description for this configuration directive shows its parameters to be:

      CreateHome off|on [<mode>] [skel <path>] [dirmode <mode>] [uid <uid>] [gid <gid>] [homegid <gid>] [NoRootPrivs]
    
    The first parameter is a simple Boolean, enabling or disabling the proftpd daemon's run-time support for home directory creation. The rest of the parameters are optional, and only apply if CreateHomde is on.

    There is the first mode parameter, used to set the directory mode on the home directory being created. As described in the documentation, if this parameter is omitted the mode used will default to 0700. There is also the dirmode mode parameter, which is slightly different. The dirmode keyword informs the daemon that the following mode is to be used on directories that may need to be created in order to create the home directory. For example, let's assume that a new user, david, is logging in. User david has been given the home directory /home/users/d/da/david. Since this is a new user, the directory does not exist. In fact, /home/users/d does not exist. When this happens, proftpd will create the d, da, and david directories. A dirmode mode would be applied to the d and da directories, and the mode (no dirmode keyword) would be applied to the final david directory. To illustrate this, assume that the following CreateHome configuration is in use:

      CreateHome on 700 dirmode 711
    
    A directory listing would show only the /home/users directory:
      drwxr-xr-x    6 root     root         4096 Jan 31 13:23 /home/users
    
    After user david logs in, a directory listing might show the new directories that have been created:
      drwxr-xr-x    6 root     root         4096 Jan 31 13:23 /home/users
      drwx--x--x    6 root     root         4096 Jan 31 13:23 /home/users/d
      drwx--x--x    6 root     root         4096 Jan 31 13:23 /home/users/d/da
      drwx------    6 david    david        4096 Jan 31 13:23 /home/users/d/da/david
    
    Notice how /home/users/d and /home/users/d/da have dirmode mode of 711 (rwx--x--x) while /home/users/d/da/david has the mode of 700 (rwx------).

    As an added feature, CreateHome also supports the ability to populate these newly created home directories. This is done by configuring a "skeleton" directory that will contain files (e.g. shell initialization files, documentation, notices, subdirectories, etc) that should be in every new user's home directory. This is done using the skel path parameter.

    Be sure to read the documentation for the CreateHome directive, for there are some restrictions and caveats to both the dirmode and skel parameters.

    The uid and gid parameters can be used to set the ownership of the newly created parent directories, up to but not including the home directory. By default, those created parent directories are owned by root (UID 0 and GID 0).

    The homegid parameter can be used to specify the group ownerhsip of the target home directory itself. By default, this home directory will be owned by the user's primary GID.

    Here are some examples (from the documentation) to help illustrate how one might use the CreateHome configuration directive:

      # Use the CreateHome default settings
      CreateHome on
    
      # Specify a mode of 711 for the created home directory
      CreateHome on 711
    
      # Specify a mode of 711, and have the parent directories owned by a specific non-root UID/GID
      CreateHome on 711 uid 100 gid 100
    
      # Specify a mode of 711, and have the parent directories owned by the UID/GID of the logging-in user
      CreateHome on 711 uid ~ gid ~
    
      # Specify a skeleton directory
      CreateHome on skel /etc/ftpd/skel
    
      # No skeleton, but make sure that intermediate directories have 755
      # permissions.
      CreateHome on dirmode 755
    
      # Skeleton directory, with 700 intermediate directories
      CreateHome on skel /etc/ftpd/skel dirmode 700
    
      # Explicitly configure everything, CreateHome-wise
      CreateHome on 711 skel /etc/ftpd/skel dirmode 700
    
      # Explicitly configure everything, CreateHome-wise.  And do NOT use root privileges when
      # creating the parent directories.
      CreateHome on 711 skel /etc/ftpd/skel dirmode 700 NoRootPrivs
    

    When to use CreateHome
    "What about the prior configuration directives for mod_sql and mod_ldap?" one asks. The CreateHome configuration directive supercedes them. Those previous module-specific directives may well be deprecated in the future, in favor of CreateHome. Future authentication modules need not try to reinvent this particular wheel. CreateHome was designed for large sites in mind, but can be used any time home-on-demand creation is desired from the FTP daemon.

    FAQ

    Question: Is it possible to have different permissions for the CreateHome mode and dirmode based on the group of the connecting user?
    Answer: Yes, if you use the mod_ifsession module. For example:

      <IfGroup special>
        CreateHome on 755 dirmode 755
      </IfGroup>
    
      <IfGroup !special>
        CreateHome on 711 dirmode 711
      </IfGroup>
    


    $Date: 2012/09/05 17:30:05 $
    proftpd-dfsg-1.3.5~rc3/doc/howto/ListOptions.html0000644000175000017500000001417011712355555021643 0ustar frankiefrankie ProFTPD mini-HOWTO - Directory Lists and ListOptions

    Directory Lists and ListOptions


    The ListOptions directive of ProFTPD can be used to control how directory listings are generated. Directory listings are sent in response to the LIST and NLST FTP commands.

    The ListOptions directive supports the following options:

    • -1
      List one file per line
    • -A
      List all files except "." and ".."
    • -a
      List all files including those whose names start with "."
    • -B
      Force printing of non-printable filename characters as \xxx, where xxx is the octal value of the character
    • -C
      List entries by columns
    • -c
      Sort by file status change time when -t is also used
    • -d
      List directory entries instead of directory contents
    • -F
      Append file type indicator (one of "*", "/", "=", "@" or "|") to names
    • -h
      Print file sizes in human-readable format (e.g. 1K, 234M, 2G)
    • -L
      List files pointed to by symlinks
    • -l
      Use a long listing format
    • -n
      List numeric UIDs/GIDs instead of user/group names
    • -R
      List subdirectories recursively
    • -r
      Sort filenames in reverse order
    • -S
      Sort by file size
    • -t
      Sort by file modification time
    • -u
      Sort by file access time when -t is also used

    Although not strictly supported by the FTP RFCs, many FTP clients send these options with the LIST and NLST commands, and many FTP servers honor them. The ListOptions directive configures default options to be used, in addition to any sent by the client. For example, to show all files except the "hidden" files for clients, you could use:

      ListOptions -a
    

    Another use of ListOptions is to prevent certain options from being used. The -R option, for recursively listing all subdirectories, can use a lot of system resources, especially on very large and/or very deep directory structures, as proftpd scans all of the files. For this reason, some sites may wish to prevent the -R option from being used. ListOptions supports this with use of the "+" character. Options are enabled using the "-" character, thus they are disabled using "+"--think of the "+" as cancelling out the "-". For example:

      ListOptions +R strict
    
    would disable all use of the -R option.

    Where did the strict come from in the example above? ListOptions configures a set of default options, but if a client sends its own directory options, proftpd will use the client's options instead. To ignore the client options and use only the ListOptions configured, one uses the "strict" keyword. That is why the +R example above required "strict"--it causes proftpd to ignore any -R option the client might send.

    What if you wanted to enable some options and disable others in the same ListOptions directive? You would surround your options in quotation marks, like so:

      ListOptions "-a +R" strict
    

    If you are not using the --enable-nls configure option, and you want to see non-printable characters in filenames when listing directories, you should use:

      ListOptions -B
    

    The following keywords are supported, in addition to "strict":

    • maxfiles
      Sets a maximum limit on the number of files listed in one directory listing
    • maxdirs
      Sets a maximum limit on the number of directories listed in one directory listing
    • maxdepth
      Sets a maximum recursion depth, if the -R option is allowed
    • LISTOnly
      Applies the ListOptions only to LIST commands (and not NLST or STAT commands)
    • NLSTOnly
      Applies the ListOptions only to NLST commands (and not LIST or STAT commands)
    • NoErrorIfAbsent
      Causes a 226 response code to be returned for LIST/NLST commands for files which do not exist, rather than 450
    These keywords were added for finer-grained control over directory listings. They make it possible to allow recursive listings and yet still apply limits, to keep the recursion from taking too long:
      ListOptions -a maxfiles 2000 maxdepth 3
    
    This configures the -a option by default, and limits the maximum files in the generated listing to 2000. If the client uses the -R option, proftpd will not recurse into directories more than 3 levels deep when generating the listing.

    Or perhaps you want the one-file-per-line format, but only for NLST commands and not LIST commands. You would thus use something like:

      ListOptions "-1" strict NLSTOnly
    

    Note that <Limit> sections can be used to block the LIST and NLST commands altogether.


    $Date: 2012/02/02 00:40:13 $
    proftpd-dfsg-1.3.5~rc3/doc/howto/Umask.html0000644000175000017500000002233111733412565020430 0ustar frankiefrankie ProFTPD mini-HOWTO - Umask

    Umask


    ProFTPD's Umask configuration directive is used to set the file permission bits on newly created files and directories. However, the way in which Umask is to be used is not entirely straightforward.

    Umask is used to set the value that proftpd will use when calling umask(2). The umask(2) function works something like this:

      new file mode = base-mode - umask
    
    (Technically, the operation is base-mode & ~umask). Thus, with a base-mode of 0666, and a umask of 0022, the permissions on the newly created file will be 0644 (e.g. rw-r--r--).

    A quick review of permission bits:

      4 is read permission (r)
      2 is write permission (w)
      1 is execute permission (x)
    
    The first digit of a mode (0750, for example) is used to specify some special bits (e.g. set-user-ID, set-group-ID, and the "sticky bit"). The second digit, the 7 in this example, specifies the user owner permissions, and is a sum of the above permission bits: 7 = 4 + 2 + 1 (e.g. rwx). Group owner permissions are specified by the third bit, 5: 5 = 4 + 1 (e.g. r-x). And finally, other or world permissions are specified using the last bit, which in the example is 0 (no permissions, e.g. ---).

    Here are some concrete examples to help illustrate things:

    Mode Label Description
      0777     rwxrwxrwx   read/write/execute permissions for user owner, group owner, and other
      0666     rw-rw-rw-   read/write permissions for user owner, group owner, and other
      0755     rwxr-xr-x   read/write/execute permissions for user owner, read/execute permissions for group owner and other
      0750     rwxr-x---   read/write/execute permissions for user owner, read permission for group owner, no permissions for other
      0644     rw-r--r--   read/write permissions for user owner, read permission for group owner and other
      0511     r-x--x--x   read/execute permissions for user owner, execute permission for group owner and other

    The proftpd daemon always starts with a base-mode of 0666 when creating files. Note that Umask can only be used to "take away" permissions granted by the base-mode; it cannot be used to add permissions that are not there. This means that files uploaded to a proftpd server will never have the execute permission enabled by default, since the 0666 base-mode does not have any execute bits enabled). This is a conscious security design decision. For directories, a different base-mode of 0777 is used. The umask used for directories can be configured using the optional second parameter to the Umask directive; if this second parameter is not used, the umask used for created directories will default to the same umask as used for files.

    If it is necessary to make uploaded files executable, the SITE CHMOD FTP command can be used:

      SITE CHMOD mode file
    
    Use of this command can be restricted using a "command" of SITE_CHMOD in a <Limit> section. For example, this section of a proftpd.conf file:
      <Limit SITE_CHMOD>
        AllowUser ftpadmin
        DenyAll
      </Limit>
    
    will deny everyone except user ftpadmin from being able to use the SITE CHMOD command to change the permissions on files via FTP. Note that this construction is recommended instead of using the deprecated (as of proftpd-1.2.2rc2) AllowChmod configuration directive.

    Examples of Using the Umask Directive
    You have just installed proftpd, and now need to figure out what permissions file/directories created on your FTP server should have. As a conscientious FTP server administrator, you want files/directories to have the minimum necessary permissions (rather than letting users have access to files/directories that they do not need).

    If only the user who creates the files and directories should have full access, e.g. so they can read and write their own files, then you might use:

      # Only the user can see their own files/directories
      Umask 0066 0077
    
    With this configuration, a newly uploaded file would have 0600 (rw-------) permissions:
      0600 = 0666 - 0066
    
    and a newly created directory would have 0700 (rwx------) permissions:
      0700 = 0777 - 0077
    

    Another common case is where you have many users who are uploading files for sharing with other users. So you want the files to be readable by everyone, but only the user who uploaded the file should have permission for writing/changing the file. For this, you might use:

      # Only the user can change their own files
      Umask 0022
    
    With this configuration, a newly uploaded file would have 0644 (rw-r--r--) permissions:
      0644 = 0666 - 0022
    
    and a newly created directory would have 0755 (rwxr-xr-x) permissions:
      0755 = 0777 - 0022
    

    Frequently Asked Questions

    Question: How can I configure proftpd so that I can upload a file with 770 permissions?
    Answer: Short answer: you can't. Too many FTP servers, in the past, would allow users to upload executable files. Hackers would use this capability, and then exploit a flaw in one of the servers on that machine to execute the crafted file they just uploaded. Thus ProFTPD does not allow uploading of files with execute permissions.

    The workaround, as mentioned above, is to allow the client to use the SITE CHMOD command to change the permissions on the file to have the execute permissions.

    Question: I have a Umask value of 0066, so that only I have read/write permissions on my files. But other users can delete my files! Is this a proftpd bug?
    Answer: No. The permission for deleting a file is not governed by the write permission on the deleted file; it is controlled by the write permission on the directory containing the file.

    If you think of a directory as a "table of contents", with entries for each of the files in that directory, then deleting a file means deleting the entry for that file from the "table of contents", which is a write on the directory (not on the deleted file).

    Let's assume that your files were in a directory whose permissions were 0777 (rwxrwxrwx). This means that everyone has write permissions in that directory. It also means that everyone can delete files from that directory.

    Now let's assume that your files instead were in a directory whose permissions where 0755 (rwxr-xr-x). This means that only the user owner of the directory can delete files from that directory, and no one else.

    For directories which contain files from different users, one of the little-known (and very useful) permissions to have for the directory is 1777 (rwxrwxrwt). The leading 1 (and t) indicates the "sticky bit". This obscure bit is little used these days, except in this useful configuration. When the sticky bit is set on a directory (making it a "sticky directory"), normal users may not delete or rename files of other users in that directory. Because of this property, "sticky directories" are quite useful as shared directories (e.g. /tmp).


    Last Updated: $Date: 2012/03/24 18:41:57 $

    proftpd-dfsg-1.3.5~rc3/doc/howto/Compiling.html0000644000175000017500000010170412067410532021264 0ustar frankiefrankie ProFTPD mini-HOWTO - Compiling ProFTPD

    Compiling ProFTPD


    The ProFTPD source code is designed to be configured for compilation on the target system by a single shell script, named configure, located in the top-level directory of the source distribution, e.g.:

      # cd proftpd-version/
      # ls -al configure
      -rwxr--r--    1 tj       tj        1155157 Nov 18 19:54 configure
    
    This configure script, generated by the GNU autoconf tool, will analyze your system and create a config.h file that should allow ProFTPD to compile cleanly.

    ProFTPD is designed to be very flexible, which necessarily leads to extra compile-time and run-time configuration complexity. The configure script also can be used to customize your build, setting compile-time options based on command-line options that you provide. In particular, software modules to be used by ProFTPD may be chosen this way.

    In addition to the config.h file generated by the configure script, the file include/options.h:

      # cd proftpd-version/
      # ls -al include/options.h
      -rw-r--r--    1 tj       tj           7212 Nov 15 14:34 include/options.h
    
    contains a number of easily tweakable compile-time options which will affect ProFTPD's operation. These options are never modified by the configure script. Changing these values is rarely needed, and most can be overriden at run-time by directives in the proftpd.conf configuration file.

    To see the full list of command-line options for configure, run:

      # ./configure --help
    
    Should you change your mind about which options to use, you will need to re-run configure with the new options. But first you will need to clean up the previous results by doing:
      # make clean
      # ./configure ...
    
    The rest of this document covers the various options of the configure script in detail.

    When you run the configure script by itself, without any command-line options, you will get the defaults:

      # cd proftpd-version/
      # ./configure
    
    What are the defaults?

    Layout Options
    One of the first decisions to make is where you want ProFTPD, and all of its supporting files, to be installed on your system. By default, the ProFTPD build system installs the files in a layout under the /usr/local/ directory. The /usr/local/ directory functions as the default prefix directory. Thus the layout of installed files will look like:

      /usr/local/bin/ftpcount
      /usr/local/bin/ftpdcount
      /usr/local/bin/ftptop
      /usr/local/bin/ftpwho
      /usr/local/bin/prxs
      /usr/local/etc/proftpd.conf
      /usr/local/include/proftpd/*.h
      /usr/local/lib/pkgconfig/proftpd.pc
      /usr/local/libexec/*.{a,la,so}
      /usr/local/sbin/ftpshut
      /usr/local/sbin/in.proftpd
      /usr/local/sbin/proftpd
      /usr/local/share/locale/lang/LC_MESSAGES/proftpd.mo
      /usr/local/share/man/man1/ftpcount.1
      /usr/local/share/man/man1/ftptop.1
      /usr/local/share/man/man1/ftpwho.1
      /usr/local/share/man/man5/xferlog.5
      /usr/local/share/man/man8/ftpdctl.8
      /usr/local/share/man/man8/ftpshut.8
      /usr/local/share/man/man8/proftpd.8
      /usr/local/var/proftpd/*
    
    To place all of these files under the /usr/ directory rather than /usr/local/, you would change the prefix directory using the --prefix option:
      # ./configure --prefix=/usr
    

    You can also change only portions of the layout, for just the binaries or the configuration file or other parts:

    --bindir Change prefix-dir/bin/
    --libexecdir Change prefix-dir/libexec/
    --localstatedir Change prefix-dir/var/
    --sbindir Change prefix-dir/sbin/
    --sysconfdir Change prefix-dir/etc/

    Thus to place the configuration file in /etc/ and the runtime state files in /var/proftpd/, you would use:

      # ./configure --sysconfdir=/etc --localstatedir=/var/proftpd
    

    Installer Options
    When you go to install ProFTPD, the build system will install all of the files and directories as user 'root' and group 'root' (or group 'wheel', depending on your system). This user/group combination is used because on most systems, that is the user which has permissions for creating new files/directories under the /usr/local/ directory.

    If you wish to install using a different user or group ownership, set the install_user and install_group environment variables before running configure. Using a Bourne-ish style shell (e.g. sh, ksh, bash), you can do this on the command line like this:

      # install_user=root install_group=wheel ./configure
    

    For example, I do a lot of personal ProFTPD builds, and so I typically use:

      # install_user=tj install_group=tj ./configure --prefix=/home/tj/proftpd/devel/build/ ...
    

    Feature Options
    There are some features which are part of the core proftpd engine itself which can be configured via compile-time options. The list below talks about the more common of these feature options:

    • --disable-auth-file
      The
      mod_auth_file module is included in the build by default; use this option to not include the module.
    • --enable-autoshadow
      Enables support for autoshadow
    • --enable-ctrls
      Enables support for the Controls feature; this is not enabled by default.
    • --enable-dso
      Enables support for DSO modules (also called "shared modules") by including the mod_dso module in the build. This is not enabled by default.
    • --enable-facl
      Enables support for POSX ACLs, which is not enabled by default. Note that the related mod_facl module must be added separately to the build, using --with-modules.
    • --disable-ident
      Disables support for IDENT (RFC1413) lookups by not adding the mod_ident module to the build. This module is added by default.
    • --disable-ipv6
      Disables IPv6 support, which is enabled by default. Note that IPv6 support can be disabled at run-time using the UseIPv6 directive in your proftpd.conf file.
    • --enable-memcache
      Enables support for using memcached for caching by including the mod_memcache module in the build. This is not enabled by default.
    • --enable-nls
      Enables support for different character sets and encodings, for translated response messages, and for the LANG FTP command via the mod_lang module. This is not enabled by default.
    • --enable-pcre
      Enable use of PCRE for POSIX regular expressions, rather than the system library. This is not enabled by default. Note that pcre-7.0 or later is required.
    • --disable-sendfile
      Disables support for the sendfile(2) function, which is enabled by default. Read here for information on when and why this is a Good Thing to do.
    • --enable-devel
      Enables code/behavior that is specifically used by developers and maintainers; this code is disabled by default. The uses for this option are covered more fully below; suffice to say that unless you really know what you are doing, you should not be using this option in your configure command.
    • --with-lastlog=/path/to/lastlog
      Enables support for lastlog logging; see the lastlog(8) man page. The optional /path/to/lastlog argument is only needed if your lastlog file location is not a standard location. Note that this configure option is needed in order to support the UseLastlog configuration directive at runtime. This feature is not enabled by default.

    There are of course other feature-specific configure options, but most of the time, most people will not need to know about or use them.

    Module Options
    Now we come to the fun part: deciding which of the many different modules to include in our build. Before doing this, though, you need to know that some modules are automatically included in the build:

    In addition to these modules, there are some modules which may be automatically added, depending on your system:
    • mod_auth_file.c
      This module is automatically added unless --disable-auth-file is used
    • mod_auth_pam.c
      This module is automatically added if PAM support is detected
    • mod_cap.c
      This module is automatically added if Linux capabilities support is detected
    • mod_cap.c
      This module is automatically added unless --disable-ident is used

    The above modules all live under the modules/ directory in the source distribution. So what modules are left to choose from? All of the modules under the contrib/ directory.

    Optional ProFTPD modules are added to the build using the --with-modules option. The value you provide is a colon-delimited list of the module names you wish to add, as staticly linked modules. Thus if you wanted to add LDAP and SSL/TLS support to your proftpd, you would list the appropriate modules in the --with-modules list:

      # ./configure --with-modules=mod_ldap:mod_tls ...
    
    Do not include the names of any modules under the modules/ directory; the modules there are either mandatory or conditional. Attempting to include a non-optional module in the --with-modules list will result in a configure error.

    The --with-shared option works much like --with-modules. You provide a colon-delimited list of names of modules to be compiled as shared modules. Note that using the --with-shared option requires the use of --enable-dso. Thus to add LDAP and SSL/TLS support as shared modules, you would use:

      # ./configure --enable-dso --with-shared=mod_ldap:mod_tls ...
    
    Failure to include the --enable-dso option when using --with-shared results in a configure error:
      configure: error: cannot build shared modules without DSO support -- aborting
    

    You can add some of the automatically included modules as shared modules, but not all of them. The following automatically included modules cannot be compiled as shared/DSO modules:

    • mod_auth.c
    • mod_auth_unix.c
    • mod_core.c
    • mod_ls.c
    • mod_xfer.c
    If your --with-shared list includes one of the above modules, it will result in a configure error:
      # ./configure --enable-dso --with-shared=mod_auth_unix ...
      configure: error: cannot build mod_auth_unix as a shared module
    
    Why can't these be shared modules? These modules must appear in the proftpd binary in order for it to function as a proper FTP server. Yes, even mod_auth_unix.c; it is the default/fallback mechanism for obtaining user/group names/IDs.

    Do not use --with-modules or --with-shared multiple times in your configure command; only the last one appearing in the configure command will be used. You must consolidate all of the modules you wish to add into a single colon-delimited list.

    Header and Library Options
    The --with-includes option is used to add additional directories containing header files to the system-defined list of header file directories used by the compiler. Likewise, the --with-libraries option is used to add additional directories containing libraries to the list of library directories searched by the linker. Both options take colon-delimited paths as the parameter.

    For example, on Solaris, you have to explicitly tell the compiler and linker to use the /usr/local/include and /usr/local/lib directories:

      # ./configure --with-includes=/usr/local/include --with-libraries=/usr/local/lib ...
    

    Or you may have the MySQL or OpenSSL packages installed in custom locations, and you need to tell configure about those locations:

      # ./configure --with-modules=mod_sql:mod_sql_mysql:mod_tls \
        --with-includes=/usr/local/mysql/include/mysql:/usr/local/openssl/include \
        --with-libraries=/usr/local/mysql/lib/mysql:/usr/local/openssl/lib
    
    These options are commonly used to specify the locations for LDAP, OpenSSL, database, and other software packages used by modules.

    Just as using --with-modules multiple times does not work, using --with-includes or --with-libraries multiple times does not work. Consolidate all of the directories for headers (or libraries) into a single colon-delimited list, and use one --with-includes option and one --with-libraries option.

    Environment Variables
    As with most other GNU autoconf-based build system, the ProFTPD configure script honors these environment variables:

    • CPPFLAGS
    • CFLAGS
    • DESTDIR
    • LDFLAGS
    • LIBS
    Use of these environment variables is for the more advanced users, system administrators, and software developers and packagersl who know the environment variable semantics.

    Putting It All Together
    Now, let's configure the build system for a proftpd that does not include IDENT support, is installed under /opt/proftpd/ as user and group 'ftpd', has staticly linked SSL/TLS support and dynamically loaded SQL backend modules:

      # install_user=ftpd install_group=ftpd ./configure \
        --prefix=/opt/proftpd \
        --disable-ident \
        --enable-dso \
        --with-modules=mod_tls \
        --with-shared=mod_sql:mod_sql_mysql:mod_sql_postgres \
        --with-includes=/usr/local/openssl/include:/usr/local/mysql/include/mysql:/usr/local/postgres/include \
        --with-libraries=/usr/local/openssl/lib:/usr/local/mysql/lib/mysql:/usr/local/postgres/lib
    
    Hint: if your configure command becomes long or complicated, you might try storing it in a sh script file, say 'proftpd-conf.sh'.

    Watch the output of the configure script. After the configure command has run, you may wish to inspect the config.h file to make sure configure didn't make any wrong "guesses" for your platform. If the configure command fails, keep a copy of the generated config.log file. Include that file, and the configure error, when asking/troubleshooting the error via the mailing lists.

    Compiling
    Now you are ready to actually compile the source code into working executables, using all of your selected options and features and capabilities. To do this, imply run 'make' from the top-level source directory:

      # cd proftpd-version/
      # make
    
    On some systems (e.g. BSDI), you may need to use GNU make (often called gmake or gnumake) instead of the default system make. Watch the output of the compile process and make sure no errors occur. On some platforms (notably AIX and IRIX) you may see some compilation or link warnings. These generally can be ignored.

    If you are interested in testing the compiled executables, read this howto about the testsuite that comes with the ProFTPD source code.

    To install the compiled executables, use:

      # cd proftpd-version/
      # make install
    
    You are now prepared to start up and use your compiled proftpd.

    Developer Options
    OK, so you think you want to use the --enable-devel configure option? You must keep in mind that this option is intended only for development purposes; it is not recommended for use in production builds or packages. If you are using a proftpd installed from a package, try this command:

      # /usr/local/sbin/proftpd -V
    
    if you see "+ Developer support" in the output, it means that your package provider used the --enable-devel option when they should not have. Let the package provider know about this, and point them to this document.

    Still here? If so, you are ready to learn how --enable-devel is used for development and debugging. The --enable-devel option, like many of ProFTPD's configure options, takes a colon-delimited list of option names. The full list of supported developer options is shown here:

      # ./configure --enable-devel=coredump:nodaemon:nofork:profile:stacktrace ...
    
    You can also use just --enable-devel by itself, without any specific option names:
      # ./configure --enable-devel ...
    
    When --enable-devel is used, the executables that are installed by the ProFTPD build system will not be stripped of their debugging symbols, as is usually done in non-developer builds.

    Let's look at what each one of these developer options does.

    Enabling coredumps using the coredump option is a bad idea. ProFTPD goes out of its way to ensure that it does not generate coredump files. Since the proftpd server is usually run with root privileges (in order to use port 21, look up passwords, etc), any coredump files generated could possibly contain sensitive information (such as users' passwords). The only people who should be looking at coredump files are developers, and even then there are better ways of debugging issues. Note that if the coredump option is used, proftpd will not switch the UID/GID to the User/Group defined in the config file, nor to that of the logged-in user. Unix kernels are notoriously picky about generating coredumps for processes that have changed their effective UID/GID; they won't do it. Thus the ID switching is disabled in order to make it possible to get a coredump. Again, it is a bad idea to run a proftpd built with coredump in production.

    The nodaemon option makes it such that the proftpd server cannot daemonize. It cannot detach from the terminal, and cannot run in the background. This is mostly useful for running proftpd under a debugger such as gdb.

    The nofork option makes a proftpd that cannot use the fork(2) system call to create a new process to handle the client connection, turning proftpd into a single-process server. Like the nodaemon option, this is usefuly mainly for running proftpd under a debugger.

    The profile option causes a profiling library to be linked into the compiled proftpd executable. Running the executable will then automatically write out profiling information suitable for use by a profiler such as gprof.

    Finally, there is the stacktrace option. It is possible, if the GNU C library is used, to have a program automatically provide a stack trace showing the function call stack, such as when the SIGSEGV signal is received (i.e. the program segfaulted). Often times when debugging issues like segfaults, the hardest part is pinpointing the exact source of the segfault, and what functions were called to reach that point. Thus seeing a stack trace (also called a "backtrace") is quite useful for developers.

    Let's say you configured the build for stacktrace support:

      # ./configure --enable-devel=stacktrace ...
    
    If/when a SIGSEGV occurs, the logs should show something like this:
      golem.castaglia.org (127.0.0.1[127.0.0.1]) - ProFTPD terminating (signal 11)
      golem.castaglia.org (127.0.0.1[127.0.0.1]) - FTP session closed.
      golem.castaglia.org (127.0.0.1[127.0.0.1]) - -----BEGIN STACK TRACE-----
      golem.castaglia.org (127.0.0.1[127.0.0.1]) - [0] ./proftpd [0x809b1e1]
      golem.castaglia.org (127.0.0.1[127.0.0.1]) - [1] ./proftpd(call_module+0x53) [0x8072c63]
      golem.castaglia.org (127.0.0.1[127.0.0.1]) - [2] ./proftpd(strftime+0x14cf) [0x8051bef]
      golem.castaglia.org (127.0.0.1[127.0.0.1]) - [3] ./proftpd(pr_cmd_dispatch+0x167) [0x8051f2f]
      golem.castaglia.org (127.0.0.1[127.0.0.1]) - [4] ./proftpd(strftime+0x1fd3) [0x80526f3]
      golem.castaglia.org (127.0.0.1[127.0.0.1]) - [5] ./proftpd [0x8053e12]
      golem.castaglia.org (127.0.0.1[127.0.0.1]) - [6] ./proftpd [0x805484d]
      golem.castaglia.org (127.0.0.1[127.0.0.1]) - [7] ./proftpd [0x8057975]
      golem.castaglia.org (127.0.0.1[127.0.0.1]) - [8] ./proftpd(main+0x9d1) [0x8058625]
      golem.castaglia.org (127.0.0.1[127.0.0.1]) - [9] /lib/i686/libc.so.6(__libc_start_main+0x93) [0x40076507]
      golem.castaglia.org (127.0.0.1[127.0.0.1]) - [10] ./proftpd(strcpy+0x31) [0x8051001]
      golem.castaglia.org (127.0.0.1[127.0.0.1]) - -----END STACK TRACE-----
    
    These function call symbols or "frames" are generated automatically by the C library; the hexadecimal numbers are memory addresses.

    The key for tracking down the location of the segfault is the first frame; in this case, "[0] ./proftpd [0x809b1e1]" and the memory address 0x809b1e1. Using the addr2line command (which you may need to install separately on your system) and that memory address, you can determine the location of the segfault source:

      # addr2line -e /usr/local/sbin/proftpd 0x809b1e1
    
    In this particular case, I saw:
      # addr2line -e /usr/local/sbin/proftpd 0x809b1e1
      /home/tj/proftpd/cvs/proftpd/modules/mod_auth.c:1723
    
    which is the location of test code I added to deliberately trigger a segfault.

    There are some other noteworthy requirements for this automatic stacktrace support. First, each proftpd binary can be subtly different, depending on the exact configure command, shared modules loaded, etc. Thus the addr2line command must be run on the same system as the segfaulting proftpd binary, and must be run on that same binary. Using the memory address and addr2line on a different proftpd, or on a different system, will not work. Second, using the stacktrace developer option disables the changing of the process title that proftpd normally does. The obtaining of the stack symbols that is done uses the process title, and if the stacktrace option did not disable that process title changing, the output would be much less legible. The automatic stacktrace code in the C library will not work if the process has been chrooted (i.e. you use the DefaultRoot and/or <Anonymous> directives); I suspect this has to do with hardcoded assumptions in the C library itself which are broken in a chrooted process. Finally, use of the -fomit-frame-pointer compiler option will cause the stacktrace feature to not work; those omitted frame pointers contain exactly the frame symbols/addresses that we want to capture.

    The stacktrace feature is known to work on Linux platform. On FreeBSD, you need to install the libexecinfo library from the Ports collection. On Mac OSX, you must be running 10.5 in order to have the proper C library support.

    Frequently Asked Questions

    Question: Why do I get a configure error about a "duplicate build request", like this:

      checking checking for duplicate module requests... yes
      configure: error: duplicate build request for mod_delay -- aborting
    
    Answer: This happens when your --with-modules list contains one of the automatically included modules (see above). In this example, the mod_delay module appeared in the --with-modules list.

    Note that older releases of ProFTPD did not check for these types of "duplicate build requests". If you are having problems with your proftpd and you see the same module appear multiple times in the output from running:

      # /usr/local/sbin/proftpd -l
    
    Then you should re-configure and re-compile your proftpd, making sure that no automatically included modules appear in your --with-modules configure option.

    Question: Why do I get a configure error like this:

      configure: error: source file './modules/d_auth_pam.c' cannot be found -- aborting
    
    Answer: Notice how the name of the module reported there is "d_auth_pam.c", rather than "mod_auth_pam.c"? If you see a mangled module name like this, it probably means that your --with-modules or --with-shared module lists contain a double colon, e.g.:
      # ./configure --with-modules=mod_sql::mod_sql_mysql:...
    
    or:
      # ./configure --with-shared=mod_sql::mod_sql_mysql:...
    
    Use only a single colon between module names; this should fix this error.

    Question: I can't seem to compile mod_tls and mod_sql. Using one or the other works (i.e. shows up in the `proftpd -l` list), but not both. I'm using the following configure command:

      # ./configure --with-modules=mod_tls --with-modules=mod_sql:mod_sql_mysql ...
    
    Answer: The problem is that the --with-modules option cannot appear multiple times in the configure command. If it does, only the last one seen on the command line wins. In this case, the user would need to put all of the desired modules into one colon-delimited list, e.g.:
      # make clean
      # ./configure --with-modules=mod_tls:mod_sql:mod_sql_mysql ...
    
    And keep in mind that the same restriction holds true for the --with-includes and --with-libraries options.

    Question: I try to start my proftpd, but I get this error:

      warning: the mod_sql_mysql module has not been properly intialized.  Please
      make sure your --with-modules configure option lists mod_sql *before*
      mod_sql_mysql, and recompile.
    
    Answer: The issue here is that the mod_sql family of modules (including mod_sql_mysql, mod_sql_postgres, mod_sql_odbc, and mod_sql_sqlite) is rather particular about the order in which they appear in the --with-modules list. The ordering affects the order in which the modules are loaded when proftpd starts up. The above error, for example, happens when --with-modules looks like:
      # ./configure --with-modules=mod_sql_mysql:mod_sql (wrong)
    
    but the mod_sql module needs to be loaded first, so that later, when mod_sql_mysql loads, the expected mod_sql code is present. Thus the proper ordering is to make sure that mod_sql appears before any of the database-specific backend modules:
      # ./configure --with-modules=mod_sql:mod_sql_mysql (correct)
    

    Note that this ordering issue occurs for the mod_quotatab and mod_wrap2 families of modules as well.

    Question: Why do I get a "Controls support required" error when I try to compile proftpd?

      mod_ctrls.c:49:3: #error "Controls support required (use --enable-ctrls)"
    
    Answer: The error is trying to tell you that that module (the mod_ctrls module, in this case) requires Controls support, and that you need to supply the --enable-ctrls option in your configure command when compiling proftpd.

    Question: How do I get a statically linked proftpd binary?
    Answer: To do this, using the following:

      # make clean
      # ./configure LDFLAGS="-Wl,-static" ...
    
    Do not try to use the "-static" value for the CFLAGS or LDFLAGS environment variables, or try to edit the Make.rules file to tweak the options. ProFTPD's build system uses libtool, and thus the above method is the way to get a statically linked proftpd executable:
      # make
      # ldd ./proftpd
        not a dynamic executable
    

    Question: I have a very long line in my proftpd.conf, and when I try to start proftpd I see this:

      warning: handling possibly truncated configuration data at line 17 of '/etc/proftpd.conf'
      Fatal: unknown configuration directive ')"' on line 18 of '/etc/proftpd.conf'
    
    How can I avoid this error?
    Answer: If possible, you should try to break up your long directive line into multiple lines, using a backslash. For example:
      Allow 1.2.3.4 5.6.7.8 9.10.11.12
    
    can also appear as:
      Allow \
        1.2.3.4 \
        5.6.7.8 \
        9.10.11.12
    
    However, if this approach cannot be used (e.g. your configuration has a single parameter which exceeds the 1024 byte buffer limit, and which cannot be broken up), then you will have to recompile proftpd with a larger buffer size. To do this, use the --enable-buffer-size configure option, e.g.:
      # ./configure --enable-buffer-size=2048 ...
    

    Question: What is the difference between the --enable-shadow and the --enable-autoshadow configure options, and when do I use them?
    Answer: The --enable-shadow configure option enables support for shadow files, e.g. /etc/shadow and the related C library functions. On other Unix platforms, though, use "transparent shadow" support, where the normal C library functions are used; only when root privileges are used to call those functions will the actual password be obtained from the shadow files. Support for this approach is enabled by the --enable-autoshadow option.

    If you are not sure which to use, try using both --enable-shadow and --enable-autoshadow


    $Date: 2012/12/28 21:38:34 $
    proftpd-dfsg-1.3.5~rc3/doc/howto/Sendfile.html0000644000175000017500000001663111530352214021074 0ustar frankiefrankie ProFTPD mini-HOWTO - Sendfile Support

    Sendfile Support


    What is "sendfile"?
    Many Unix kernels provide a function called sendfile(2), a system call which provides a "zero-copy" way of copying data from one file (or socket) descriptor to another. The phrase "zero-copy" refers to the fact that all of the copying of data between the two descriptors is done entirely by the kernel, with no copying of data into userspace buffers. The normal way of copying data between files involves using the read(2) system call to read data from the source descriptor into a userspace buffer, then calling the write(2) system call to write that buffer to the destination descriptor. This copying of the data twice (once into the userland buffer, and once out from that userland buffer) imposes some performance and resource penalties. The sendfile(2) avoids these penalties by avoiding any use of userland buffers; it also results in a single system call (and thus only one context switch), rather than the series of read(2)/write(2) system calls (each system call requiring a context switch) usually used for data copying.

    Unix kernels handle a socket as just another file descriptor; this means that sendfile(2) can be used to efficiently copy data from a file on disk to a network socket, e.g. for downloading a file.

    Use of sendfile(2) in ProFTPD
    For the above reasons, ProFTPD will, by default, attempt to use the sendfile(2) function for all downloads. However, there are a few cases where ProFTPD will specifically avoid the use of sendfile(2):

    • When data are transferred in ASCII mode; note that this automatically applies to directory listings (which, by definition, are ASCII transfers)
    • When RFC2228 data channel protection is in effect (e.g. SSL/TLS) When transfers are being throttled via the TransferRate directive
    • When MODE Z data compression is being used (via the mod_deflate module)
    The use of sendfile(2) can also be explicitly configured at run-time by using the following in your proftpd.conf file:
      UseSendfile off
    

    Sendfile support in the compiled proftpd daemon can also be disabled at compile time, by using the --disable-sendfile configure option, e.g.:

      # ./configure --disable-sendfile ...
    
    This is not recommended unless necessary.

    Known Issues with sendfile(2)
    As useful as the sendfile(2) function can be, there are unfortunately cases where bad implementations of the function can cause problems. These problems manifest as broken or aborted downloads, or as downloaded data being corrupted, or even as downloaded files being larger than the original file.

    The sendfile(2) function requires support from both the Unix kernel and from the filesystem drivers which handle the filesystems for the file descriptors being used. The following operating systems have had reports of issues when using sendfile(2):

    There have also been some issues reported from users of virtualization technologies such as OpenVZ and VMware.

    There have been cases where it was the filesystems, rather than the kernels, which appeared to have been the culprits in sendfile(2) problems:

    • Network filesystems (e.g NFS, SMBFS/Samba, CIFS)
    • Virtualized filesystems (OpenVZ, VMware, and even Veritas)
    • Other filesystems (e.g. NTFS and tmpfs on Linux)
    Again, if you encounter issues with downloading files from ProFTPD when those files reside on a networked or virtualized filesystem, try using "UseSendfile off" in your proftpd.conf.

    Bugs in certain network cards have been reported on Linux, where the use of sendfile(2) triggers TCP checksum offloading bugs on these cards when using IPv6.

    Bug 3081 also demonstrates an interesting sendfile(2) issue. It is a special case where the FTP client and server are on the same machine, sendfile(2) is used when downloading a file, and the client is downloading the file to the exact same filesystem path from which the server is reading the file. When this happens, proftpd will "hang". The fix for this situation is relatively simple: "Don't do that."

    If your Unix kernel and your filesystems work together to support the use of sendfile(2) properly, you may run into one last potential issue with ProFTPD's ftptop and ftpwho utilities when sendfile(2) is used (at least for versions of proftpd prior to 1.3.4rc1). These utilities rely on data in ProFTPD's ScoreboardFile for providing their information, including transfer rates. The progress of a file being downloaded is tracked in the ScoreboardFile as part of the download process; specifically, as part of the normal read(2)/write(2) loop. When the sendfile(2) function is used, the ScoreboardFile is not updated with the progress (since all of the data copying is being handled by the kernel, not by proftpd code at that point). Thus for downloads which use sendfile(2), ftptop and ftpwho often report the transfer rate as "Inf".

    The transfer rates for uploads are still reported properly by ftptop and ftpwho, however.

    In proftpd-1.3.4rc1 and later, the UseSendfile directive changed. Now you can use UseSendfile in <Directory> sections and .ftpaccess files. This allows sites to disable use of sendfile(2) just for specific directories/filesystems where it might be a problem, e.g.:

      <Directory /path/to/nfs/files>
        UseSendfile off
      </Directory>
    

    Instead of the usual on/off parameters, the UseSendfile directive can also take a byte length, or a file size percentage, as parameters. These parameters can be used so that sendfile(2) is used for more optimal downloads while still letting ftptop and ftpwho display download progress rates. To use this, the best way to use specify a file size percentage such as 10% or 25%; this means that sendfile(2) will be used for each 10% or 25% percent of the size of the file being downloaded:

      <Directory />
        UseSendfile 10%
      </Directory>
    


    $Date: 2011/02/21 02:57:16 $
    proftpd-dfsg-1.3.5~rc3/doc/howto/Controls.html0000644000175000017500000003011212073354327021146 0ustar frankiefrankie ProFTPD mini-HOWTO - Controls

    Controls and mod_ctrls


    What Controls Are
    ProFTPD version 1.2.10rc1 introduced a new capability: Controls. Controls are a way to communicate directly with a standalone proftpd daemon while it is running. This provides administrators a way to alter the daemon's behavior in real time, without having to restart the daemon and have it re-read its configuration. Changing log levels, kicking connected clients, disabling individual virtual servers, etc. are all possible. The Controls functionality includes an API that third-party modules can use to add new control actions.

    The functionality involves a client and a server communicating over a Unix domain socket, using a simple text-based protocol. A new program, ftpdctl, is distributed with ProFTPD; ftpdctl is a Controls client. The server side of the Controls functionality is the mod_ctrls module, which is compiled into a proftpd daemon when the --enable-ctrls configure option is used. Note, however, that the Controls functionality only works for proftpd daemons whose ServerType is standalone; proftpd daemons run via inetd/xinetd cannot support Controls and the ftpdctl program.

    Configuring mod_ctrls
    Here's an example configuration for mod_ctrls:

      <IfModule mod_ctrls.c>
        ControlsEngine        on
        ControlsACLs          all allow group ftpadm
        ControlsMaxClients    2
        ControlsLog           /var/log/proftpd/controls.log
        ControlsInterval      5
        ControlsSocket        /tmp/ctrls.sock
        ControlsSocketOwner   ftpd ftpd
        ControlsSocketACL     allow group ftpadm
      </IfModule>
    
    The first configuration directive you will want to use is the ControlsEngine directive, which enables the processing of Controls requests by the engine within the mod_ctrls engine.

    When first configuring mod_ctrls and its modules, you will probably want to configure a ControlsLog. The mod_ctrls modules will log any errors they have to this file (unless the module has its own module-specific log), as well as all control requests made using ftpdctl. Like most proftpd log files, the directive should use the full path to the log file, and the file cannot be in a world-writeable directory.

    The ControlsInterval directive configures how often mod_ctrls checks for connecting clients such as ftpdctl. Often when using ftpdctl, the system administrator may notice a long pause before ftpdct responds. This delay is probably caused by the configured ControlsInterval. A related directive is ControlsMaxClients, which sets how many clients are handled at one time. If more than the configured maximum number of clients are attempting to send control requests, mod_ctrls will wait to handle the remaining clients until its next check.

    The ControlsSocket directive is used to configure the path to the Unix domain socket on which mod_ctrls should listen. This path should be in a place where ftpdctl users have access to it, and should have read and write permissions. The ControlsSocketOwner directive explicitly configures the ownership the created Unix domain socket file should have. This means that the configuration above:

      ControlsSocket        /tmp/ctrls.sock
      ControlsSocketOwner   ftpd ftpd
    
    overrides the default location of the Unix domain socket, and tells mod_ctrls to use /tmp/ctrls.sock, and to make the socket owned by user ftpd and group ftpd. The default ownership of the socket is user root, group root.

    Controls Access Control Lists
    Communicating with the daemon process allows for some great features, but it also allows the potential to easily abuse the system. Thus, by default, all users including user root are denied access to all ftpdctl actions. Access for control actions must be explicitly granted. Also, be aware that the users and groups configured in these ACLs are system users and groups, not the virtual users and groups that proftpd may have been configured to use. The group will be only the primary group of the user; supplemental group memberships are currently ignored.

    The mod_ctrls first checks whether the connecting client has been granted the ability to use the Unix domain socket itself. This access list is controlled by the ControlsSocketACL directive. By default, every Controls client can use the socket. Thus, in the example configuration above:

      ControlsSocketACL     allow group ftpadm
    
    only the system group ftpadm would be allowed to send Controls requests to the Unix domain socket; all other users and groups will be denied.

    Next, ACLs on the specific control action requested by the connecting client will be check. Most modules that use the Controls API will have their own module-specific directives for setting ACLs on the specific actions implemented by that module. For mod_ctrls, the ControlsACLs configuration directive is used. In the example configuration we see:

      ControlsACLs all allow group ftpadm
    
    which allows only the system group ftpadm to use all of the control actions provided by mod_ctrls. If one wanted to allow all users to use all of the control actions, it would be:
      ControlsACLs all allow user *
    
    However, if one wanted to specify separate ACLs for separate actions, then the ControlsACLs directive would be used multiple times, like so:
      ControlsACLs insctrl allow group wheel
      ControlsACLs lsctrl allow user *
      ControlsACLs rmctrl deny group ftp
    

    Why is there such complexity for a simple client/server interaction? The primary answer is that the running proftpd daemon has a lot of privileges, and access to the running daemon should be strictly controlled. Allow few people to have access via control actions; those few should be able to use only the control actions necessary.

    What Controls Do
    The mod_ctrls module provides basic control actions, or commands that ftpdctl can send to the daemon:

    • help
      Lists all registered control actions and a brief description for each
    • insctrl
      Reenable a disabled control action
    • lsctrl
      Lists all enabled control actions and the modules providing them
    • rmctrl
      Disable a control action

    Denied Actions Versus Disabled Actions
    What is the difference between an action that has been denied via an ACL versus an action that has been disabled using the rmctrl action? A disabled action cannot be used by any client, regardless of any ACLs that have been configured for that action. Thus if a system administrator deemed that a particular control action should not be used by anyone, that action can be disabled. The rmctrl action can disable any action implemented by any module using the Controls API, not just actions provided by mod_ctrls. Once disabled, a given action can be re-enabled using the insctrl action. The insctrl and rmctrl actions, in addition to lsctrl, cannot themselves be disabled. For example, to disable an action called foo:

      # ftpdctl rmctrl foo
      ftpdctl: 'foo' control disabled
      # ftpdctl lsctrl
      ftpdctl: help (mod_ctrls.c)
      ftpdctl: insctrl (mod_ctrls.c)
      ftpdctl: lsctrl (mod_ctrls.c)
      ftpdctl: rmctrl (mod_ctrls.c)
    
    Note that the foo action is not listed by lsctrl. Now, reenable that action:
      # ftpdctl insctrl foo
      ftpdctl: 'foo' control enabled
      # ftpdctl lsctrl
      ftpdctl: foo (mod_foo.c)
      ftpdctl: help (mod_ctrls.c)
      ftpdctl: insctrl (mod_ctrls.c)
      ftpdctl: lsctrl (mod_ctrls.c)
      ftpdctl: permit (mod_ban.c)
      ftpdctl: rmctrl (mod_ctrls.c)
    
    And now the foo action, provided by the module mod_foo.c, appears in the lsctrl listing.

    The following shows an example of attempting to disable the lsctrl action. It demonstrates the use of the -v command-line option for ftpdctl, for showing a verbose interaction with mod_ctrls:

      # ftpdctl -v lsctrl
      ftpdctl: adding "lsctrl" to reqargv
      ftpdctl: contacting server
      ftpdctl: sending control request
      ftpdctl: receiving control response
      ftpdctl: debug (mod_ctrls_admin.c)
      ...
    
      # ftpdctl rmctrl lsctrl
    
      # ftpdctl -v lsctrl
      ftpdctl: adding "lsctrl" to reqargv
      ftpdctl: contacting server
      ftpdctl: sending control request
      ftpdctl: receiving control response
      ftpdctl: access denied
    
    The "access denied" message happens because of the special status of the lsctrl action which keeps it from being disablable.

    Admin Controls
    The mod_ctrls module, by itself, is rather unexciting. Other modules, such as mod_ctrls_admin, provide more interesting and useful control actions, including:

    • debug
    • dump
    • kick
    • restart
    • shutdown
    • start
    • status
    • stop
    • trace
    These actions provide basis administrative control over the running proftpd daemon; see the mod_ctrls_admin documentation for more information.

    A basic mod_ctrls_admin configuration is:

      <IfModule mod_ctrls_admin.c>
        AdminControlsACLs all allow user *
      </IfModule>
    
    will allows anyone to use any mod_ctrls_admin control action.

    Here is another configuration, encompassing both mod_ctrls and mod_ctrls_admin:

      <IfModule mod_ctrls.c>
        ControlsEngine        on
        ControlsACLs          all allow group ftpadm
        ControlsMaxClients    2
        ControlsLog           /var/log/proftpd/controls.log
        ControlsInterval      5
        ControlsSocketACL     allow group ftpadm
        ControlsSocket        /tmp/ctrls.sock
        ControlsSocketOwner   ftpd ftpd
    
        <IfModule mod_ctrls_admin.c>
          AdminControlsACLs all allow user dave,bob,lisa
        </IfModule>
      </IfModule>
    
    In this configuration, users dave, bob, and lisa are allowed to use all of the control actions supplied by mod_ctrls_admin. However, unless these users are members of group ftpadm, access will be denied. Only group ftpadm has been allowed access to the mod_ctrls socket itself by the ControlsSocketACL directive.

    What about configuring an ACL for a given control that includes both users and groups? Use:

      AdminControlsACLs restart allow user dave,lisa
      AdminControlsACLs restart allow group ftpadm
    
    What if user dave is not a member of group ftpadm? If configured, both user and group ACLs must deny the client. If either allows access, the client can use that control action.


    Last Updated: $Date: 2013/01/09 20:53:43 $

    proftpd-dfsg-1.3.5~rc3/doc/howto/TLS.html0000644000175000017500000015030612117504263020010 0ustar frankiefrankie ProFTPD mini-HOWTO - FTP and SSL/TLS

    FTP and SSL/TLS


    RFC 4217 defines FTP over SSL/TLS:

      http://www.faqs.org/rfcs/rfc4217.html
    
    The mod_tls module for proftpd is an implementation of RFC 4217.

    RFC 2228 defines FTP Security Extensions, of which mod_tls is one implementation. Another such RFC 2228 implementation is the mod_gss module, available from SourceForge.

    Example mod_tls configuration:

      <IfModule mod_dso.c>
        # If mod_tls was built as a shared/DSO module, load it
        LoadModule mod_tls.c
      </IfModule>
    
      <IfModule mod_tls.c>
        TLSEngine on
        TLSLog /var/ftpd/tls.log
    
        # Support both SSLv3 and TLSv1
        TLSProtocol SSLv3 TLSv1
    
        # Are clients required to use FTP over TLS when talking to this server?
        TLSRequired off
    
        # Server's certificate
        TLSRSACertificateFile /etc/ftpd/server.cert.pem
        TLSRSACertificateKeyFile /etc/ftpd/server.key.pem
    
        # CA the server trusts
        TLSCACertificateFile /etc/ftpd/root.cert.pem
    
        # Authenticate clients that want to use FTP over TLS?
        TLSVerifyClient off
    
        # Allow SSL/TLS renegotiations when the client requests them, but
        # do not force the renegotations.  Some clients do not support
        # SSL/TLS renegotiations; when mod_tls forces a renegotiation, these
        # clients will close the data connection, or there will be a timeout
        # on an idle data connection.
        TLSRenegotiate none
    
      </IfModule>
    

    Debugging
    There are a couple of tools available for debugging and analysing FTPS traffic. One of the easiest to use is the s_client application, part of OpenSSL.

    The following examples assume that proftpd+mod_tls is listening on 127.0.0.1, port 21:

      # openssl s_client -connect 127.0.0.1:21 -starttls ftp
      CONNECTED(00000003)
      depth=1 /CN=castaglia3-serverCA/C=US/emailAddress=tj@castaglia.org/O=Castaglia/OU=Castaglia Research and Development/OU=TJ Saunders/ST=Washington
      verify error:num=20:unable to get local issuer certificate
      verify return:0
      ---
      Certificate chain
       0 s:/CN=castaglia3-server/C=US/emailAddress=tj@castaglia.org/O=Castaglia/OU=Castaglia Research and Development/OU=TJ Saunders/ST=Washington
         i:/CN=castaglia3-serverCA/C=US/emailAddress=tj@castaglia.org/O=Castaglia/OU=Castaglia Research and Development/OU=TJ Saunders/ST=Washington
       1 s:/CN=castaglia3-serverCA/C=US/emailAddress=tj@castaglia.org/O=Castaglia/OU=Castaglia Research and Development/OU=TJ Saunders/ST=Washington
         i:/CN=castaglia3/C=US/ST=Washington/L=Seattle/O=Castaglia/OU=Castaglia Research and Development/OU=TJ Saunders/emailAddress=tj@castaglia.org
      ---
      Server certificate
      -----BEGIN CERTIFICATE-----
      ...
      -----END CERTIFICATE-----
      subject=/CN=castaglia3-server/C=US/emailAddress=tj@castaglia.org/O=Castaglia/OU=Castaglia Research and Development/OU=TJ Saunders/ST=Washington
      issuer=/CN=castaglia3-serverCA/C=US/emailAddress=tj@castaglia.org/O=Castaglia/OU=Castaglia Research and Development/OU=TJ Saunders/ST=Washington
      ---
      Acceptable client certificate CA names
      /CN=castaglia3-clientCA/C=US/emailAddress=tj@castaglia.org/O=Castaglia/OU=Castaglia Research and Development/OU=TJ Saunders/ST=Washington
      /CN=castaglia3/C=US/ST=Washington/L=Seattle/O=Castaglia/OU=Castaglia Research and Development/OU=TJ Saunders/emailAddress=tj@castaglia.org
      /CN=castaglia3-clientCA/C=US/emailAddress=tj@castaglia.org/O=Castaglia/OU=Castaglia Research and Development/OU=TJ Saunders/ST=Washington
      /CN=castaglia3/C=US/ST=Washington/L=Seattle/O=Castaglia/OU=Castaglia Research and Development/OU=TJ Saunders/emailAddress=tj@castaglia.org
      ---
      SSL handshake has read 3731 bytes and written 344 bytes
      ---
      New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
      Server public key is 1024 bit
      Compression: NONE
      Expansion: NONE
      SSL-Session:
          Protocol  : TLSv1
          Cipher    : DHE-RSA-AES256-SHA
          Session-ID: D1F2E7C001BCFE57D797F34BD1518BDCC6160106D56A238CC0F957337C093435
          Session-ID-ctx: 
          Master-Key: F8EE2812270E8FCD87D1B26F20546EF9BABAE40F36BC6F8DF45B0E2F089571E731EAFAEA5E61BCA7D9D204BE06F28B21
          Key-Arg   : None
          Start Time: 1232997620
          Timeout   : 300 (sec)
          Verify return code: 20 (unable to get local issuer certificate)
      ---
      220 ProFTPD 1.3.2rc4 Server (TJ's FTPS Server) [127.0.0.1]
      quit
      221 Goodbye.
      read:errno=0
    
    Note that the "verify error" message is not of particular concern for us, since we are not using s_client to verify the server's certificate in this example.

    The parts of the s_client output which are of particular interest are the highlighted "Certificate chain" and "Acceptable client certificate CA names" sections.

    The "Certificate chain" section shows the certificate chain/trust path, from the server's certificate up through the root CA for that certificate. Note that this assumes the certificates in the trust path are available on the server. By default, OpenSSL constructs this certificate chain using the server's certificate (configured using TLSRSACertificateFile or TLSDSACertificateFile) and the trusted CA certificates configured using TLSCACertificateFile and/or TLSCACertificatePath. See the TLSCertificateChainFile FAQ for more details on how to influence the constructed certificate chain.

    The "Acceptable client certificate CA names" section contains the list of CAs that can issue certificates that mod_tls is willing to trust. These CAs always come from the configured TLSCACertificateFile and/or TLSCACertificatePath. This list of acceptable client CAs is presented to the client whenever the server is requesting the client's certificate (which is what mod_tls does by default). If you use:

      TLSOptions NoCertRequest
    
    then the server will not send this list of acceptable client CAs; using s_client in that case, you would see:
      ---
      No client certificate CA names sent
      ---
    
    In case you're wondering, a list of CAs is sent to the client, rather than just a single CA, because this allows clients the ability to determine which certificate (as a client can have many) to use when talking to this particular server.

    Another tool, slightly older, is ssldump. This tool is more like ethereal or tcpdump for any SSL/TLS traffic; it is deliberately modeled after tcpdump.

    To use ssldump for watching your FTPS traffic, you will need the server key file (for decrypting), and possibly root privileges (for listening on the network interface). Here is an example where ssldump is used to listen on the loopback interface (lo0), port 21:

      # sudo ssldump -d -k server.pem -i lo0 port 21
      New TCP connection #1: localhost(64148) <-> localhost(21)
      0.0423 (0.0423)  S>C
      ---------------------------------------------------------------
      220 ProFTPD 1.3.2rc4 Server (TJ's FTPS Server) [127.0.0.1]
      ---------------------------------------------------------------
    
      0.0427 (0.0004)  C>S
      ---------------------------------------------------------------
      AUTH TLS
      ---------------------------------------------------------------
    
      0.0430 (0.0002)  S>C
      ---------------------------------------------------------------
      234 AUTH TLS successful
      ---------------------------------------------------------------
    
      1 1  0.0433 (0.0003)  C>S SSLv2 compatible client hello
        Version 3.1 
        cipher suites
        Unknown value 0x39  
        Unknown value 0x38  
        Unknown value 0x35  
        TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA  
        TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA  
        TLS_RSA_WITH_3DES_EDE_CBC_SHA  
        SSL2_CK_3DES  
        Unknown value 0x33  
        Unknown value 0x32  
        Unknown value 0x2f  
        TLS_RSA_WITH_IDEA_CBC_SHA  
        SSL2_CK_IDEA  
        SSL2_CK_RC2  
        TLS_RSA_WITH_RC4_128_SHA  
        TLS_RSA_WITH_RC4_128_MD5  
        SSL2_CK_RC4  
        TLS_DHE_RSA_WITH_DES_CBC_SHA  
        TLS_DHE_DSS_WITH_DES_CBC_SHA  
        TLS_RSA_WITH_DES_CBC_SHA  
        SSL2_CK_DES  
        TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA  
        TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA  
        TLS_RSA_EXPORT_WITH_DES40_CBC_SHA  
        TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5  
        SSL2_CK_RC2_EXPORT40  
        TLS_RSA_EXPORT_WITH_RC4_40_MD5  
        SSL2_CK_RC4_EXPORT40  
      1 2  0.0658 (0.0225)  S>C  Handshake
            ServerHello
              Version 3.1 
              session_id[32]=
                09 25 df 7a a8 e8 71 a2 9f 56 a6 7b dd 95 ac 67 
                7d 2e 81 b2 1c ca b4 5f 1e 95 13 47 01 28 20 19 
              cipherSuite         Unknown value 0x39
              compressionMethod                   NULL
      1 3  0.0658 (0.0000)  S>C  Handshake
            Certificate
      1 4  0.0658 (0.0000)  S>C  Handshake
            ServerKeyExchange
      1 5  0.0658 (0.0000)  S>C  Handshake
            CertificateRequest
              certificate_types                   rsa_fixed_dh
              certificate_types                   dss_fixed_dh
              certificate_types                   rsa_sign
              certificate_types                   dss_sign
              certificate_authority
                30 81 b8 31 1c 30 1a 06 03 55 04 03 13 13 63 61 
                73 74 61 67 6c 69 61 33 2d 63 6c 69 65 6e 74 43 
                41 31 0b 30 09 06 03 55 04 06 13 02 55 53 31 1f 
                30 1d 06 09 2a 86 48 86 f7 0d 01 09 01 16 10 74 
                6a 40 63 61 73 74 61 67 6c 69 61 2e 6f 72 67 31 
                12 30 10 06 03 55 04 0a 13 09 43 61 73 74 61 67 
                6c 69 61 31 2b 30 29 06 03 55 04 0b 13 22 43 61 
                73 74 61 67 6c 69 61 20 52 65 73 65 61 72 63 68 
                20 61 6e 64 20 44 65 76 65 6c 6f 70 6d 65 6e 74 
                31 14 30 12 06 03 55 04 0b 13 0b 54 4a 20 53 61 
                75 6e 64 65 72 73 31 13 30 11 06 03 55 04 08 13 
                0a 57 61 73 68 69 6e 67 74 6f 6e 
              certificate_authority
                30 81 c1 31 13 30 11 06 03 55 04 03 13 0a 63 61 
                73 74 61 67 6c 69 61 33 31 0b 30 09 06 03 55 04 
                06 13 02 55 53 31 13 30 11 06 03 55 04 08 13 0a 
                57 61 73 68 69 6e 67 74 6f 6e 31 10 30 0e 06 03 
                55 04 07 13 07 53 65 61 74 74 6c 65 31 12 30 10 
                06 03 55 04 0a 13 09 43 61 73 74 61 67 6c 69 61 
                31 2b 30 29 06 03 55 04 0b 13 22 43 61 73 74 61 
                67 6c 69 61 20 52 65 73 65 61 72 63 68 20 61 6e 
                64 20 44 65 76 65 6c 6f 70 6d 65 6e 74 31 14 30 
                12 06 03 55 04 0b 13 0b 54 4a 20 53 61 75 6e 64 
                65 72 73 31 1f 30 1d 06 09 2a 86 48 86 f7 0d 01 
                09 01 16 10 74 6a 40 63 61 73 74 61 67 6c 69 61 
                2e 6f 72 67 
              certificate_authority
                30 81 b8 31 1c 30 1a 06 03 55 04 03 13 13 63 61 
                73 74 61 67 6c 69 61 33 2d 63 6c 69 65 6e 74 43 
                41 31 0b 30 09 06 03 55 04 06 13 02 55 53 31 1f 
                30 1d 06 09 2a 86 48 86 f7 0d 01 09 01 16 10 74 
                6a 40 63 61 73 74 61 67 6c 69 61 2e 6f 72 67 31 
                12 30 10 06 03 55 04 0a 13 09 43 61 73 74 61 67 
                6c 69 61 31 2b 30 29 06 03 55 04 0b 13 22 43 61 
                73 74 61 67 6c 69 61 20 52 65 73 65 61 72 63 68 
                20 61 6e 64 20 44 65 76 65 6c 6f 70 6d 65 6e 74 
                31 14 30 12 06 03 55 04 0b 13 0b 54 4a 20 53 61 
                75 6e 64 65 72 73 31 13 30 11 06 03 55 04 08 13 
                0a 57 61 73 68 69 6e 67 74 6f 6e 
              certificate_authority
                30 81 c1 31 13 30 11 06 03 55 04 03 13 0a 63 61 
                73 74 61 67 6c 69 61 33 31 0b 30 09 06 03 55 04 
                06 13 02 55 53 31 13 30 11 06 03 55 04 08 13 0a 
                57 61 73 68 69 6e 67 74 6f 6e 31 10 30 0e 06 03 
                55 04 07 13 07 53 65 61 74 74 6c 65 31 12 30 10 
                06 03 55 04 0a 13 09 43 61 73 74 61 67 6c 69 61 
                31 2b 30 29 06 03 55 04 0b 13 22 43 61 73 74 61 
                67 6c 69 61 20 52 65 73 65 61 72 63 68 20 61 6e 
                64 20 44 65 76 65 6c 6f 70 6d 65 6e 74 31 14 30 
                12 06 03 55 04 0b 13 0b 54 4a 20 53 61 75 6e 64 
                65 72 73 31 1f 30 1d 06 09 2a 86 48 86 f7 0d 01 
                09 01 16 10 74 6a 40 63 61 73 74 61 67 6c 69 61 
                2e 6f 72 67 
            ServerHelloDone
      1 6  0.1005 (0.0346)  C>S  Handshake
            Certificate
      1 7  0.1005 (0.0000)  C>S  Handshake
            ClientKeyExchange
      1 8  0.1005 (0.0000)  C>S  ChangeCipherSpec
      1 9  0.1005 (0.0000)  C>S  Handshake
      1 10 0.1164 (0.0159)  S>C  ChangeCipherSpec
      1 11 0.1164 (0.0000)  S>C  Handshake
      1 12 1.7856 (1.6692)  C>S  application_data
      1 13 1.7856 (0.0000)  C>S  application_data
      1 14 1.7861 (0.0004)  S>C  application_data
      1    1.7866 (0.0004)  S>C  TCP FIN
      1 15 1.7868 (0.0002)  C>S  Alert
    

    As you can see, the level of granularity used by ssldump is on the level of each SSL/TLS packet; while useful in some cases, I suspect that using openssl s_client will provide most of the information you will want in figuring out your certificate and verification issues.

    TLS Client Auth/Mutual Auth
    Like most web servers, when mod_tls is used, it does not require that the connecting client present a certificate for verification by default. That is, mod_tls does not require "client auth" or "mutual auth" by default. To require that clients present a valid certificate, you would use the TLSVerifyClient directive like so:

      <IfModule mod_tls.c>
        TLSEngine on
        ...
        # Verify clients that want to use FTP over TLS
        TLSVerifyClient on
      </IfModule>
    

    With this directive enabled in your configuration, if a client connects and performs the SSL/TLS handshake but does not present a valid certificate, then the TLSLog would contain error messages like this:

      mod_tls/2.4.3[12065]: TLS/TLS-C requested, starting TLS handshake
      mod_tls/2.4.3[12065]: unable to accept TLS connection: protocol error: 
        (1) error:140890C7:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:peer did not return a certificate
      mod_tls/2.4.3[12065]: TLS/TLS-C negotiation failed on control channel
    
    The client failed to provide a valid certificate, and so the connection was rejected.

    Frequently Asked Questions

    Question: When I enable mod_tls, I can't upload or download files, or list directories. I see the following error in my client:

      425 Unable to build data connection: Operation not permitted.
    
    Why?
    Answer: By default, mod_tls requires that the same SSL session be used data transfers (see
    TLSOptions), which includes uploads, downloads, and directory listings. If your data transfers are failing, you might look in your TLSLog, and see a log message like this:
      client did not reuse SSL session, rejecting data connection (see the NoSessionReuseRequired TLSOptions parameter)
    
    The workaround, then, is to add the TLSOption mentioned in the log message to your configuration, i.e.:
      # Relax the requirement that the SSL session be reused for data transfers
      TLSOptions NoSessionReuseRequired
    
    Then restart proftpd, and your data transfers should work.

    Question: How do I generate the certificate files used by mod_tls?
    Answer: The mod_tls module uses the same certificate files as Apache's mod_ssl. The mod_ssl documentation explains what the files are, how they are used, and how to generate your own:

      http://www.modssl.org/docs/2.7/ssl_faq.html
    

    Question: Does FTPS protect both the control connection and the data connections?
    Question: Short answer: yes.

    The long answer is, of course, that it depends. In the case of mod_tls, it depends on your TLSRequired setting. If you use:

      TLSRequired on
    
    then you are configuring mod_tls to require SSL/TLS protection for both control connections (e.g. protecting the username and password used to log in) and data connections. If you have:
      TLSRequired off
    
    then it is up to the FTPS client whether both control and data connections will be protected via SSL/TLS. Other TLSRequired settings can be used to specify specific combinations: data connections only, control connections only, authentication plus data data connections only, etc. The TLSRequired
    documentation has the details.

    Question: Where can I find a list of clients that support FTPS?
    Answer: This page is a good FTPS resource:

      http://www.ford-hutchinson.com/~fh-1-pfh/ftps-ext.html
    
    including the list of FTPS clients. On a related note, there have been some reports that Debian's ftp-ssl client has a few bugs; using Peter Runestig's ftp-tls is known to work.

    Note, though, that there are known issues with some FTPS clients:

      http://www.runestig.com/osp.html#NOTE1
    

    Question: How come mod_tls does not support "implicit" FTPS (i.e. automatically encrypting sessions on port 990)?
    Answer: The short answer is because the Draft no longer specifies support for such a mode. Here is a
    description of why the alternatives to the current mode (client-requested encryption using standard control channel) are "bad".

    The long answer is covered in Eric Rescorla's excellent book, "SSL and TLS". There tend to be two different strategies used when adding new features to a protocol: separate ports for protocol variants, or upward negotiation. Port 443 for HTTPS is an example of the separate ports strategy. The drawback to the separate ports approach is that there is a finite number of ports available, and so this approach does not scale well. The benefit is that use of separate ports tends to require smaller changes to client and server code. Upward negotiation is more flexible, but requires that the protocol support some sort of feature negotiation or extension discovery, allowing clients and servers to easily agree to negotiate "upward" into a secure channel. The authors of the FTPS Draft felt that upward negotiation was the more appropriate of these two approaches for encrypting FTP channels.

    All that said, in ProFTPD 1.3.3rc2, the mod_tls module was enhanced to support implicit FTPS via the UseImplicitSSL TLSOption.

    Question: Can I require TLS on a per-user basis?
    Answer: Prior to ProFTPD 1.2.10rc2, no. The IETF Draft specifying FTP over TLS requires that the TLS handshake occur before the client sends the USER command. This means that the server does not know the name of the user that the client will be using when the TLS session is established. It is possible that the client's certificate, if one is even presented, may contain information the server may use to map that certificate to a user, but such mapping is not currently supported by mod_tls. Note that this is also the reason the TLSRequired directive cannot appear in the <Anonymous> context: anonymous logins are based on the USER command.

    However, in 1.2.10rc2, the mod_tls module was modified to allow such per-user TLS requirements. To do this, the AllowPerUser parameter of the TLSOptions directive is used. For example, the following example mod_tls configuration allows non-SSL anonymous sessions, but requires SSL/TLS for all other sessions:

      <IfModule mod_tls.c>
        TLSEngine on
        TLSRSACertificateFile ...
        TLSCACertificateFile ...
        TLSOptions AllowPerUser
        TLSRequired on
    
        <Anonymous ~ftp>
          User ftp
          Group ftp
          UserAlias anonymous ftp
    
          RequireValidShell off
    
          # Note how TLSRequired is set to off here in the <Anonymous> context
          TLSRequired off
        </Anonymous>
      </IfModule>
    
    The modification also allows mod_ifsession-based conditions, so that one can have settings like:
      <IfGroup trusted>
        TLSRequired off
      </IfGroup>
    
    However, there is a risk involved in using the AllowPerUser option: it causes mod_tls not to enforce TLSRequired until after the potentially sensitive USER and PASS commands have been sent by the client. This allows clients, even when TLSRequired on or TLSRequired ctrl are in effect, to send the USER and PASS commands unencrypted. Depending on your site's security needs, the ability to require SSL/TLS on a per-user basis may or may not be worth the ability to require SSL/TLS for the USER and PASS commands.

    Question: When I use the following in my proftpd.conf:

      TLSRequired on # or "TLSRequired auth", or "TLSRequired auth+data"
      TLSOptions AllowPerUser
    
    I get the following error when I try to start proftpd:
      cannot enforce both 'TLSRequired auth' and 'TLSOptions AllowPerUser' at the same time
    
    Answer: The reason this error occurs is because you have a configuration which is impossible to support. The TLSRequired setting (e.g. "on", "auth", or "auth+data") requires that SSL/TLS be in use during authentication. But in order to support the TLSOption AllowPerUser setting, the mod_tls cannot require that SSL/TLS be in use during authentication, since it does not know the user until after authentication has completed. The requested configuration cannot be supported, and thus the server will refuse to start.

    Question: Why does mod_tls break FXP transfers?
    Answer: The Draft specifying FTP over SSL explicitly omits site-to-site transfers. A TLS session is established between the client and the server on the control channel and, to save on the expensive overhead of TLS handshake, that session is reused for encrypting traffic on the data channel. In a site-to-site transfer, the client opens two control channels, one with each server, and then arranges for those servers to open a data channel between themselves. However, since the servers have not established a TLS session between themselves, that opening of the data channel fails.

    Note that the above happens only if the server requires that TLS be used on data connections (e.g. TLSRequired is either on or data), of if the client tells the server that the client will be using TLS on the data connections (e.g. when it sends the AUTH command with an argument of TLS-P). Without these conditions, site-to-site transfers can occur normally, albeit unencrypted. Encrypted site-to-site transfers are not supported.

    Question: How come mod_tls does not support SSLv2?
    Answer: Various defects have been found in the SSLv2 protocol. Some legacy sites need to support SSLv2 for their HTTP traffic, in spite of its flaws. Use of FTP over TLS is fairly new, however, and there is not much "legacy" in that regard; it was felt that, as mod_tls aims to provide strong cryptographic security, supporting a known bad protocol is a Bad Idea.

    Question: Using mod_tls, FTP sessions through my firewall now no longer work. What's going on?
    Answer: The short answer is that FTPS and firewalls (and devices performing NAT) do not interact well. The control connection happens on a well-known port, and has no issues; it is the data connection that poses problems for FTP-aware firewalls. In a non-FTPS session, the firewall can inspect the FTP server's responses on the control connection to a client's PASV or PORT command, and thus know which on which ports/addresses the data connection will be established. In an FTPS session, though, those control connection messages are encrypted (that is the point of using FTPS, right?), and so the FTP-aware firewall cannot peek. Hence, it cannot know which on which ports the data connection will be established. For firewalls that are configured to always allow a certain range of ports (such as might be configured using the PassivePorts directive), FTPS should function without issue.

    Unfortunately, this is a rather intractable--and known--issue. Earlier versions of the Draft defining FTPS used to allow something known as "implicit" FTPS, by which a client could contact a well-known port (akin to port 443 for HTTPS; FTPS used port 990) and the server, simply because the client contacted that certain port, would automatically encrypt the session. This approach has several drawbacks (the reason why it was removed from later versions of the Draft), but it did allow for simple TCP proxying.

    To attempt to deal with the above issue, the RFC for FTP over SSL/TLS suggests using the CCC FTP command (Clear Command Channel). The CCC command makes an encrypted control channel revert back to an unencrypted channel. This helps to solve data connection problems in situations where network equipment (such as firewalls, routers, NAT) peek at the control channel in order to open ports. By sending the CCC command and unecrypting the control channel, the network equipment can once again peek at the commands (i.e. PORT and EPRT) in the control channel. Since the CCC command must come after the client has logged in, the USER and PASS commands on the control channel will still be protected by SSL/TLS.

    Note that in order to configure the mod_tls module to allow use of the CCC command by clients, the following must appear in your proftpd.conf:

      TLSRequired auth+data
    
    See the TLSRequired description for more details.

    Question: Sometimes my encrypted transfers are slow. Is there a way to speed them up?
    Answer: There have been reports that increasing the tunable buffer size (using the --enable-buffer-size option of the configure script) to 8192 increases transfer speeds, most notably on very high speed networks. Increasing the buffer size does not appear to affect normal FTP transfers (in fact, it may benefit them as well, depending on the client).

    Question: I can login using FTPS, but I cannot see any directories. Why not?
    Answer: You have most likely configured mod_tls to require SSL/TLS protection for data transfers as well as control commands, by using:

      TLSRequired on
    
    However, if your FTPS client does not expect to handle encrypted data transfers (and directory listings count as data transfers, as they are sent over a data channel), you may see your client appear to hang, waiting for data it can read. Make sure your client is prepared to handle the security requirements you have configured on the server.

    The following may also appear in the TLS for any data transfers (which include directory listings):

      client did not reuse SSL session, rejecting data connection (see the NoSessionReuseRequired TLSOptions parameter
    
    This message appears because an additional security restriction that was added in ProFTPD 1.3.3rc1. The
    TLSOptions documentation for this "NoSessionReuseRequired" option describes the situation in more detail.

    You may also see the following appear in the TLSLog on occasion:

      PROT: unwilling to accept security parameter (C), declining
    
    The PROT FTP command is used to set the protection level to be used for data transfers. Some clients send a PROT command with a security parameter of C, meaning "Clear", which effectively tells the server not to protect data transfers. The mod_tls module will refuse the C security parameter if, like above, there is "TLSRequired on" in your proftpd.conf. This case also indicates a disagreement between the client's security expectations and the security policy you have configured on the server.

    In order to accept a "PROT C" FTP command, your mod_tls configuration would need to use a TLSRequired value other than required, e.g. something like:

      # We only require SSL/TLS protection during authentication
      TLSRequired auth
    
      # We will accept SSL/TLS protection for the control channel if the
      # client wants to use it, but NOT for data transfers
      TLSRequired !data
    

    Question: Using FTPS, after uploading a very large file, my next directory listing fails:

      425 Unable to build data connection: Operation not permitted
    
    The TLSLog contains:
      client did not reuse SSL session, rejecting data connection (see the NoSessionReuseRequired TLSOptions parameter
    
    but I do not want to use that option, and would like to rely on the additional security protection provided by requring SSL session reuse. And my FTPS client is correctly reusing SSL session IDs (as earlier data transfers were working properly). So why is my data transfer failing after the upload of a very large file?
    Answer: The answer involves SSL session caching on the server side (i.e. mod_tls), cache timeouts, and session renegotiations.

    By default, mod_tls uses OpenSSL's "internal" session cache, which is an in-memory caching of SSL session IDs. And by default, OpenSSL's internal session cache has a cache timeout of 5 minutes; after that amount of time in the internal session cache, a cached SSL session ID is considered stale and is available for reuse.

    This means that 5 minutes or more into an FTPS session, even if your FTPS client reused an SSL session ID, the OpenSSL internal session cache will time out that SSL session ID. The next time your FTPS client goes to reuse that session ID for a data transfer, mod_tls won't find it in the OpenSSL internal session cache, and will think that your FTPS client is not reusing the SSL session ID as is required, and fail the transfer.

    Fixing this situation requires two parts: a) the ability to change the cache timeout used for the OpenSSL internal session cache, and b) renegotiating the SSL session ID with the FTPS client periodically, to keep the SSL session ID up-to-date in the session cache.

    The first part, configuring the session cache timeout for the OpenSSL internal session cache, is only possible in ProFTPD 1.3.4rc2 and later (see Bug#3580). The TLSSessionCache directive was modified to allow a configuration such as:

      TLSSessionCache internal: 1800
    
    (Unfortunately, the ':' after "internal" is necessary.) This configures mod_tls such that the OpenSSL internal session cache uses a cache timeout of 1800 seconds (30 minutes), rather than the default of 300 seconds (5 minutes).

    No matter how long you configure the cache timeout, eventually you will have a session which lasts longer than that timeout. Which brings us to the second part of the solution: renegotiating a new SSL session ID periodically, which keeps it fresh in the session cache. The TLSRenegotiate directive is needed for this. For example, the following configuration should address the issue of failed data transfers after very large uploads:

      TLSRenegotiate ctrl 1500 timeout 300
      TLSSessionCache internal: 1800
    
    This tells mod_tls to request a renegotiation of the SSL session on the control channel every 1500 seconds (25 minutes), and to allow 300 seconds (5 minutes) for the client to perform the renegotiation. It also tells mod_tls to cache the SSL session data for 1800 seconds (30 minutes), i.e. longer than the renegotiation time of 1500 seconds.

    This way, as long as your client supports renegotiations and is updating the SSL session ID properly for data transfers, when a data transfer is requested, the SSL session ID presented by the client should always be fresh and in the session cache.

    Question: Why would I see the following errors while attempting to build proftpd with mod_tls?

      /usr/local/ssl/lib/libcrypto.a(dso_dlfcn.o)(.text+0x35): In function `dlfcn_load': : undefined reference to `dlopen'
      /usr/local/ssl/lib/libcrypto.a(dso_dlfcn.o)(.text+0x95): In function `dlfcn_load': : undefined reference to `dlclose'
      /usr/local/ssl/lib/libcrypto.a(dso_dlfcn.o)(.text+0xbc): In function `dlfcn_load': : undefined reference to `dlerror'
      /usr/local/ssl/lib/libcrypto.a(dso_dlfcn.o)(.text+0x147): In function `dlfcn_bind_var': : undefined reference to `dlsym'
      /usr/local/ssl/lib/libcrypto.a(dso_dlfcn.o)(.text+0x172): In function `dlfcn_bind_var': : undefined reference to `dlerror'
      /usr/local/ssl/lib/libcrypto.a(dso_dlfcn.o)(.text+0x237): In function `dlfcn_bind_func': : undefined reference to `dlsym'
      /usr/local/ssl/lib/libcrypto.a(dso_dlfcn.o)(.text+0x262): In function `dlfcn_bind_func': : undefined reference to `dlerror'
      /usr/local/ssl/lib/libcrypto.a(dso_dlfcn.o)(.text+0x50b): In function `dlfcn_unload': : undefined reference to `dlclose'
      collect2: ld returned 1 exit status
      make: *** [proftpd] Error 1
    
    Answer: Add -ldl to your configure command, for example:
      make clean
      ./configure LDFLAGS=-ldl ...
      make
    
    This tells the proftpd build system to add libdl, an OS-specific library for handling dynamically loaded code, to the list of libraries used when linking proftpd. On some systems, the functions in the libdl library are part of libc, and are not in a separate library.

    I suspect that the reason this build option may be necessary is that OpenSSL 0.9.8 contained changes regarding how OpenSSL loads "engines", software modules that talk to hardware devices that can do specialized cryptographic operations. These changes involve being able to dynamically load the "engine" software modules.

    Question: Why would I see a "no shared cipher" error in the TLSLog when attempting to connect with my FTPS client?

      Jan 10 17:15:18 mod_tls/2.1.1[2212]: TLS/TLS-C requested, starting TLS handshake
      Jan 10 17:15:18 mod_tls/2.1.1[2212]: unable to accept TLS connection:
        (1) error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher
      Jan 10 17:15:18 mod_tls/2.1.1[2212]: TLS/TLS-C negotiation failed on control channel
    
    Answer: There are two reasons this might happen.

    The first is that there is indeed no ciphersuite in common between mod_tls and your FTPS client. The SSL/TLS ciphersuites used by mod_tls are configured using the TLSCipherSuite directive. If you have a complex or restrictive TLSCipherSuite configured, that could be the culprit. Try relaxing (or removing outright) your TLSCipherSuite, or try to configure your FTPS client to use the same SSL/TLS ciphersuites.

    Another possibility is a misconfiguration. If your TLSCACertificateFile and TLSRSACertificateFile directives are in the "server config" context of the proftpd.conf file, and you have <VirtualHost> sections in your proftpd.conf, then you might see the "no shared cipher" error. The easiest thing is to move those TLSCACertificateFile and TLSRSACertificateFile directives into a <Global> section in your proftpd.conf, so that they apply to all vhosts configured. The virtual hosting howto describes this in more detail.

    Question: My FTPS client sometimes times out after uploading/downloading more than 1 GB of data. When I turn off SSL/TLS, the upload/download works. Why?
    Answer: The culprit behind this is most likely SSL/TLS renegotiations. By default, mod_tls uses SSL/TLS renegotiations to periodically update the session key which protects the data being transferred; see the
    TLSRenegotiate documentation for more details, particularly the time-based and bytes-based limits at which renegotations are forced.

    Some FTPS clients, however, do not support server-initiated SSL/TLS renegotations. When the server does try to force a renegotiation, the client fails that new handshake, cannot upload/download any more data over the protected channel, and the transfer will eventually time out. Alternatively, the transfer could terminate strangely in the middle of the upload/download. Note, however, that not all transfer issues will be caused by SSL/TLS renegotiations. Bugs in firewalls and routers can also cause these symptoms.

    Should you suspect that you are having issues with your FTPS client because of SSL/TLS renegotiations, you can configure mod_tls to accept renegotiations if the client requests one, but not to otherwise force them:

      TLSRenegotiate required off
    

    Question: My FTPS client has trouble connecting to proftpd using SSL/TLS, with the following error appearing in the TLSLog:

      Sep 17 11:03:46 mod_tls/2.1.2[9628]: TLS/TLS-C requested, starting TLS handshake
      Sep 17 11:03:46 mod_tls/2.1.2[9628]: unable to accept TLS connection: received EOF that violates protocol
      Sep 17 11:03:46 mod_tls/2.1.2[9628]: TLS/TLS-C negotiation failed on control channel
    
    Is this a bug in mod_tls, in the client, or something else?

    Answer: There might be several different causes for this error. It could be a bug in the OpenSSL library, in mod_tls, in the FTPS client, or it could be a transient network issue.

    Now, one possible thing to try is to use the following in your proftpd.conf file:

      TLSOptions NoCertRequest
    
    This option tells the OpenSSL library to not include a message requesting the client's certificate in the SSL/TLS handshake messages. Some older SSL implementations seem to have trouble with this certificate request message, and react badly. This includes some Windows FTP clients, as well as some FTP clients for the Mac.

    One user tried using both the Transmit and the Fetch applications for the Mac; both state that they can handle FTP over SSL/TLS. Using both of these applications, the user saw the above error. The user, when using Transmit, saw the following error message appear from the client:

      Server said:
      AUTH TLS successful
      error:00000000:lib(0):func(0):reason(0)
    
    And when using Fetch, the error message displayed by that client was:
     
      SSL Error -9844
      Server responded: "AUTH TLS successful"
    
    In both causes, using "TLSOptions NoCertRequest" appeared to make those clients happy.

    Question: When proftpd starts up, I am prompted to enter the passphrases for my certificates. How can I get the daemon to start without having to enter passphrases?
    Answer: You can either remove the passphrase from the certificate key file (as mentioned in the Apache mod_ssl
    FAQ), or you can use the TLSPassPhraseProvider directive to configure a program will which provide the passphrases to proftpd automatically.

    Question: How can I configure mod_tls to use OpenSSL in FIPS mode?
    Answer: Using OpenSSL in FIPS mode requires quite a few steps. First, you would configure proftpd to use the mod_tls module as normal, assuming your OpenSSL installation has been compiled with FIPS support:

      ./configure --with-modules=mod_tls ...
    

    Compiling proftpd requires the following, for FIPS support to work properly:

      make CC=/path/to/openssl/bin/fipsld FIPSLD_CC=gcc
    
    The FIPSLD_CC variable should point to your normal C compiler, e.g. gcc. The use of this fipsld program is mandatory. The FIPS standard requires that the linking process happen a very specific way, involving verification of calculated and expected checksums of compiled code, etc. The OpenSSL packages with FIPS support supply this fipsld program which will link the compiled code according to the FIPS specifications. If you do not use fipsld, then attempts to use OpenSSL in FIPS mode will fail. For example, you would see the following if starting a proftpd daemon which has not been linked using fipsld while requesting use of FIPS:
      - mod_tls/2.1.2: unable to use FIPS mode: (unknown)
      - Fatal: unable to load module 'mod_tls.c': Operation not permitted
    

    Now, assuming you have compiled and installed your proftpd properly, e.g.:

      make CC=/path/to/openssl/bin/fipsld FIPSLD_CC=gcc
      make CC=/path/to/openssl/bin/fipsld FIPSLD_CC=gcc install
    
    you will now be ready to start proftpd.

    In order for FIPS mode to be effective, OpenSSL must be told to run in FIPS mode from the very beginning. The mod_tls module initializes the OpenSSL library when the mod_tls module is loaded, before the proftpd.conf file is parsed. Thus the requesting of FIPS mode cannot be done via a setting in proftpd.conf. (Annoying, I know.)

    Instead, you must use the -D command-line parameter when starting proftpd (see the docs for the <IfDefine> and Define directives) to define a specific variable, which the mod_tls module will look for. Specifically, you will need to start proftpd like thus:

      /path/to/proftpd -DTLS_USE_FIPS ...
    
    This will define the TLS_USE_FIPS variable; this tells mod_tls to initialize OpenSSL using FIPS mode. When this works, you will see the following when proftpd starts up:
      - mod_tls/2.1.2: FIPS mode enabled
    

    For additional reading on OpenSSL and FIPS, see:

      http://www.openssl.org/docs/fips/SecurityPolicy-1.1.1.pdf
      http://www.openssl.org/docs/fips/UserGuide-1.1.1.pdf
    

    Question: Why do I see the following in my logs when I start proftpd using mod_tls?

     - mod_tls/2.2: compiled using OpenSSL version 'OpenSSL 0.9.7i 14 Oct 2005'
    headers, but linked to OpenSSL version 'OpenSSL 0.9.7l 28 Sep 2006' library
    
    What does this mean?
    Answer: That is an informational/warning message.

    Some systems are badly maintained by their admins (and/or by the packages installed on the systems), such that the OpenSSL headers can become quite badly out of sync with the OpenSSL libraries. If this discrepancy becomes bad enough, you can see strange behavior from OpenSSL, ranging from random behavior to segfaults. So mod_tls tries to let the admin know about the system's mismatched OpenSSL header/library versions.

    Usually a minor OpenSSL version difference like the example above is OK, but it really depends on exactly what changed in OpenSSL, and how.

    If you see the above message, it is not a requirement that you recompile proftpd against the OpenSSL headers of the same version as the OpenSSL libraries. However, the version discrepancy is a possible source of trouble.

    This header/library version check was added recently, hence why older proftpd releases do not log the warning.

    Question: When should the TLSCertificateChainFile directive be used?
    Answer: Short answer: only in very specific arrangements of CA hierarchies. Most of the time, you probably do not need it.

    The long explanation requires an illustration. Let's say we have a CA hierarchy that looks something like this:

           MyRootCA                      TheirRootCA
               |                             |
          MyServerCA                    TheirClientCA
               |                             |
        +------+------+               +------+------+
        |      |      |               |      |      |
      certA  certB  certC           cert1  cert2  cert3
    

    Another way of asking the question thus is: "How to I send MyServerCA and MyRootCA to the client without having them in my trusted CA locations"?

    We might configure mod_tls to have "certA" as the server's certificate, via TLSRSACertificateFile. The "certA" certificate is issued by MyServerCA. And let's assume that we do not want to verify any client certificates issued by MyServerCA.

    We do want to be able to verify client certs issued by a different CA, say, TheirClientCA. We configure TheirClientCA in mod_tls using TLSCACertificateFile or TLSCACertificatePath.

    The client connects to mod_tls, and starts the SSL/TLS handshake. mod_tls sends its "certA" certificate, along with any certs that may be needed on the client for verifying the server's certificate. (This is what appears in the "Certificate chain" output from s_client; see SSL/TLS debugging above.) Perhaps the client does not have MyServerCA present in the client certificate store. So we need to tell mod_tls to send the MyServerCA and MyRootCA certs, along with "certA". We could place the MyServerCA and MyRootCA certs in TLSCACertificatePath, but then any client certs issued by MyServerCA would be trusted as well (and that's not what we want for this example).

    The solution here is to use TLSCertificateChainFile to supply the MyServerCA and MyRootCA certs, as part of the server cert chain. The configured TLSCertificateChainFile would contain the PEM-formatted MyServerCA and MyRootCA public certs. And although the TLSCertificateChainFile states that the certs contained in the file should be in certificate chain order, this is not strictly necessary; the OpenSSL library will adjust the ordering as appropriate.

    Question: I am having trouble connecting to my SSL/TLS-enabled proftpd; my FTPS client shows this error:

      error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure
    
    What is wrong?
    Answer: It depends; the first thing is to check your TLSLog to see what errors, if any, are logged by the mod_tls module. For example, you might see:
      Dec 14 10:47:58 mod_tls/2.4.1[13393]: unable to accept TLS connection: protocol error: 
        (1) error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher
    
    The most common causes of these problems are: a) overly restrictive TLSCipherSuite configuration, or b) missing server certificate (i.e. TLSRSACertificateFile, TLSDSACertificateFile, or TLSPKCS12File). The file configured for the server certificate might also be badly formatted, which would result in the same error.

    Question: Is there a way to require TLS (FTPS) for remote clients only, and allow simple FTP (without TLS) for local clients (i.e. for clients in networks which we will be able to define as "local")?
    Answer: Yes.

    To do this, you would use a combination of <Class> sections and mod_ifsession's <IfClass>, e.g.:

      <Class local>
        From ...
      </Class>
    
      <IfModule mod_tls.c>
        # Normal mod_tls configuration here
    
        <IfClass local>
          # Don't require FTPS from local clients
          TLSRequired off
        </IfClass>
    
        <IfClass !local>
          # Require FTPS from remote/non-local clients
          TLSRequired on
        </IfClass>
    
      </IfModule>
    

    Question: I have configured my proftpd server for FTPS. When I use FileZilla to try to connect to it, though, I see this error in the FileZilla logs:

      GnuTLS error -9: A TLS packet with unexpected length was received
    
    Is there a ProFTPD directive to fix this error?
    Answer: In most cases, the above client error indicates an error unrelated to SSL/TLS on your server. Check the proftpd debug logging, the SQLLogFile if you are using the mod_sql module, etc.


    Last Updated: $Date: 2013/03/12 01:45:23 $

    proftpd-dfsg-1.3.5~rc3/doc/howto/Testing.html0000644000175000017500000002150211565260342020761 0ustar frankiefrankie ProFTPD mini-HOWTO - Testing

    ProFTPD Testsuite


    The proftpd source code is accompanied by a testsuite, for testing various features and functionality. At present, the testsuite is divided into two main parts: the API-level tests, and the integration tests. The API tests are written in C, and exercise the various APIs that proftpd provides to module developers. The integration tests are currently written in Perl, and seek to check a compiled proftpd's run-time behavior.

    In order to run the testsuite, you must configure your proftpd build so that the testsuite is prepared. You do this by using the --enable-tests configure option, along with your other build options, e.g.:

      # ./configure --enable-tests ...
    

    API Tests
    The API tests use the libcheck library; see:

      http://check.sourceforge.net/
    
    This library must be installed on your machine in order to run the API tests. When the --enable-tests configure option is used, proftpd's configure script will check for libcheck, and will fail unless the library is present. If no libcheck is found and you've used --enable-tests, you will see:
        checking for tcase_create in -lcheck... no
        configure: error: libcheck support, required for tests, not present -- aborting
    
    Note that, if necessary, the --with-includes and --with-libraries configure options can be used to specify the locations of the libcheck headers and libraries.

    To run the testsuite, use the make check target:

      # ./configure --enable-tests ...
      # make
        ...
      # make check
        ...
      ./api-tests
      Running suite(s): pool
       array
       str
       sets
       timers
       table
       var
       event
       env
       version
       feat
       netaddr
       netacl
       class
       regexp
       expr
       scoreboard
       modules
      100%: Checks: 140, Failures: 0, Errors: 0
    
    The make check will also go on to run the integration tests, if the API tests all pass.

    If one of the API tests fails, you will see an error message like:

      99%: Checks: 140, Failures: 1, Errors: 0
      api/env.c:53:F:base:env_get_test:0: Failed to handle null arguments
      -------------------------------------------------
       FAILED 1 test
    
       Please send email to:
    
         proftp-devel@lists.sourceforge.net
    
       containing the `api-tests.log' file (in the tests/ directory)
       and the output from running `proftpd -V'
      -------------------------------------------------
    
    Please do follow those instructions; you will be helping in proftpd development!

    Expected Failures
    Unfortunately, due to variations in system configurations, it's possible that some of the API tests will fail, without it necessarily being an indication of a regression or problem.

    Most notably, some of the most brittle tests make assumptions about the host's /etc/hosts file, particularly the list of names associated with the address 127.0.0.1. If the /etc/hosts file has a name other than "localhost" or "localhost.localdomain" immediately after the 127.0.0.1 address, e.g.:

      127.0.0.1	some.other.name localhost
    
    Then the API tests may fail with errors like this:
      98%: Checks: 152, Failures: 2, Errors: 0
      api/netaddr.c:344:F:base:netaddr_get_dnsstr_test:0: Expected 'localhost or localhost.localdomain', got 'some.other.name'
      api/netacl.c:535:F:base:netacl_match_test:0: Failed to positively match ACL to addr: No such file or directory
    
    If this is the case, it is an expected failure; please do not report the issue as a bug. (Unfortunately, I have not been able to think of a good solution/workaround for these situations other than ignoring the test failure, but I would rather not do that if possible.)

    Integration Tests
    The current integration tests are written in Perl, and rely on the Test-Unit Perl package. Specifically, you must use Test-Unit-0.14, not Test-Unit-0.25. Not sure which version of Test-Unit you have, if at all? Run the following command:

      # perl -MTest::Unit -e 'print $Test::Unit::VERSION, "\n";'
      0.14
    

    To run the integration tests manually, use the tests.pl script:

      # cd tests/
      # perl tests.pl
      t/logins.....................ok                                              
      t/commands/user..............ok                                              
      t/commands/pass..............ok                                              
      t/commands/pwd...............ok                                              
      t/commands/cwd...............ok                                              
      t/commands/cdup..............ok                                              
      t/commands/syst..............ok                                              
      t/commands/type..............ok                                              
      t/commands/mkd...............ok                                              
      t/commands/rmd...............ok                                              
      t/commands/dele..............ok                                              
      t/commands/mdtm..............ok                                              
      t/commands/size..............ok                                              
      t/commands/mode..............ok                                              
      t/commands/stru..............ok                                              
      t/commands/allo..............ok                                              
      t/commands/noop..............ok                                              
      t/commands/feat..............ok                                              
      t/commands/help..............ok                                              
      t/commands/quit..............ok                                              
      t/commands/rnfr..............ok                                              
      t/commands/rnto..............ok                                              
      t/commands/rest..............ok                                              
      t/commands/pasv..............ok                                              
      t/commands/epsv..............ok                                              
      t/commands/port..............ok                                              
      t/commands/eprt..............ok                                              
      t/commands/nlst..............ok                                              
      t/commands/list..............ok                                              
      t/commands/retr..............ok                                              
      t/commands/stor..............ok                                              
      t/commands/appe..............ok                                              
      t/config/displayconnect......ok                                              
      t/config/displaylogin........ok                                              
      t/config/maxloginattempts....ok                                              
      t/config/serverident.........ok                                              
      All tests successful.
      Files=37, Tests=141, 160 wallclock secs ( 4.33 cusr +  4.74 csys =  9.07 CPU)
    

    Some of the integration require root privileges in order to perform the test properly, e.g. for <Anonymous>/DefaultRoot logins, etc. If you do not run `make check' as root, those tests which require root privileges are automatically skipped. Thus for doing a full regression, run the integration tests as the root user.

    Adding New Tests
    The following information is for those who are interested in adding new tests, updating existing tests, or otherwise helping with the testsuite development.

    The API tests driver, api-tests, honors the PR_TEST_SUITE environment variable. This is useful for running just the test cases associated with a particular suite, such as env or pool. Only one suite can be specified using the PR_TEST_SUITE environment variable:

      # make check
      # cd tests/
      # PR_TEST_SUITE=pool ./api-tests
      Running suite(s): pool
      100%: Checks: 5, Failures: 0, Errors: 0
    
    This way, when you are adding to an existing test case or adding a new test case to an existing suite, you need not run the entire API testsuite in order to run your changes.


    Last updated: $Date: 2011/05/19 18:26:42 $

    proftpd-dfsg-1.3.5~rc3/doc/howto/Stopping.html0000644000175000017500000002465111311473754021161 0ustar frankiefrankie ProFTPD mini-HOWTO - Stopping and Starting

    Stopping and Starting ProFTPD


    The starting and stopping of a ProFTPD server is a straightforward process, once the means intended for such things are understood. Starting the server is easy. Stopping and/or restarting the server are the more complicated tasks. Stopping and/or restarting can be accomplish either using signals or ftpshut, depending on your needs. Use of signals will fulfill most requirements; the ftpshut program is used for a specific way of shutting down a proftpd server.

    Starting proftpd
    The ServerType configured in your proftpd.conf determines how you should start your proftpd daemon. A ServerType of "inetd" means that you are letting inetd/xinetd handle the starting of the server; using "standalone" means that you will probably end up using some kind of script (e.g. init.d shell scripts).

    All start scripts end up using, in some form or another, the various command-line options supported by proftpd:

      /usr/local/sbin/proftpd [options]
    
    where /usr/local/sbin is determined by configure and [options] are described below (or in proftpd(8)):
     -h, --help
         Display proftpd usage
     -n, --nodaemon
         Disable background daemon mode and send all output to stderr)
     -q, --quiet
         Don't send output to stderr when running with -n or --nodaemon
     -d [level], --debug
         Set debugging level (0-9, 9 = most debugging)
     -D [definition], --define
         Set arbitrary IfDefine definition
     -c [config-file], --config
         Specify alternate configuration file
     -p [0|1], --persistent
         Enable/disable default persistent passwd support
     -l, --list
         List all compiled-in modules
     -t, --configtest
         Test the syntax of the specified config
     -v, --version
         Print version number and exit
     -vv, --version-status
         Print extended version information and exit
    

    Signals
    You will notice many proftpd processess running on your system, but you should not send signals to any of them except the parent, whose PID is in the PidFile. That is to say, you should not ever need to send signals to any process except the parent. There are two signals that you can send the parent: TERM and HUP, which will be described below.

    To send a signal to the parent you should issue a command such as:

      kill -TERM `cat /usr/local/var/proftpd.pid`
    
    You can read about its progress by issuing:
      tail -f /usr/local/var/logs/proftpd.log
    
    Modify those examples to match your SystemLog and PidFile settings.

    The TERM Signal (stop now)
    Sending the TERM signal to the daemon parent process causes it to immediately attempt to kill off all of its children. It may take it several seconds to complete killing off its children. The daemon itself then exits. Any transfers in progress are terminated, and no further session requests are served.

    Servers run out of inetd or xinetd (e.g. with a ServerType setting of inetd) will not need this signal, as their "parent" is the inetd or xinetd process.

    The HUP Signal (restart now)
    Sending the HUP signal to the daemon parent process causes it to re-read its configuration file(s), and re-opens any log files. Then it returns to handling new sessions. Any existing sessions will not be terminated.

    Servers run out of inetd or xinetd will not need this signal; a new server process is started by the superserver process (e.g. inetd or xinetd) for every session request. This means that any changes to the configuration file will be visible to the next session after saving the changes to the file.

    Note that if your configuration file has errors in it when you issue a restart then your parent will not restart, it will exit with an error. To avoid this, perform a syntax check of the file before sending the signal:

      proftpd -t -d5
    

    Example init.d script
    If your particular Unix/Linux distribution and/or proftpd package does not provide an init shell script for proftpd, or you want to write your own, here is a simple example script to demonstrate what one would look like:

      #!/bin/sh
    
      # ProFTPD files
      FTPD_BIN=/usr/local/sbin/proftpd
      FTPD_CONF=/usr/local/etc/proftpd.conf
      PIDFILE=/var/run/proftpd.pid
    
      # If PIDFILE exists, does it point to a proftpd process?
    
      if [ -f $PIDFILE ]; then
       pid=`cat $PIDFILE`
      fi
    
      if [ ! -x $FTPD_BIN ]; then
        echo "$0: $FTPD_BIN: cannot execute"
        exit 1
      fi
    
      case $1 in
    
        start)
          if [ -n "$pid" ]; then
            echo "$0: proftpd [PID $pid] already running"
            exit
          fi
    
          if [ -r $FTPD_CONF ]; then
            echo "Starting proftpd..."
    
            $FTPD_BIN -c $FTPD_CONF
    
          else
            echo "$0: cannot start proftpd -- $FTPD_CONF missing"
          fi
          ;;
    
        stop)
          if [ -n "$pid" ]; then
            echo "Stopping proftpd..."
            kill -TERM $pid
    
          else
            echo "$0: proftpd not running"
            exit 1
          fi
          ;;
    
        restart)
          if [ -n "$pid" ]; then
            echo "Rehashing proftpd configuration"
            kill -HUP $pid
    
          else
            echo "$0: proftpd not running"
            exit 1
          fi
          ;;
    
        *)
          echo "usage: $0 {start|stop|restart}"
          exit 1
          ;;
    
      esac
    
      exit 0
    

    For Mac OSX users, here is an example Launcher/launchd plist configuration for proftpd:

      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
        <plist version="1.0">
          <dict>
            <key>KeepAlive</key>
              <dict>
                <key>SuccessfulExit</key>
                  <true/>
              </dict>
            <key>Label</key>
              <string>org.proftpd.proftpd</string>
            <key>ProgramArguments</key>
              <array>
                <string>/usr/local/sbin/proftpd</string>
                <string>-n</string>
              </array>
            <key>RunAtLoad</key>
              <true/>
            <key>ServiceIPC</key>
              <false/>
          </dict>
        </plist>
    
    This has been reported to run successfully on Mac OSX 10.4 and 10.5.

    The ftpshut program
    The ftpshut program that comes as part of ProFTPD can also be used to shut down a proftpd server, in a sense. This program does not actually cause the server to stop completely, but rather places the server in an "administrative shutdown" state. This means that the server will still be handling session requests, but will deny incoming requests, telling clients to come back later. ftpshut allows the administrator to configure the server to start refusing connections at some future date, and also to disconnect existing sessions at some future date.

    The situation in which this ability is most useful (a FAQ) is one where filesystem maintainenance or work needs to be done in the area from which the FTP server is serving files, but the server need not be shutdown. By placing the server in an "administrative shutdown" mode, clients are barred from their file while the adminstrative work is being done. Once completed, the server can be put back in normal operating mode by simply deleting the shutdown message file, described below.

    The ftpshut program works by creating a file, usually /etc/shutmsg, for which the server checks periodically. This file will contain the time at which the server is to place itself in "administrative shutdown" mode, and times (if any) of refusing incoming connections, disconnecting existing connections. Unfortunately, many third-party administration tools use ftpshut to shut down proftpd servers, rather than using the method above. The problem with this approach is that, once restarted, the server will check for /etc/shutmsg, and will not accept incoming connections, leading to this FAQ; the third-party administration tool often forgets to delete that file once done.

    Read ftpshut's man page for more detailed information on its usage.


    Last Updated: $Date: 2009/12/14 17:37:48 $

    proftpd-dfsg-1.3.5~rc3/doc/howto/SQL.html0000644000175000017500000007613012156645332020015 0ustar frankiefrankie ProFTPD mini-HOWTO - SQL and mod_sql

    SQL and mod_sql


    Compiling with mod_sql
    To compile proftpd with the mod_sql SQL module, you will need to have the libraries and header files of a SQL database installed; the mysql.h and libmysqlclient.a files for MySQL, the libpq-fe.h and libpq.a files for Postgres.

    mod_sql is the module that provides a generic interface between the proftpd daemon and the underlying SQL database(s); mod_sql relies on backend modules to handle the database-specific operations. For MySQL database, the backend module is mod_sql_mysql; mod_sql_postgres is to be used when dealing with Postgres databases. Then, to build a proftpd daemon to use mod_sql, use the --with-modules option of the configure script, specifying both mod_sql and the backed module, e.g.:

      ./configure --with-modules=mod_sql:mod_sql_mysql
    
    Sometimes the necessary header and library files for building in SQL support are in non-standard locations; the configure script needs to be told about these non-standard locations so that it can find the necessary files, and build the daemon properly. The --with-includes option (for header file locations) and --with-libraries option (for library file locations) are used for informing configure of such things. For example, if you had installed MySQL using a prefix of /usr/local/mysql, so that the path the header file was:
      /usr/local/mysql/include/mysql/mysql.h
    
    and the path the library was:
      /usr/local/mysql/lib/mysql/libmysqlclient.a
    
    then, the above configure line would be changed to look like:
      ./configure \
        --with-modules=mod_sql:mod_sql_mysql \
        --with-includes=/usr/local/mysql/include/mysql \
        --with-libraries=/usr/local/mysql/lib/mysql
    
    The same options can be used similarly for specifying Postgres file locations. (NOTE: Postgres 7.2 or higher should be used; earlier versions of Postgres lacked a string-escaping function that allowed for an SQL injection vulnerability. Use the mod_sql_postgres from proftpd 1.2.9rc1 or later in conjunction with a newer Postgres library to fix the bug.)

    mod_sql is capable of using OpenSSL for different ways of encrypting passwords stored in database tables. The configure options for building an OpenSSL-capable mod_sql might look something like this:

      CFLAGS=-DHAVE_OPENSSL LIBS=-lcrypto ./configure \
        --with-modules=mod_sql:mod_sql_mysql \
        --with-includes=/usr/local/mysql/include/mysql:/usr/local/openssl/include \
        --with-libraries=/usr/local/mysql/lib/mysql:/usr/local/openssl/lib
    
    Note that this example assumes that you have installed OpenSSL using a prefix of /usr/local/openssl.

    Configuring mod_sql
    Now that a proftpd daemon has been compiled for SQL support, you can begin the task of configuring it so that mod_sql can access your SQL database tables. At a very minimum, mod_sql assumes that it has access to a table with two columns, one for user names, the other for passwords. For more complete functionality, tables providing full user and group information are needed. The full information that can be provided is described below.

    User Information Table1
    Column Type Required? Duplicates? Null? Purpose
    userid text yes no no user's login
    passwd text yes yes no user's password
    uid number yes no2 yes user's UID
    gid number no yes yes user's GID
    home3 text no yes yes user's home
    shell4 text no yes yes user's shell

    Notes:

    1. The user table MUST exist.

    2. Nothing in proftpd or mod_sql prevents you from using duplicate UIDs, from given multiple users the same UID. Hower, this is should be done only if you are certain you know what you are doing.

    3. See the SQLDefaultHomedir and SQLUserInfo configuration directives.

    4. See the RequireValidShell configuration directive.

    Group Information Table1
    Column Type Required? Null? Purpose
    groupname text yes no group's name
    gid number yes no group's GID
    members2 text yes yes group's members

    Notes:

    1. mod_sql will normally concatenate all matching group rows; you can have multiple rows for each group with only one member per group, or have a single row with multiple groups, or a mixing of the two. However, if you use the fast option for groupset of the SQLAuthenticate directive, you may not have multiple rows per group.

    2. Multiple members per group are formatted as comma-separated names (no contained whitespace) in the text for this column.

    The two SQL statements below should work for any ANSI SQL compliant databases, and are known to work for MySQL and PostgreSQL. They both fully specify the tables as described above, with reasonable defaults for field length and data type. More stringent definitions are suggested: if you plan on keeping home directory or shell information in the database, those fields could be defined as NOT NULL, or even UNIQUE for home directory. Similarly, if you plan on being able to use the groupsetfast argument to the SQLAuthenticate directive, you should create both the groupname and gid fields as UNIQUE.

    To create a user table:

      CREATE TABLE users (
        userid VARCHAR(30) NOT NULL UNIQUE,
        passwd VARCHAR(80) NOT NULL,
        uid INTEGER UNIQUE,
        gid INTEGER,
        homedir VARCHAR(255),
        shell VARCHAR(255)
      );
    
      CREATE INDEX users_userid_idx ON users (userid);
    
    
    (Note: if you plan to reuse the same UID for multiple users, then you will need to remove the UNIQUE from the uid column description). To create a group table:
      CREATE TABLE groups (
        groupname VARCHAR(30) NOT NULL,
        gid INTEGER NOT NULL,
        members VARCHAR(255)
      );
    
      CREATE INDEX groups_gid_idx ON groups (gid);
    

    The key configuration directives for mod_sql are:

    • SQLConnectInfo for setting the information for connecting to the database server
    • SQLAuthenticate for controlling how the module will perform its authentication lookups
    • SQLAuthTypes for defining which authentication methods to use
    • SQLUserInfo for modifying the names of the columns using which the module will lookup values from the user table
    • SQLGroupInfo for modifying the names of the columns using which the module will lookup values from the group table
    A list of mod_sql configuration directives can be found here.

    Recipes

    Using SQLNamedConnectInfo
    What is SQLNamedConnectInfo, and how can I use it? The
    SQLNamedConnectInfo directive appeared in proftpd-1.3.4rc2 (see Bug#3262); it allows logging to SQL tables in a database separate from e.g. your user database. Using SQLNamedQuery and SQLLog, you tell mod_sql to log information to your database. And now, with SQLNamedConnectInfo, you can tell mod_sql to log information to multiple different databases.

    The following illustrates how SQLNamedConnectInfo can be used. We have two databases, a "userdb" containing the tables with our user data, and a "logdb" database containing various logging tables. First, in the users table schema in the userdb database, let's include a users.last_accessed column, indicating when that user last logged in successfully:

      CREATE TABLE users (
        userid VARCHAR(30) NOT NULL UNIQUE,
        passwd VARCHAR(80) NOT NULL,
        uid INTEGER UNIQUE,
        gid INTEGER,
        homedir VARCHAR(255),
        shell VARCHAR(255),
        last_accessed DATETIME
      );
    
    In the logdb database, let's define a table that we will use for separately logging all successful logins:
      CREATE TABLE login_history (
        user VARCHAR NOT NULL,
        client_ip VARCHAR NOT NULL,
        server_ip VARCHAR NOT NULL,
        protocol VARCHAR NOT NULL,
        when DATETIME
      );
    

    With these tables defined in their databases, we can now configure mod_sql to use the users table for authenticating users. In addition, when a user logs in successfully, update the users.last_accessed column and add a row to the login_history table in the separate logging database:

      <IfModule mod_sql.c>
        AuthOrder mod_sql.c
    
        # We need our "default" connection to the userdb database
        SQLConnectInfo userdb@dbhost:3306 user pass
    
        # Now that we have a default connection, we can create another connection, named "logdb" and using the "mysql" backend, to the logdb database
        SQLNamedConnectInfo logdb mysql logdb@dbhost:3306 user pass
    
        # Point mod_sql at our users/groups tables
        SQLUserInfo users ...
        SQLGroupInfo groups ...
    
        # Update the users.last_accessed column on successful login in the userdb
        SQLNamedQuery last_accessed UPDATE "last_accessed = NOW() WHERE userid='%u'" users
        SQLLog PASS last_accessed
    
        # Add a row to the login_history table on successful login in the logdb
        SQLNamedQuery log_sess FREEFORM "INSERT INTO login_history (user, client_ip, server_ip, protocol, when) VALUES ('%u', '%a', '%V', '%{protocol}', NOW())" logdb
    
        SQLLog PASS log_sess IGNORE_ERRORS
      </IfModule>
    
    Notice how the "log_sess" SQLNamedQuery has "logdb" at the end of the directive, after the SQL to be run? That tells mod_sql that, when running that SQLNamedQuery, use the connection named "logdb".

    Another interesting point in the example above is the use of the IGNORE_ERRORS modifier, when we call the "log_sess" SQLNamedQuery. Why is that used? Here, it means that if the logdb database is not available, or if there is any other problem when inserting the row into the login_history table, that mod_sql should ignore that error and keep processing the connection.

    Question: Why does the SQLNamedConnectInfo documentation say that "SQLNamedConnectInfo directives will only be honored if a SQLConnectInfo directive is configured"?
    Answer: The mod_sql module requires a SQLConnectInfo directive in order to define the "default" named connection. This will be the database connection that mod_sql uses for queries, unless explicitly told to use some other named connection. And if there is no SQLConnectInfo directive present, then mod_sql won't even bother to look for SQLNamedConnectInfo directives, since the "default" connection must be present in order to use any other named connection.

    Using SQLUserPrimaryKey and SQLGroupPrimaryKey
    What is a primary key in mod_sql, and how can I use it? To answer this question, let's look at a common database layout for a proftpd site. You have a ftp_users table containing the user information (i.e. username/password, UID, GID, etc). You have a ftp_sessions logging table that records all client sessions, keyed to the user that logged in. And you have another logging table, ftp_transfers, that tracks the files that are transferred in and out by clients; the entries in this table, too, are keyed to the logged-in user.

    Good schema design principles suggest that which this schema, the ftp_sessions and ftp_transfers tables should have foreign key constraints on columns in the ftp_users table, to enforce the fact that entries in the ftp_sessions and ftp_transfers tables must be related to a row in the ftp_users table. And for efficient database storage, you want the foreign key constraint to use a small column. But there's a problem. The obvious choice of primary key for an ftp_user row would be the UID, a numeric value. But you reuse UIDs for your users; this means that a single UID does not uniquely identify a user. In fact, the only unique identifier you have in ftp_users is the actual username, a string. And some of your usernames are quite large.

    To demonstrate this more clearly, let's look at the mod_sql configuration that would be used to add rows to the ftp_sessions table:

      # Insert a row on successful login (i.e. successful PASS)
      SQLLog PASS start-session IGNORE_ERRORS
    
      SQLNamedQuery start-session FREEFORM "INSERT INTO ftp_sessions (userid, session_id, ...) VALUES ('%u', '%{env:UNIQUE_ID}', ...)"
    
    Instead of userid (which is a VARCHAR(255)), you would prefer to use the ftp_users.id column value, which you added to your ftp_users table specifically to use as a primary key. How to do you tell mod_sql to use that as the primary key for the logged-in user?

    The SQLUserPrimaryKey and SQLGroupPrimaryKey directives appeared in proftpd-1.3.5rc3 (see Bug#3864) for just this reason; they configure the columns that mod_sql to retrieve/use as primary keys. When these directives were present, whenever mod_sql does a successful lookup of a user by name (or of a group by name), mod_sql will then run another query, i.e.:

      SELECT column-name FROM user/group-table WHERE name = user/group-name
    
    And to support the case where the tables/columns are customised, these new directives would of course support custom queries:
      SQLUserPrimaryKey custom:/named-query
      SQLGroupPrimaryKey custom:/named-query
    
    So that you could do:
      SQLNamedQuery get-user-key SELECT "id FROM ftp_users WHERE userid = '%U'"
      SQLUserPrimaryKey custom:/get-user-key
    
      SQLNamedQuery get-group-key SELECT "id FROM ftp_groups WHERE groupname = '%g'"
      SQLGroupPrimaryKey custom:/get-group-key
    

    Now that mod_sql can look up the value for the primary key for the user/group, we need to then be able to use that value in other queries. For this, you would use the "notes" SQLLog variable:

      %{note:sql.user-primary-key}
      %{note:sql.group-primary-key}
    

    Putting this altogether, the above mod_sql configuration for adding rows to the ftp_sessions table, using ftp_users.id as the primary key, becomes:

      # Tell mod_sql to use the ftp_users table for user data
      SQLUserInfo ftp_users ...
    
      # Use ftp_users.id as the user primary key
      SQLUserPrimaryKey id
    
      # Insert a row on successful login (i.e. successful PASS)
      SQLLog PASS start-session IGNORE_ERRORS
    
      SQLNamedQuery start-session FREEFORM "INSERT INTO ftp_sessions (userid, session_id, ...) VALUES (%{note:sql.user-primary-key}, '%{env:UNIQUE_ID}', ...)"
    

    Question: Why use new configuration directives, rather than changing the existing SQLUserInfo/SQLGroupInfo directives to include a primary key column?
    Answer: New directives were added for this functionality for two reasons: 1) not every site needs/uses primary keys and foreign key constraints in their schema, and 2) we wanted to make sure that existing configurations/schema did not break and behave unexpectedly (i.e. to preserve backward compatibility).

    Frequently Asked Questions
    Whenever questions arise about problems using mod_sql, the first place to look will be the server debugging output and in a SQLLogFile. mod_sql is very verbose with its debugging information, and you can see everything it is doing. However, there are times when there is too much information in the debugging output, and you are unsure of how to remedy the problem. These are some of the frequent questions.

    Question: Why is proftpd only looking in my SQL tables when a user logs in?
    Answer: You probably configured mod_sql to be "authoritative" in your SQLAuthenticate setting by using the * option. Conversely, if you actually want proftpd to only authenticate SQL-defined users, the * "authoritative" suffix is what you would want to use.

    Question: Why does my SQL user not use the UID/GID I configured for her in my SQL table?
    Answer: More than likely, you gave this user a UID that is below the default SQLMinUserUID (999), or a GID that is below the default SQLMinUserGID (999). Use the SQLMinUserUID, SQLMinUserGID, and/or SQLMinID configuration directives to set these limits lower as needed.

    Question: Do I have to configure a real shell for my SQL-defined users?
    Answer: No. The proftpd daemon only checks the shell for a user in order to provide compatibilty with other FTP daemons, which do the same check; proftpd itself does not spawn the shell. See the RequireValidShell configuration directive for turning this check off.

    Question: How come my SQLLog QUIT is not run if the session aborts or dies?
    Answer: Not all FTP clients are polite and issue the QUIT before the session ends. Perhaps their session is timed out, or dropped due to network problems. Use EXIT as the FTP command in your SQLLog directive, rather than QUIT, as mentioned in the SQLLog documentation.

    Question: How can I make mod_sql go faster?
    Answer: There are a couple of things you might try. First, if using a version of mod_sql from ProFTPD-1.2.7rc1 or later, make use of the SQLNegativeCache configuration directive.

    Other forms of this question are "Why does mod_sql iterate through every user in the database?", or "Why is mod_sql so slow during logins?" Here's the reason: mod_sql is designed to handle all authentication functions that the daemon throws at it. This includes the functions that iterate through all users (setpwent(), getpwent(), endpwent()) and the functions that iterate through all groups (setgrent(), getgrent(), endgrent()).

    When you see mod_sql iterating through all groups or users, it is doing so because it has been asked to do so by the daemon. Since there is no good way to keep an open query around without adding more to the various backend modules than we already have, mod_sql pre-caches all users when setpwent() is called, and pre-caches all groups when setgrent() is called. This allows the getpwent() and getgrent() calls to be simple, at the cost of more time during login.

    In simple situations, these functions are never called. When you start limiting access to directories, files, or various FTP commands based on user or group, that is when the daemon needs to iterate through the users and groups to check permissions. A basic FTP server, including virtual and anonymous servers, will never make the (potentially, very) expensive user iteration calls, but may iterate through all groups.

    The SQLAuthenticate directive provides a method to tune mod_sql; by default, mod_sql will handle the various *pwent() and *grent() calls. When SQLAuthenticate is told not to handle userset or groupset, mod_sql simply passes the request on to whatever authentication handlers exist in the system. Keep in mind that using SQLAuthenticate in this way means that the proftpd daemon is not using the same information to authenticate the user as it is to control the user's actions during their session.

    For those of you who have used mod_sql in the past, these lookups should probably be set to off. Versions of mod_sql prior to 3.2.0 (or thereabouts) did not handle the {set|get|end}{pw|gr}ent functions at all, so by setting these lookups to off, you lose no functionality. Those of you new to mod_sql should to consider your needs: is the cost of iterating through every user stored in the database worth the ability to limit access based on users/groups from the database? If not, you will need to re-evaluate the way you are using the database, and where you should be storing your user/group information.

    Question: When I use an SQLAuthTypes that includes "OpenSSL", what do the values in the database need to look like?
    Answer: The value that mod_sql expects is the base64-encoded value of the digested password string. To get a list of the message digest algorithms supported by your OpenSSL installation, you can execute the following command:

      openssl list-message-digest-commands
    
    To generate the string to put into the SQL tables, using MD5 as the digest algorithm and "password" as the password:
      /bin/echo "{md5}"`/bin/echo -n "password" | openssl dgst -binary -md5 | openssl enc -base64`
    
    The "{md5}" prefix is necessary, so that mod_sql knows what digest algorithm was used.

    Here's a quick and dirty example of generating database-ready strings using every digest algorithm supported by the installed OpenSSL:

      for c in `openssl list-message-digest-commands`; do
        /bin/echo "{$c}"`/bin/echo -n "password" | openssl dgst -binary -$c | openssl enc -base64`
      done
    
    which generates:
      {md2}8DiBqIxuORNfDsxg79YJuQ==
      {md4}ip0JPxT4cB3xdzKyuxgsdA==
      {md5}X03MO1qnZdYdgyfeuILPmQ==
      {mdc2}HA0SCu32vhW+exItsGK4lQ==
      {rmd160}LAjo9YhHUKe5n28vNC/GONsl/zE=
      {sha}gAclaL6zshAjJesgP20P+S9c744=
      {sha1}W6ph5Mm5Pz8GgiULbPgzG37mj9g=
    

    Note: the {digest} prefix syntax is only needed for passwords that will be handled as OpenSSL-style passwords. This prefix is not needed for any of the other SQLAuthType types.

    There are a lot of PHP applications which might want to generate passwords suitable for use with mod_sql. For example, to generate a base64-encoded MD5 password with PHP, which can then be read by mod_sql, use the following PHP code:

      // $password contains the cleartext password before
      $password = "{md5}".base64_encode(pack("H*", md5($password)));
    
      // $password now contains the encrypted, encoded password
    
    Or if you're using Python, you might try the following:
      password = "{md5}" + base64.b64encode(md5.new("password").digest())
    

    If this prefixed format is not sufficient for your needs, you can also use the mod_sql_passwd module, which knows how to handle "raw" MD5, SHA1, and other encoding schemes.

    Question: Why do I see "error deleting scoreboard entry: Invalid argument"?
    Answer: This log message almost always denotes use of mod_sql, and a problem in the mod_sql configuration. To debug the problem, define an SQLLogFile (making sure the path is not in a world-writable directory), to which mod_sql will write debugging information.

    Question: I am trying to compile proftpd with MySQL support, and get the following error when I run make. Why?

      /usr/bin/ld: cannot find -lz
      collect2: ld returned 1 exit status
      make: *** [proftpd] Error 1
    
    Answer: This error means that the linker cannot find the libz library. For many systems, this library is provided by the zlib package; you may need to install this zlib package. The libz library is required by the MySQL client libraries.

    Question: I was able to compile proftpd with mod_sql without problems, but now when I try to start proftpd, I get the following error. Why?

      proftpd: error while loading shared libraries: libpq.so.5: cannot open shared object file: No such file or directory
    
    Answer: Errors about "loading shared libraries", especially when they happen when starting proftpd, come from the dynamic/shared library loader. The linker was able to find that library at compile time, but not at run time. If you were to look for the specified library, you would see it. So why can't the shared library loader find it?

    Updating the directories searched automatically by the shared library loader is a platform-specific task. On Linux, for example, you will need to edit your /etc/ld.so.conf file to include the directory containing the SQL client libraries; then run /sbin/ldconfig in order update the shared library loader cache file. Once the shared library loader has been updated, proftpd should start without problems.

    Question: What is the difference between the userset and usersetfast SQLAuthenticate options, and when would I use them?
    Answer: It depends, of course.

    First, the use of these options is only relevant when the session is chrooted, either via the DefaultRoot directive or because it is an <Anonymous> login. (Why? When chrooting a session, proftpd calls the setpwent() function in order to "reset" or "rewind" the user info database; this ensures that all of the info in the user info database is accessible in the chrooted session.)

    The userset SQLAuthenticate option says that the info for all users should be looked up and cached when setpwent() is called. Specifically, the list of names for every user in the database (and just the names!) is looked up. For each user name, a SELECT query (using the SQLUserInfo configuration) is used to retrieve all of the details for that user.

    The usersetfast SQLAuthenticate option goes even further, Rather than having a SELECT per user name, usersetfast says to lookup all the info for all the users when setpwent() is called, in a single SELECT query (again, based on the SQLUserInfo configuration).

    Knowing the above, the choice of when to use userset or usersetfast becomes one of efficiency. Some efficiency (in terms of ID-to-name lookups during the session) can be gained by using userset, since the info for all users is cached (using a SELECT query per user). Even more efficiency is gained by using usersetfast to lookup the info for all users using a single SELECT query. In both cases, the price you pay for the efficiency is increased memory usage in the session process, of course; the info for all users will be held in memory in the process for every session.

    The above holds true for the groupset and groupsetfast SQLAuthenticate options as well.

    Question: How do I configure mod_sql so that it will use encrypted connections (e.g. SSL/TLS) to the backend database server?
    Answer: This sort of configuration depends on the backend database server you are using.

    If you are using MySQL, then you can configure this in the "[client]" section of your my.cnf configuration file.

    If you are using Postgres, then this will happen automatically, by default, as long as your libpq Postgres client library has been compiled with SSL support.


    Last Updated: $Date: 2013/06/14 16:54:50 $

    proftpd-dfsg-1.3.5~rc3/doc/howto/ConfigurationTricks.html0000644000175000017500000003647012036435546023351 0ustar frankiefrankie ProFTPD mini-HOWTO - Configuration Tricks

    Configuration Tricks


    Proficient users of proftpd, and site administrators who require fancy configurations, usually make use of a handful of useful tricks when it comes to configuring their FTP server. These tricks can help to make your proftpd.conf smaller, clearer, and easier to maintain.

    Configuration File Variables
    One juicy tidbit of configuration knowledge is the little known %u variable. It will be substituted, during the handling of an FTP session, with the name of the user who logged in.

    The %u variable can be appear in the proftpd.conf like so:

      DefaultRoot /home/%u
    
    Now, the above may not seem that useful, not much of an improvement over using the tilde (~) symbol, for restricting users to their home directories. But what if you wanted to restrict users to the public_ftp/ subdirectory, within their home directories? Using the tilde character cannot achieve that. Instead, you might use:
      DefaultRoot /home/%u/public_ftp
    

    This is also useful for setting up configurations for specific directories in all users' home directories, e.g.:

      <Directory /home/%u/public_ftp>
        ...
      </Directory>
    

    This %u variable can appear in the following configuration directives:

    • DefaultChdir
    • DefaultRoot
    • <Directory>

    Simple Per-User Directory Hashing
    Some sites find that they might have large number of users (on the order of hundreds to thousands), each with their own home directory. You might start off using a directory layout such as /home/user/ for each user, but this quickly leads to such a large number of subdirectories in the /home/. With that number of entries, simple commands like ls(1) may never complete, or take minutes to hours.

    To reduce the number of entries within a given directory, such large sites often look to use some form of directory hashing. The simplest form is to change from e.g. /home/user/ to /home/u/us/user/. For example, if you had user "bobsmith", the home directory would be /home/b/bo/bobsmith.

    The question then is: can proftpd be configured to use a directory hashing scheme like this, without having to change the home directory attribute for those thousands of users (which might be stored in an LDAP directory used by applications as well)? Answer: yes. The %u variable above supports way to handle simple directory hashing.

    To use it, you would use something like the following in your proftpd.conf:

      DefaultRoot /home/%u[0]/%u
    
    where the %u variable is the user name, and %u[index] can be used to reference the letters in the user name, at that index position. The above configuration would use a single level of directory hashing, resulting in e.g. /home/b/bobsmith. If your directory hashing gets more complex, using more levels, you can still use this syntax:
      DefaultRoot /home/%u[0]/%u[0]%u[1]/%u[0]%u[1]%u[2]/%u
    
    which would result in /home/b/bo/bob/bobsmith.

    Of course, more complex hashing schemes can be used, but proftpd does not currently implement them.

    Environment Variables
    Did you know that you can also substitute environment variables into your proftpd.conf as well? It's true! ProFTPD started supporting using environment variables in configuration files in the 1.2.10rc1 release. To use the environment variable, simply use:

      %{env:ENV_VAR_NAME}
    
    Unlike the %u variable, you can use environment variables anywhere within your proftpd.conf file.

    For example, you might use something like this if you wanted to control the default IP address on which proftpd listens using an environment variable:

      DefaultAddress %{env:PR_DEFAULT_ADDR}
    
    Then whatever value the PR_DEFAULT_ADDR environment variable has, when starting proftpd, will be substituted in. Using:
      PR_DEFAULT_ADDR='127.0.0.1' /usr/local/sbin/proftpd ...
    
    would mean that, effectively, the configuration would be:
      DefaultAddress 127.0.0.1
    
    "What happens if the environment variable is not set?" you ask. Good question. Then the configuration file parser will substitute in an empty string, and proftpd will probably fail to start, citing a configuration error.

    Conditional Configuration Files
    Another common request or desire to make large sections of your configuration conditional. Maybe you only want some directives to apply to certain users, or maybe you want to ship a proftpd.conf that can be used by people with different modules loaded (e.g. for distributing a common proftpd.conf). Or maybe you simply want some sections of your configuration file to be used based on something else entirely.

    The most common conditional you will probably see in various proftpd.conf files is:

      <IfModule moduleName>
        ...
      </IfModule>
    
    This is way of making the configuration directives within that section only in effect if the specified module is present. It may not seem like much, but this is quite useful. (I have a single proftpd.conf with more than 20 such sections, for use while I develop new modules.)

    I have seen one clever sysadmin use the above conditional section in conjunction with DSO modules in their proftpd.conf like so:

      <IfModule mod_dso.c>
        # If mod_dso is present, we know we can dynamically load DSO modules
    
        <IfModule !mod_sql.c>
          # If mod_sql is not yet loaded, load it!
          LoadModule mod_sql.c
        </IfModule>
    
        <IfModule !mod_sql_mysql.c>
          # If mod_sql_mysql is not yet loaded, load it!
          LoadModule mod_sql_mysql.c
        </IfModule>
        
      </IfModule>
    
    You can see how, with the above, you can use provide the same proftpd.conf to sites which use shared modules as well as those which use static modules.

    Users who wish to have entire sections of configuration only apply to specific users, or groups, or even classes of clients really should be aware of the mod_ifsession module, and its very handy <IfUser>, <IfGroup>, and <IfClass> sections.

    And, for those admins who want even more control over large sections of their proftpd.conf on a conditional basis, there is:

      <IfDefine value>
        ...
      </IfDefine>
    
    The enclosed section of the configuration file will be parsed only if value is defined. For multiple directives, this trick is better than using multiple environment variables; the latter is better for single parameters.

    "But how you define value?", you say. There are two ways of defining the values that <IfDefine> looks for: using the -D command-line option, or by using the Define directive.

    Let us assume that your proftpd.conf contains a section like:

      <IfDefine USE_SQL>
        LoadModule mod_sql.c
        LoadModule mod_sql_mysql.c
      </IfDefine>
    
    You can then make sure your proftpd loads those modules by starting it using -D, i.e.:
      /usr/local/sbin/proftpd -DUSE_SQL ...
    
    Or, if later you decide that you don't want to use -D anymore, you can simply add a Define to the proftpd.conf:
      Define USE_SQL
    
      ...
    
      <IfDefine USE_SQL>
        LoadModule mod_sql.c
        LoadModule mod_sql_mysql.c
      </IfDefine>
    

    If you are really ambitious, you can use devious combinations of Define, environment variables, <IfModule> and <IfDefine> sections in your configuration file to achieve some terse but powerful files.

    As a demonstration, here is an example making use of environment variables, Define, and <IfDefine>. First, set an environment variable, e.g. (assuming Bourne shell syntax):

      $ USE_BANS=TRUE
      $ export USE_BANS
    
    Now start proftpd using the -D command-line option to set a define based on the value of that environment variable:
      $ ./proftpd -DUSE_BANS=$USE_BANS ...
    
    And in the proftpd.conf, you might have something like:
      <IfDefine USE_BANS=TRUE>
        ..
      </IfDefine>
    
    in which case, the directives within that conditional section would be in effect when proftpd was started. On the other hand, to disable those configuration directives before starting proftpd, all that you need to do now is change the environment variable value:
      $ USE_BANS=FALSE
      $ export USE_BANS
    
    That <IfDefine> section will no longer be in effect when proftpd is started.

    Multiple Daemons on Same Host
    What if you wanted to run multiple instances of proftpd on the same host? This is actually a prudent idea, for running one production proftpd while running a different, possibly newer proftpd for testing, side-by-side. Is it possible? Of course!

    Different proftpd daemons can coexist on the same machine, but they cannot all use the same configuration file. There is a small list of directives that need to have different parameters for each proftpd instance, i.e.:

    • PidFile
    • ScoreboardFile
    • ServerLog
    • SystemLog

    Failure to assign different PidFiles and ScoreboardFiles for each proftpd will cause the multiple instances to overwrite each other's files, and inevitably cause problems. Keeping separate log files (ServerLog, SystemLog, etc) for each daemon is simply a good idea.

    What about the PassivePorts directive? Do the different proftpd instances each need their own range? No. When a passive data transfer is requested, proftpd will choose a random port from within a PassivePorts range, but not before then. If the port happens to be in use, proftpd will try another random port within the range, and so on, until the range is exhausted. Thus multiple proftpd instances should be able to share the same PassivePorts range without issue (assuming it is a decently wide range).

    There is one final setting which can cause problems: Port. An actual incident can help illustrate the issue:

    I tried to setup another instance of proftpd. I copied my existing config file and changed the port information. My production FTP server runs on port 1979. In the test config file I specified 1980. I started the testing instance on the command line by executing the following command: ./proftpd -d 5 -n -c /etc/proftpd/proftpd.test.conf The testing instance started up without any problems. Unfortunately, when a client connected it gave the error message that the server is already bound to port 1979. This is very strange, as the client connected successfully to port 1980 in the first instance. How did the test server get the port information of the other production server?

    In reality, the test server did not "get" the port information from the production instance. Instead, this admin was encountering the "L-1" issue. The FTP RFCs state that for active data transfers, the source port of the TCP connection (the source port of the TCP connection from the server to the client) must be L-1, where L is the control port number.

    So if your control port (configured by the Port directive in proftpd.conf) is 1980, then the source port that proftpd has to use, for any active data transfers (e.g. for clients which use the PORT or EPRT commands), is 1979. If that port 1979 is already in use by another daemon (such as another proftpd instance as its control port), you have a collision, and will likely see the "Address already in use" error message.

    In the case, the test server should work if the following was used:

      Port 1981
    
    i.e. a port number that is the existing proftpd's port number plus two (or more).

    Using the above configuration tricks, the same proftpd.conf file could be used by both the production and the test daemons, using something like:

      # These directives need to differ depending on whether the test server
      # or the production server is reading this configuration.
      <IfDefine TEST>
        Port 2121
        PidFile /var/ftpd/proftpd.test.pid
        ScoreboardFile /var/ftpd/proftpd.test.scoreboard
      </IfDefine>
    
      <IfDefine !TEST>
        Port 2123
        PidFile /var/ftpd/proftpd.pid
        ScoreboardFile /var/ftpd/proftpd.scoreboard
      </IfDefine>
    
    Then, starting proftpd with the proper command-line invocation e.g.:
      /usr/local/sbin/proftpd -DTEST ...
    
    will use the test server configuration. Omitting the -D option on the command-line will cause proftpd to use the production configuration.

    Reducing FTP Traffic Impact on Host System
    Some sites run proftpd on a system which is used to host other services as well (e.g. Apache, a file server, etc). These sites might notice that when many FTP downloads or uploads are happening, the other services start to be impacted: slower/stuttering web pages or streaming video/music, for example.

    Wouldn't it be nice if you could somehow tell proftpd to use a lower priority, i.e. in the manner of the nice(1) command, for such data transfers? Fortunately, you can do exactly this using the TransferPriority directive. For example, a good default configuration to use is:

      # Use a low process priority during all data transfers
      TransferPriority APPE,RETR,STOR,STOU low
    
    One user reporting always having stuttering streaming video when FTP data transfers were happening. After using the TransferPriority directive, that user saw no more video stream stuttering while still approaching full LAN network speed for the FTP data transfer.


    $Date: 2012/10/14 04:11:18 $
    proftpd-dfsg-1.3.5~rc3/doc/utils/0000755000175000017500000000000012156653653016466 5ustar frankiefrankieproftpd-dfsg-1.3.5~rc3/doc/utils/ftpmail.html0000644000175000017500000001730112057453050020777 0ustar frankiefrankie ftpmail: Automated Email Notifications of Uploads

    ftpmail: Automated Email Notifications of Uploads



    The ftpmail program is a Perl script designed to read ProFTPD's TransferLog log entries, watching for uploads, and to send an automatic email notification when uploads occur. To use ftpmail, you configure your proftpd daemon to write its TransferLog to a FIFO; the ftpmail program is a FIFO reading program which then processes those log messages.

    The most current version of ftpmail is distributed with the ProFTPD source code.

    Author

    Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this program.



    Usage

    First, you have the following Perl modules installed:
    • Mail::Sendmail
    • Time::HiRes
    You can easily determine if your Perl has these modules present, using:
      # perl -MMail::Sendmail -e0
      # perl -MTime::HiRes -e0
    
    If you see an error similar to:
      Can't locate Mail/Sendmail.pm in @INC (@INC contains: ...)
    
    it means that you do not have that Perl module installed. Go to search.cpan.org to download the latest versions of these modules, and install them as per their instructions.

    Next, you need to create the FIFO that ftpmail will read from. See the mkfifo(1) man page for instructions on how to create a FIFO. Note that you must use mkfifo to create a FIFO; using an ordinary file that happens to have a ".fifo" extension will not work for this.

    After that, you need to start ftpmail running, before starting proftpd. For example, you might do:

       # ./ftpmail \
           --fifo=/var/proftpd/log/transfer.fifo \
           --from='tj@castaglia.org' \
           --recipient='tj@castaglia.org' \
           --smtp-server=mail.domain.com \
           --attach-file \
           --log=/var/proftpd/log/transfer.log &
    
    The key is to make ftpmail run in the background, so that it is constantly running. If the ftpmail process dies, then proftpd will not be able to write the TransferLog.

    The next step is to configure your proftpd daemon to write to the FIFO you created. Thus in your proftpd.conf, you would use the same path as given to ftpmail's --fifo option, e.g.:

      TransferLog /var/proftpd/log/transfer.fifo
    

    Then start proftpd, log in, upload a file, and see what happens. One user modified their init for proftpd such that the ftpmail program was automatically started before the proftpd daemon was started.

    Options
    The following shows the full list of ftpmail options; this can also be obtained by running:

      # ftpmail --help
    
      usage: ftpmail [--help] [--fifo $path] [--from $addr] [--log $path]
        [--recipient $addr] [--subject $string] [--smtp-server $addr]
        [--attach-file] [--ignore-users $regex | --watch-users $regex]
    
      The purpose of this script is to monitor the TransferLog written by proftpd
      for uploaded files.  Whenever a file is uploaded by a user, an email
      will be sent to the specified recipients.  In the email there will be
      the timestamp, the name of the user who uploaded the file, the path to
      the uploaded file, the size of the uploaded file, and the time it took
      to upload.
    
      Command-line options:
    
        --attach-file         If used, this will cause a copy of the uploaded file
                              to be included, as an attachment, in the generated
                              email.
    
        --auth $path          Configures the path to a file containing SMTP
                              authentication information.
    
                              The configured file should look like this:
    
                                  user = $user
                                  password = $password
    
        --fifo $path          Indicates the path to the FIFO to which proftpd is
                              writing its TransferLog.  That is, this is the path
                              that you used for the TransferLog directive in your
                              proftpd.conf.  This parameter is REQUIRED.
    
        --from $addr          Specifies the email address to use in the From header.
                              This parameter is REQUIRED.
    
        --help                Displays this message.
    
        --ignore-users $regex Specifies a Perl regular expression.  If the
                              uploading user name matches this regular expression,
                              then an email notification is NOT sent; otherwise,
                              an email is sent.
    
        --log $path           Since this script reads the TransferLog using FIFOs,
                              the actual TransferLog file is not written by default.
                              Use this option to write the normal TransferLog file,
                              in addition to watching for uploads.
    
        --recipient $addr     Specifies an email address to which to send an email
                              notification of the upload.  This option can be
                              used multiple times to specify multiple recipients.
                              AT LEAST ONE recipient is REQUIRED.
    
        --smtp-server $addr   Specifies the SMTP server to which to send the email.
                              This parameter is REQUIRED.
    
        --subject $string     Specify a custom Subject header for the email sent.
                              The default Subject is:
    
                                User '$user' uploaded file '$file' via FTP
    
        --watch-users $regex  Specifies a Perl regular expression.  If the
                              uploading user name matches this regular expression,
                              then an email notification is sent; otherwise,
                              no email is sent.
    

    FAQ

    Question: I would like to use ftpmail to send emails, but only for files uploaded to specific domains. How do I do this?
    Answer: To do this, you will need to configure different TransferLog files in your different <VirtualHost> sections in your proftpd.conf.

    The TransferLog file format does not include a field indicating the IP address (or DNS name) of the server on which the file transfer is occurring. This means that ftpmail does not know which server is handling the transfer. So, in order to have ftpmail send emails only for certain domains/servers, you will have to do something like:

     <VirtualHost a.b.c.d>
        ...
        TransferLog /path/to/vhost1.xferlog
        ..
      </VirtualHost>
    
      <VirtualHost e.f.g.h>
        ...
        TransferLog /path/to/vhost2.xferlog
        ...
      </VirtualHost>
    
    Then start instances of ftpmail running, but only for the TransferLog files of the domains/virtual servers to be monitored.



    Author: $Author: castaglia $
    Last Updated: $Date: 2012/12/04 19:59:36 $


    © Copyright 2008-2012 TJ Saunders
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/utils/prxs.html0000644000175000017500000000772611720513510020343 0ustar frankiefrankie prxs: PRoftpd eXtenSion tool

    prxs: PRoftpd eXtenSion tool



    This prxs program is used to build DSO modules (also known as "shared" modules).

    The most current version of prxs is distributed with the ProFTPD source code.

    Author

    Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this program.



    Usage

    prxs is a tool for building and installing extension modules for the ProFTPD FTP server. This is achieved by building a dynamic shared object (DSO) from one or more source or object files which then can be loaded into the ProFTPD server at runtime via the LoadModule directive from the mod_dso module.

    To use this extension mechanism your platform has to support the DSO feature and your proftpd executable has to be built with the mod_dso module. The prxs tool automatically complains if this is not the case. You can check this yourself by manually running the command:

      $ proftpd -l
    
    The module mod_dso should be part of the displayed list. If these requirements are fulfilled you can easily extend your ProFTPD server's functionality by installing your own modules with the DSO mechanism by the help of this prxs tool.

    The DSO documentation also describes how prxs works in more details.



    Options

    The following is the output from running prxs --help:
    usage: prxs   
    
    Actions:
    
     -c, --compile          Compiles the listed .c source files into a proftpd
                            DSO module.
    
     -i, --install          Installs a compiled proftpd DSO module into the
                            directory where proftpd expects to find loadable
                            DSO modules.
    
     -d, --clean            Removes any generated files, returning the build
                            directory to a clean state.
    
    Options:
    
     -h, --help             Displays this message.
    
     -n, --name             Tells prxs the name of the module being compiled.
                            By default, prxs determines the module name from
                            the list of .c files listed, expecting to see a
                            "mod_$name.c" file.
    
     -D key                 Passes these macros through to the compilation step.
     -D key=value           Note that the space before the key is important.
    
     -I includedir          Specify additional include file search directories.
                            Note that the space before the directory is important.
    
     -L libdir              Specify additional library file search directories.
                            Note that the space before the directory is important.
    
     -l library             Specify additional libraries for linking.
                            Note that the space before the library name is
                            important.
    
    At least one of the above actions must be specified when using prxs.  More
    than one action can be specified at the same time.
    
    To use prxs all in one step, you could do:
    
      prxs -c -i -d mod_custom.c
    
    



    Author: $Author: castaglia $
    Last Updated: $Date: 2012/02/20 18:56:08 $


    © Copyright 2000-2012 TJ Saunders
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/utils/index.html0000644000175000017500000000547212061706177020466 0ustar frankiefrankie ProFTPD Utilities Documentation

    ProFTPD Utilities Documentation


    The following is a collection of HTML documentation for utilities which accompany the ProFTPD source distribution.

      The ftpasswd utility
      Handles the creation/management of AuthUserFile, AuthGroupFile, and UserPasswords.

      The ftpcount utility

      The ftpdctl utility

      The ftpmail utility
      Used to automatically send email, triggered by directing the, TransferLog to the script via a FIFO.

      The ftpquota utility
      Handles the creation/management of quota limit/tally tables of type "file" for the mod_quotatab module.

      The ftpscrub utility
      Can be used to "scrub" the ScoreboardFile of dead sessions, i.e. caused by sessions which die uncleanly. See the Scoreboard howto for more information.

      The ftpshut utility

      The ftptop utility

      The ftpwho utility

      The prxs utility
      Used to compile DSO modules.

    If your question or issue is not covered by any of these pages, please send a request to the ProFTPD documentation list. Directions for subscribing to the docs list, as well as the other ProFTPD mailing lists, are at:

      http://www.proftpd.org/lists.html
    
    If you are looking to see if ProFTPD supports a particular feature, the first place to look as the complete list of configuration directives:
      http://www.proftpd.org/docs/directives/linked/by-name.html
    
    The list may be intimidatingly long, but it is well worth scanning through all of the directives to see everything that ProFTPD is capable of supporting.


    Last Updated: $Date: 2012/12/11 19:41:51 $

    proftpd-dfsg-1.3.5~rc3/doc/utils/ftpasswd.html0000644000175000017500000003271411534011571021200 0ustar frankiefrankie ftpasswd: tool for ProFTPD's AuthUserFile, AuthGroupFile, UserPassword

    ftpasswd: tool for ProFTPD's AuthUserFile, AuthGroupFile, UserPassword



    This program is used to create and manage files, correctly formatted, suitable for use with ProFTPD's AuthUserFile and AuthGroupFile configuration directives. It can also generate password hashes for ProFTPD's UserPassword directive.

    The most current version of ftpasswd is distributed with the ProFTPD source code, under the contrib/ directory.

    Author

    Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this program.



    Usage

    The following describes the common usage of the ftpasswd tool. The options supported are described in more detail later.

    This script is intended to replace the genuser.pl script that is currently distributed with proftpd. That script can generate DES-hashed passwords, suitable for use with the UserPassword configuration directive, but it is not quite right for AuthUserFiles. Another common mistake is to use the htpasswd program from Apache to create files for proftpd. Apache and ProFTPD both have the same AuthUserFile and AuthGroupFile directives; the format of the files used by each server is different.

    Creating Files
    The ftpasswd program can create and update files for both AuthUserFile and AuthGroupFile. When it is used for the first time, the program will create the necessary file. If that file already exists, ftpasswd will update it with the new information.

    ftpasswd must first know what type of file to create. Use either the --passwd option (for handling AuthUserFiles), or the --group option (for handling AuthGroupFiles); this is required.

    When creating an AuthUserFile, the following options are also required: --name, --uid, --home, and --shell. This information is required by proftpd to authenticate a user. The optional parameters for an AuthUserFile include --gid (defaults to the given --uid argument when not provided) and --gecos (not used by proftpd at all). For example:

      ftpasswd --passwd --name=bob --uid=1001 --home=/home/bob --shell=/bin/false
    
    creates an account for user bob. To create a file with a name or location other than the default (which, for --passwd mode is ftpd.passwd), use the --file option. For example, to create the alternate password file in /usr/local/etc/ftpd/passwd:
      ftpasswd --passwd --file=/usr/local/etc/ftpd/passwd --name=bob --uid=1001 --home=/home/bob \
        --shell=/bin/false
    

    For AuthGroupFiles, use --group:

      ftpasswd --group --name=group-name --gid=group-id --member=user-member1  \
        --member=user-member2 ... --member=user-memberN
    

    The most common change to these files is made to AuthUserFiles, to change a user's password. The --change-password option was provided just for this scenario:

      ftpasswd --passwd --name=user --change-password
    

    Creating Hashes
    A less common need is to generate a password hash for some user, to be used in a UserPassword directive in the proftpd.conf. One could generate a file using --passwd and then extract the password hash from the file. Easier, though, is to use ftpasswd's --hash option:

      ftpasswd --hash
    
    The password will either be prompted for, or it can be given on standard in using --stdin.

    Automated Use
    The ftpasswd provides a useful command-line interface to interacting with the authentication files. Many sites would like to be able to remotely manipulate these files, just as ftpasswd does, only using a web-based mechanism, perhaps even providing a page to users to change their passwords, instead of requiring use of a shell. Wrapping a shell or Perl script around ftpasswd is the logical solution.

    To aid such automated wrapper scripts, ftpasswd has two features: its return value, and a specific option. The program returns 0 if the requested change was successful, and 1 if there was an error (no such user/group, password matched system password and the --not-system-password option was used, etc.). The specific option is --stdin: this allows scripts to provide a password to ftpasswd without prompting for a password. For example:

      echo passwd-variable | ftpasswd opts --stdin
    
    Note that the --stdin option does not allow passwords to be passed to the script on the command line, but on stdin. This is done as a security measure: the standard Unix ps command can be used to show all the processes running on a system including their command line parameters. This means that any user could use ps to watch passwords given to ftpasswd, if those passwords were to be passed on the command line. Some operating systems (e.g. FreeBSD) allow the sysadmin to prevent users from seeing all processes in this manner; consult your operating system documentation for more information.

    There are other issues that arise when using AuthUserFiles. This document discusses these issues in greater detail.



    Options

    The following is the output from running ftpasswd --help:
    usage: ftpasswd [--help] [--hash|--group|--passwd]
    
      REQUIRED: --passwd, --group, or --hash.  These specify whether ftpasswd is to
      operate on a passwd(5) format file, on a group(5) format file, or simply
      to generate a password hash, respectively.
    
      If used with --passwd, ftpasswd creates a file in the passwd(5) format,
      suitable for use with proftpd's AuthUserFile configuration directive.
      You will be prompted for the password to use of the user, which will be
      encrypted, and written out as the encrypted string.  New entries are
      appended to the file by default.
     
      By default, using --passwd will write output to "./ftpd.passwd".
    
      Error exit values:
    
      To make it easier for wrapper scripts to interact with ftpasswd, ftpasswd
      will exit with the following error values for the reasons described:
    
        1       no such user
        2       password matches current password
        4       password matches system password
        8       relative path given for home directory
    
      Options:
    
        --file      Write output to specified file, rather than "./ftpd.passwd"
    
        -F          If the file to be used already exists, delete it and write a
        --force     new one.  By default, new entries will be appended to the file.
    
        --gecos     Descriptive string for the given user (usually the user's
                    full name).
    
        --gid       Primary group ID for this user (optional, will default to
                    given --uid value if absent)
    
        -h          Displays this message
        --help
    
        --home      Home directory for the user (required)
    
        --des       Use the DES algorithm for encrypting passwords.  The default
                    is the MD5 algorithm.
    
        --md5       Use the MD5 algorithm for encrypting passwords.  This is the
                    default.
    
        --name      Name of the user account (required).  If the name does not
                    exist in the specified output-file, an entry will be created
                    for her.  Otherwise, the given fields will be updated.
    
        --shell     Shell for the user (required).  Recommended: /bin/false
    
        --uid       Numerical user ID (required)
    
        --change-password
    
                    Update only the password field for a user.  This option
                    requires that the --name and --passwd options be used, but no
                    others.  This also double-checks the given password against
                    the user's current password in the existing passwd file, and
                    requests that a new password be given if the entered password
                    is the same as the current password.
    
        --not-system-password
    
                    Double-checks the given password against the system password
                    for the user, and requests that a new password be given if
                    the entered password is the same as the system password.  This
                    helps to enforce different passwords for different types of
                    access.
    
        --stdin
                    Read the password directly from standard in rather than
                    prompting for it.  This is useful for writing scripts that
                    automate use of ftpasswd.
    
        --use-cracklib
                    Causes ftpasswd to use Alec Muffet's cracklib routines in
                    order to determine and prevent the use of bad or weak
                    passwords.  The optional path to this option specifies
                    the path to the dictionary files to use -- default path
                    is "/usr/lib/cracklib_dict".  This requires the Perl
                    Crypt::Cracklib module to be installed on your system.
    
        --version
                    Displays the version of ftpasswd.
    
      If used with --group, ftpasswd creates a file in the group(5) format,
      suitable for use with proftpd's AuthGroupFile configuration directive.
    
      By default, using --group will write output to "./ftpd.group".
    
      Options:
    
        --enable-group-passwd
    
                    Prompt for a group password.  This is disabled by default,
                    as group passwords are not usually a good idea at all.
    
        --file      Write output to specified file, rather than "./ftpd.group"
    
        -F          If the file be used already exists, delete it and write a new
        --force     one.  By default, new entries will be appended to the file.
    
        --gid       Numerical group ID (required)
    
        -h
        --help      Displays this message
    
        -m
        --member    User to be a member of the group.  This argument may be used
                    multiple times to specify the full list of users to be members
                    of this group.
    
        --des       Use the DES algorithm for encrypting passwords.  The default
                    is the MD5 algorithm.
    
        --md5       Use the MD5 algorithm for encrypting passwords.  This is the
                    default.
    
        --name      Name of the group (required).  If the name does not exist in
                    the specified output-file, an entry will be created for them.
                    Otherwise, the given fields will be updated.
    
        --stdin
                    Read the password directly from standard in rather than
                    prompting for it.  This is useful for writing scripts that
                    automate use of ftpasswd.
    
        --use-cracklib
                    Causes ftpasswd to use Alec Muffet's cracklib routines in
                    order to determine and prevent the use of bad or weak
                    passwords.  The optional path to this option specifies
                    the path to the dictionary files to use -- default path
                    is "/usr/lib/cracklib_dict".  This requires the Perl
                    Crypt::Cracklib module to be installed on your system.
    
        --version
                    Displays the version of ftpasswd.
    
      If used with --hash, ftpasswd generates a hash of a password, as would
      appear in an AuthUserFile.  The hash is written to standard out.
      This hash is suitable for use with proftpd's UserPassword directive.
    
      Options:
    
        --des       Use the DES algorithm for encrypting passwords.  The default
                    is the MD5 algorithm.
    
        --md5       Use the MD5 algorithm for encrypting passwords.  This is the
                    default.
    
        --stdin
                    Read the password directly from standard in rather than
                    prompting for it.  This is useful for writing scripts that
                    automate use of ftpasswd.
    
        --use-cracklib
                    Causes ftpasswd to use Alec Muffet's cracklib routines in
                    order to determine and prevent the use of bad or weak
                    passwords.  The optional path to this option specifies
                    the path to the dictionary files to use -- default path
                    is "/usr/lib/cracklib_dict".  This requires the Perl
                    Crypt::Cracklib module to be installed on your system.
    



    Author: $Author: castaglia $
    Last Updated: $Date: 2011/03/03 22:17:29 $


    © Copyright 2000-2011 TJ Saunders
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/utils/ftpwho.html0000644000175000017500000000353011534010517020645 0ustar frankiefrankieManpage of ftpwho

    NAME

    ftpwho - show current process information for each ftp user

    SYNOPSIS

    ftpwho

    DESCRIPTION

    The ftpwho command shows process information for all active proftpd connections, and a count of all connected users off of each server. Proftpd sesssions spawned from inetd are counted seperately from those created by a master proftpd standalone server.

    OPTIONS

    -h, --help
    Display a short usage description, including all available options.
    -p, --path scoreboard-path
    Specify the full path to proftpd's run-time scoreboard files (configured via the ScoreboardPath directive in proftpd.conf). If proftpd's default directory has been changed via this directive, ftpwho must either be recompiled, or this option must be used in order to find proftpd's scoreboard.
    -v, --verbose
    Reports additional information for each connection, such as the remote host and current working directory.

    FILES

    /usr/bin/ftpwho
    /var/run/proftpd-[pid]
    /var/run/proftpd-inetd

    AUTHORS

    ProFTPD is written and maintained by a number of people, full credits can be found on http://www.proftpd.org/credits.html

    SEE ALSO

    inetd(8), ftp(1), proftpd(8), ftpcount(1), ftpshut(8)

    Full documentation on ProFTPD, including configuration and FAQs is available at http://www.proftpd.org/

    Report bugs at http://bugs.proftpd.org
    For help/support, try the ProFTPD mailing lists, detailed on http://www.proftpd.org/lists.html


    proftpd-dfsg-1.3.5~rc3/doc/utils/ftpshut.html0000644000175000017500000000672511534010517021044 0ustar frankiefrankieManpage of ftpshut

    NAME

    ftpshut - shut down all proftpd servers at a given time

    SYNOPSIS

    ftpshut [ -l min ] [ -d min ] time [ warning-message ]

    DESCRIPTION

    The ftpshut command provides an automated shutdown procedure that a superuser can use to automagically disconnect current proftpd connections, and deny new connections. The command creates a control file as /etc/shutmsg to inform proftpd processes about an impending shutdown.

    OPTIONS

    time
    The time at which the ftp servers will be brought down. It may be the word `now', indicating an immediate shutdown, or a future time in one of two formats: +number or HHMM. The first form brings the servers down in number minutes, while the second form indicates an exact time of day, using a 24-hour clock format.

    -l min
    Specifies the number of minutes before shutdown that new ftp access will be disabled. If the -l option is not specified, a default of 10 minutes (or immediately, if less than 10 minutes remains until shutdown) is used.

    -d min
    Specifies the number of minutes before shutdown that existing ftp connections will be disconnected. If the -d option is not specified, a default of 5 minutes (or immediately, if less than 5 minutes remains until shutdown) is used.

    warning-message
    Optionally provide a message which will be sent to new connections (if denied) and existing connections (when disconnected). The message can contain the following magic cookies, which will be replaced as follows before being sent to new or existing connections:
    %s
    time proftpd is being shut down
    %r
    time new connections will be denied
    %d
    time current connections will be dropped
    %C
    current working directory (where applicable)
    %L
    local host name (of virtualhost name)
    %R
    remote host name
    %T
    local time (format Thu Nov 15 17:12:42 1990)
    %U
    username given at login time

    CAVEATS

    Proftpd servers can only be shutdown via ftpshut if a master daemon is running in standalone mode. Servers running in inetd mode will honor the shutdown message file created by ftpshut, however currently running servers may be chroot(2)ed, and unable to read the shutdown message control file.

    It is possible to set an absolute shutdown time which is earlier than the current time. If this is the case, proftpd will not shutdown until the indicated time on the following day.

    FILES

    /usr/sbin/ftpshut
    /etc/shutmsg

    AUTHORS

    ProFTPD is written and maintained by a number of people, full credits can be found on http://www.proftpd.org/credits.html

    SEE ALSO

    inetd(8), ftp(1), proftpd(8), ftpwho(1), ftpcount(1)

    Full documentation on ProFTPD, including configuration and FAQs, is available at http://www.proftpd.org/

    Report bugs at http://bugs.proftpd.org/
    For help/support, try the ProFTPD mailing lists, detailed on http://www.proftpd.org/lists.html


    proftpd-dfsg-1.3.5~rc3/doc/utils/ftpcount.html0000644000175000017500000000336411534010517021205 0ustar frankiefrankie Manpage of ftpcount

    NAME

    ftpcount - show current number of connections for each proftpd server configuration

    SYNOPSIS

    ftpcount

    DESCRIPTION

    The ftpcount command shows the current number of connections per server and virtualhost/anonymous configuration defined in the proftpd.conf file. Connections spawned by inetd are counted seperately from those created by a master proftpd standalone server.

    OPTIONS

    -h, --help
    Display a short usage description, including all available options.
    -p, --path scoreboard-path
    Specify the full path to proftpd's run-time scoreboard files (configured via the ScoreboardPath directive in proftpd.conf). If proftpd's default directory has been changed via this directive, ftpcount must either be recompiled or this option must be used in order to find proftpd's scoreboard.

    FILES

    /usr/bin/ftpcount
    /var/run/proftpd-[pid]
    /var/run/proftpd-inetd

    AUTHORS

    ProFTPD is written and maintained by a number of people, full credits can be found on http://www.proftpd.org/credits.html

    SEE ALSO

    inetd(8), ftp(1), proftpd(8), ftpwho(1), ftpshut(8)

    Full documentation on ProFTPD, including configuration and FAQs is available at http://www.proftpd.org/.

    Report bugs at http://bugs.proftpd.org
    For help/support, try the ProFTPD mailing lists, detailed on http://www.proftpd.org/lists.html


    proftpd-dfsg-1.3.5~rc3/doc/utils/ftpquota.html0000644000175000017500000002623111534011571021205 0ustar frankiefrankie ftpquota: tool for ProFTPD mod_quotatab

    ftpquota: tool for ProFTPD module mod_quotatab



    This ftpquota program is used to create and manage quota tables, for the mod_quotatab module, of type "file".

    The most current version of ftpquota is distributed with the ProFTPD source code, in the contrib/ directory.

    Author

    Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this program.



    Usage

    The following describes the common usage of the ftpquota tool. The options supported are described in more detail later.

    Creating Tables
    To start using mod_quotatab, the two required tables are required. Tables of type "file" have identifying magic headers such that ftpquota is needed to initially create both tables. It is an error to attempt to create a table that already exists:

      # ftpquota --create-table --type=limit
      ftpquota: cannot create existing table
    

    To create the initial limit table:

      ftpquota --create-table --type=limit
    
    To create the initial tally table:
      ftpquota --create-table --type=tally
    
    The population of a tally table file with the tally for users, groups, classes, and all is done automatically by mod_quotatab.

    For both of these operations, the --table-path can be used to create a table in a non-default location.

    Updating Tables
    Now that you have the initial tables created, but blank, you need to add records (to the limit table) for the users, groups, classes, etc on which you, as the administrator, wish to impose quotas.

    To a basic limit record for a user bob using the default quotas (which are all "unlimited" by default):

      ftpquota --add-record --type=limit --name=bob --quota-type=user
    
    Similarly for quotas of type group or class. Note that for quotas of type all, the --name option is not necessary; the all record applies to everyone, regardless of name or group or class membership. If no byte or file limits are specified, the default settings (unlimited numbers of bytes/files) are used.

    It is an error to add a record that already exists. Note, however, that it is possible to have multiple records of the same name, but different quota types. The record to use for a given session is identified by the combination of name and quota type.

    An example of creating a limit record with more complex quotas for a class named "browsers"

      ftpquota --add-record --type=limit --name=browsers --quota-type=class \
        --files-upload=0  --files-download=25 --table-path=/usr/local/etc/ftplimit.tab
    
    or, another way:
      ftpquota --add-record --type=limit --name=browsers --quota-type=class \
        --bytes-upload=0 --bytes-download=2 --units=Gb --table-path=/usr/local/etc/ftplimit.tab
    
    In general, it is a good idea to use either byte quotas or file quotas, but not both, unless you know what you are doing. In these examples, the --table-path option is used to add the record to a limit table in a non-default location.

    Another option available when creating limit records is the --per-session option. By default, quotas are persistent, and apply to the user (or group, class, or everyone) across all sessions. Using this option means the limits will be enforced only for the duration of the client's session, and that the limits will apply only to that client. In other words, using this option for group, class, or all quotas is not a good idea.

    Similarly, for removing records from the limit table (effectively removing quotas from affecting that user/group/class/all) or from the tally table (effectively resetting the quotas to zero for that user/group/class/all), there is the --delete-record option:

      ftpquota --delete-record --type=limit --name=browsers --quota-type=class
    

    In addition to adding and removing records, an administrator may want to simply change the quotas in a given record, either in the limit or tally tables. In this case, use --update-record:

      ftpquota --update-record --type=tally --name=bob --quota-type=user \
        --bytes-download=100 --files-download=1
    
    This example command manually sets user bob's download tally to 100 bytes, 1 file. It is an error to update a record that does not exist.

    There are some administrators who wish to impose quotas on a daily basis, that is, to have a per-day quota. At present, the easiest way to do this is to have a cron job that, once a day, does the following:

      ftpquota --update-record --type=tally --name=name --quota-type=quotatype
    
    This command will "reset" the matching tally record. By default, if no byte or file quotas are set, the default values are used: unlimited if updating a limit record, zero if updating a tally record.

    When editing the tables, ftpquota will obtain read or write locks as necessary. If those tables are being used by a running server, which also performs locking, the script will wait until it is able to obtain a lock. Changing of in-use table information is ideally done while the server is quiescent. This locking is to avoid data synchronization and corruption issues.

    Showing Tables
    Having tables in binary format makes it difficult to easily see what the current records are, to double-check limits or simply to view the current tally. ftpquota thus supports the dumping out of table contents in human-legible form via the --show-records option:

      ftpquota --show-records --type=limit
    
    or, for a tally table not in the location where the scripts expects it to be:
      ftpquota --show-records --type=tally --table-path=/usr/local/etc/ftpd/quota-tally.tab
    
    When viewing tables this way, the --units option can be used to display byte quotas in other units (e.g. Kb, Mb, etc).



    Options

    The following is the output from running ftpquota --help:
    usage: ftpquota [options]
    
     The following options describe the type of operation to be performed:
    
      --add-record         Create a new record with the specified limits.  Any
                           limits left unspecified with have their default
                           values.  This option requires the --name and
                           --quota-type options.
    
      --create-table       Create the table if not present.  Used to initialize
                           a table.  The default limit table path is
                           "./ftpquota.limittab".  The default tally table path is
                           "./ftpquota.tallytab".
    
      --delete-record      Deletes a quota record from the table.  This option
                           requires the --name and --quote-type options.
    
      --show-records       Prints out all of the quota records in the table in
                           a legible format.
    
      --update-record      Updates a quota record with the specified limits.  Any
                           limits left unspecified will be updated with their
                           default value.  This option requires the --name and
                           --quota-type options.
    
     The following option describes the type of table on which to operate:
    
      --type               Specifies a table type to use.  The allowable options
                           are: "limit" or "tally".  This is required.
    
     The following options are used to specify specific quota limits:
    
      --Bu                 Specifies the limit of the number of bytes that may be
      --bytes-upload       uploaded.  Defaults to -1 (unlimited).
    
      --Bd                 Specifies the limit of the number of bytes that may be
      --bytes-download     downloaded.  Defaults to -1 (unlimited).
    
      --Bx                 Specifies the limit of the number of bytes that may be
      --bytes-xfer         transferred.  Note that this total includes uploads,
                           downloads, AND directory listings.  Defaults to
                           -1 (unlimited).
    
      --Fu                 Specifies the limit of the number of files that may be
      --files-upload       uploaded.  Defaults to -1 (unlimited).
    
      --Fd                 Specifies the limit of the number of files that may be
      --files-download     downloaded.  Defaults to -1 (unlimited).
    
      --Fx                 Specifies the limit of the number of files that may be
      --files-xfer         transferred, including uploads and downloads.  Defaults
                           to -1 (unlimited).
    
      -L                   Specifies the type of limit, "hard" or "soft", of
      --limit-type         the bytes limits.  If "hard", any uploaded files that
                           push the bytes used counter past the limit will be
                           automatically deleted; if "soft", those extra bytes
                           will be allowed, but future uploads will be denied.
                           This option only makes sense if --type is "limit".
    
      -N                   Specifies a name for the quota record.  This name
      --name               will be the user/login name, group name, or class
                           name, depending on the quota type.  This option
                           is ignored if the quota type specified is "all".
    
      -P
      --per-session        Specifies that the quota limit is to be applied only
                           to each session, rather than persisting across
                           sessions.  By default, quotas are persistent.
    
      -Q                   Specifies a "quota type" for this record, where
      --quota-type         the type means to which category of FTP users this
                           quota will apply.  The quota type must be one of:
                           "user", "group", "class", or "all".
    
     The following options are miscellaneous:
    
      --help               Displays this message.
    
      --table-path         Specifies the path to a quota table file to use.
    
      --units              Specifies whether to treats bytes as is, in kilobytes,
                           megabytes, or gigabytes.  Allowable options are:
                           "B" or "byte", "Kb" or "kilo", "Mb" or "mega",
                           and "Gb" or "giga".  Defaults to "byte".
    
      --verbose            Toggles more verbose information about the doings of
                           the tool as it works.
    



    Author: $Author: castaglia $
    Last Updated: $Date: 2011/03/03 22:17:29 $


    © Copyright 2000-2011 TJ Saunders
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/utils/ftpdctl.html0000644000175000017500000000367011540256612021010 0ustar frankiefrankieMan page of ftpdctl

    NAME

    ftpdctl - ProFTPD control program

    SYNOPSIS

    ftpdctl [ -hv ] [ -s Unix domain socket ] action action-parameters

    DESCRIPTION

    ftpdctl is the control program for the Professional File Transfer Protocol (FTP) server daemon. The control program is used to control the daemon while it is running, supporting actions like restarting or shutting down the daemon, disabling or enabling specific virtual servers, kicking FTP users, etc.

    The specific actions available via ftpdctl depend on the modules compiled into proftpd. Check the modules documentation for more information on the specific actions supported by the modules.

    OPTIONS

    -h,--help
    Display a short usage description, including all available options.
    -s,--socket
    Specifies an alternate path to be used for communicating with proftpd rather than the default Unix domain socket. The default controls socket is /var/run/proftpd/proftpd.sock
    -v,--verbose
    Display informational messages while communicating with the proftpd daemon.

    AUTHORS

    ProFTPD is written and maintained by a number of people, full credits can be found on http://www.proftpd.org/credits.html

    SEE ALSO

    inetd(8), ftp(1), proftpd(8)

    Full documentation on ProFTPD, including configuration and FAQs, is available at http://www.proftpd.org/

    For help/support, try the ProFTPD mailing lists, detailed on http://www.proftpd.org/lists.html

    Report bugs at http://bugs.proftpd.org/


    proftpd-dfsg-1.3.5~rc3/doc/utils/ftptop.html0000644000175000017500000000504111540255514020656 0ustar frankiefrankieMan page of ftptop

    NAME

    ftptop - display running status on proftpd server connections

    SYNOPSIS

    ftptop

    DESCRIPTION

    The ftptop command displays the current status of FTP sessions in a continuously updating top like format.

    OPTIONS

    -A
    Filter the display to show sessions that are authenticating.
    -a
    Filter the display to hide sessions that are authenticating.
    -D
    Filter the display to show sessions that are downloading.
    -S
    Specify the ServerName for a specific virtual host. If used, ftptop will only show sessions for the given virtual host.
    -d
    Specify the delay, in seconds, between display refreshes. The default is 2 seconds. Only values between 0 and 15 seconds are accepted.
    -f
    Specify the full path to proftpd's run-time scoreboard file (configured via the ScoreboardFile directive in proftpd.conf). If proftpd's default directory has been changed via this directive, ftptop must either be recompiled or this option must be used in order to find proftpd's scoreboard. -h Display a short usage description, including all available options.
    -I
    Filter the display to show sessions that are idle.
    -i
    Filter the display to hide sessions that are idle.
    -U
    Filter the display to show sessions that are uploading.
    -V
    Print out the version of ftptop and quit.

    While ftptop is running, hit the 'q' key to quit. The 't' key toggles between display modes. Currently there are two display modes: normal and transfer speed modes.

    FILES

    /usr/local/bin/ftptop
    /usr/local/var/proftpd.scoreboard

    AUTHORS

    ProFTPD is written and maintained by a number of people, full credits can be found on http://www.proftpd.org/credits.html

    SEE ALSO

    inetd(8), ftp(1), proftpd(8), ftpwho(1), ftpcount(1)

    Full documentation on ProFTPD, including configuration and FAQs, is available at http://www.proftpd.org/

    For help/support, try the ProFTPD mailing lists, detailed on http://www.proftpd.org/lists.html

    Report bugs at http://bugs.proftpd.org/


    proftpd-dfsg-1.3.5~rc3/doc/utils/ftpscrub.html0000644000175000017500000000341411540255514021174 0ustar frankiefrankieMan page of ftpscrub

    NAME

    ftpscrub - scrub the proftpd scoreboard file of stale entries

    SYNOPSIS

    ftpscrub

    DESCRIPTION

    The ftpscrub command provides a way to scrub the scoreboard file on demand, at times which suit the site best. This should be run periodically on sites which run proftpd in inetd mode.

    OPTIONS

    -h,--help
    Display a short usage description, including all available options.
    -f,--file scoreboard-file
    Specify the full path to proftpd's run-time scoreboard file (configured via the ScoreboardFile directive in proftpd.conf ). If proftpd's default directory has been changed via this directive, ftpscrub must either be recompiled, or this option must be used in order to find proftpd's scoreboard.
    -v,--verbose
    Reports additional information while scrubbing the scoreboard.

    FILES

    /usr/local/bin/ftpscrub
    /usr/local/var//proftpd.scoreboard

    AUTHORS

    ProFTPD is written and maintained by a number of people, full credits can be found on http://www.proftpd.org/credits.html

    SEE ALSO

    inetd(8), ftp(1), proftpd(8), ftpwho(1), ftpcount(1)

    Full documentation on ProFTPD, including configuration and FAQs, is available at http://www.proftpd.org/

    For help/support, try the ProFTPD mailing lists, detailed on http://www.proftpd.org/lists.html

    Report bugs at http://bugs.proftpd.org/


    proftpd-dfsg-1.3.5~rc3/doc/faq.html0000644000175000017500000027234407750273270016774 0ustar frankiefrankieProfessional FTP Daemon FAQ

    Professional FTP Daemon FAQ

    Mark Lowes

    Copyrights and Trademarks

    This document may be reproduced in whole or in part, without fee, subject to the following restrictions:

    1. The copyright notice above and this permission notice must be preserved complete on all complete or partial copies

    2. Any translation or derived work must be approved by the author in writing before distribution.

    3. If you distribute this work in part, instructions for obtaining the complete version of this manual must be included, and a means for obtaining a complete version provided.

    4. Small portions may be reproduced as illustrations for reviews or quotes in other works without this permission notice if proper citation is given.

    Exceptions to these rules may be granted for academic purposes: Write to the author and ask. These restrictions are here to protect us as authors, not to restrict you as learners and educators.



    Preface

    This document sets out many of the FAQs related to the installation, functioning and configuration of ProFTPD. It also provides some guidance on policy and security issues.


    Chapter 1. Introduction to ProFTPD

    1. What is ProFTPD?
    2. What is the current version?
    3. Version numbering scheme
    4. Website & documentation
    5. Bug reporting
    6. I've found a security hole
    7. Downloading
    8. Mailing lists
    9. Copyright Issues

    1. What is ProFTPD?

    ProFTPD is a ftp server primarily written for the various unix variants however it will compile under Cygwin giving some support on Windows platforms. It has been designed to be much like Apache in concept taking many of the ideas (configuration format, modular design, etc) from it.

    2. What is the current version?

    Stable: 1.2.9

    Release Candidate: -none-

    3. Version numbering scheme

    At the moment there is a little irrationality in the numbering scheme however it can be summarised as follows

    1.0.x

    This is the previous stable version.

    1.1.x

    Development code

    1.2.0rcx

    Release candidate code, these releases are pretty much bug free and are testing releases prior to the final stable code.

    1.2.x

    This will be the stable cycle with the final .x being the incremental patches to fix bugs discovered after the release version is issued.

    1.3.x

    1.3.x is the planned development tree, work on this has been pushed back while more active development of 1.2.x is undertaken.

    4. Website & documentation

    http://www.proftpd.org/ is the primary source for all information about the project including documentation and security alerts. There are a number of geographic mirror sites, see the mirror pages on www.proftpd.org for more details or try www.<isocode>.proftpd.org (ie www.uk.proftpd.org).

    Helping with documentation

    Writing documentation is time consuming and requires some work but it's not actually difficult. Look through the directive list shipped with the source and package builds of ProFTPD and see what needs work. Check the source code to ensure that the context is correct by grepping through the source code looking for something like

    CHECK_CONF(cmd,CONF_ROOT|CONF_VIRTUAL|CONF_ANON|CONF_GLOBAL)
                  

    to figure out where the directive is valid (server config, <VirtualHost>, <Anonymous>, <Global> for the above example). Once you think you understand what it does, test, play, break (if possible).

    Then either submit a plain text update via the bug reporting system or a patch against the docbook/sgml source (available from CVS on sourceforge (Project: pdd)

    5. Bug reporting

    Bug reports should be made via http://bugs.proftpd.org/ which uses the bugzilla tracking system. Patches should be attached to the appropriate bug and not mailed directly to the mailing lists or any given team member.

    6. I've found a security hole

    Please report all security problems with the code to before releasing the information into the public domain. It would be appreciated if you give the core team a few days to put together a patch and/or new release to address the issue.

    Please adhere to the proceedures and timescales given in the RF Policy document http://www.wiretrip.net/rfp/policy.html, this will give the core development team a chance to get a fix or workaround in place before the problem becomes fully public domain.

    7. Downloading

    There are two main methods of getting the software. Downloading a compressed tarball or rpm (there is also a Debian package available in the main distribution) from proftpd.org or from a mirror site, alternatively if you wish to run the latest bleeding edge code then collecting from the cvs server is the best method.

    Mirror sites

    There is a complete and maintained list of ftp mirror sites available from http://www.proftpd.org/download.html

    CVS

    cvs -d :pserver:anonymous@cvs.proftp.sourceforge.net:/cvsroot/proftp login (Hit Enter when prompted for a password.)

    Then do:

    cvs -d :pserver:anonymous@cvs.proftp.sourceforge.net:/cvsroot/proftp -z3 co proftpd

    To obtain the latest/greatest updates, just hop into the proftpd directory and do: cvs update

    A couple of sites generate downloadable tarballs of the latest CVS code to make obtaining the test code easier.

    8. Mailing lists

    There are a number of mailing lists for ProFTPD

    Announce

    proftpd-announce@proftpd.org

    This is a very low traffic list where only ProFTPD announcements/changes will be announced. Subscribe by sending a message to with "subscribe" in the subject.

    Web interface: https://lists.sourceforge.net/lists/listinfo/proftp-announce

    Users

    proftp-user@proftpd.org

    This is intended to the the user support channel for the software, in most likelihood this is going to be a high traffic list and slightly chatty. Please read the FAQ, the documentation and the list archives before posting a question.

    Subscribe by sending a message to with "subscribe" in the subject.

    Web interface: https://lists.sourceforge.net/lists/listinfo/proftp-user

    Development

    proftpd-devel@proftpd.org

    This list is intended for discussion of development-related issues of ProFTPD, and feature design. It is NOT intended to be a "user help" group.

    Subscribe by sending a message to with "subscribe" in the subject.

    Web interface: https://lists.sourceforge.net/lists/listinfo/proftp-devel

    Archives

    The mailing list archives can be found at:

    Unsubscribing

    Before posting to any of the lists or mailing the list admins please try and remove yourself first. Either by emailing <listname>-request@lists.sourceforge.net with the subject "unsubscribe" or visiting the web interface and unsubscribing from there.

    I've (lost / never had) a password to the interface. Easy, enter the address you are subscribed to the list as into the form and hit the "email me my password" button.

    9. Copyright Issues

    The software is currently distributed under the GNU General Public License (version 2 or later) as published by the Free Software Foundation. Copyright is held by Public Flood Software.


    Chapter 2. Compilation and installing

    1. What platforms will it compile on?
    2. Why not libc5 on Linux?
    3. CVS
    4. How do I get debug output
    5. Patches
    6. Using non-default modules
    7. Microsoft platform support
    8. New features/modules

    1. What platforms will it compile on?

    There have been reports of ProFTPD compiling on all the following platforms (and versions).

    • Linux 2.0.x & 2.2.x (glibc 2.x only) & 2.4.x

    • BSDI 3.1 & 4.0

    • IRIX 6.2, 6.3, 6.4, 6.5

    • Solaris 2.5.1, 2.6, 2.7, 8 (Sparc)

    • AIX 3.2 & 4.2

    • OpenBSD 2.2/2.3

    • FreeBSD 2.2.7

    • Digital UNIX 4.0A

    • DEC OFS/1

    • Cygwin

    2. Why not libc5 on Linux?

    There are several known problems with libc5-based systems, including improperly implemented library routines (vsprintf and vsnprintf are examples). There are known problems with the resolver library. For these reasons and others lib5 is not being supported at all, the latest versions of the major distributions (inc Debian, Redhat and Suse) are all glibc.

    3. CVS

    CVS (Concurrent Versions System), is a version control system which allows multiple developers (scattered across the same room or across the world) to maintain a single codebase and keep a record of all changes to the work.

    The CVS repository for ProFTPD is available for non-developers in read-only mode, however this code is right on the bleeding edge and is not guaranteed to even compile let alone work. Access to CVS is given to allow important security patches out into the wild and to allow users and interested users to test out the latest changes on real systems.

    Nightly tarballs of the current CVS are available on ftp.proftpd.org, these are built at approx 1am UK time.

    Recommended ~/.cvsrc settings

    cvs -z 3
    update -Pd
    diff -u
                

    Where can I get information on cvs?

    CVS is produced by Cyclic Software (http://www.cyclic.com/) and details on CVS can be found on their website. The CVS documentation is clear, detailed and above all heavy when printed. I'd recommend reading it if you're planning on using CVS a lot.

    4. How do I get debug output

    The easiest way is to fire up proftpd manually from the command line with the debug level cranked up.

    /usr/local/sbin/proftpd -d9 -n
                

    This will result in maximal debug output direct to the console. Warning, this can get messy on a busy server, for testing I would suggest copying the config and altering the port the server binds to and then testing.

    5. Patches

    Any patches should be submitted in Universal format, this makes integrating them into the main cvs source a lot easier. When generating a diff against the current cvs source use "cvs diff -uw" to generate the patch.

    cvs diff -u filename > filename.patch
    
      or
    
    cvs diff -u > bigger.patch
                

    Patches that add configuration directives without proper documentation. Will be rejected. New features without documentation are less than useless to the community at large.

    6. Using non-default modules

    Simply configure ProFTPD with

    ./configure --with-modules=mod_module1:mod_module2:mod_module3
    make
    make install
                

    7. Microsoft platform support

    There are no current plans for a direct port to any MS platform.

    8. New features/modules

    While anything new is welcomed it's probably better to at least float the idea first on the devel mailing list to ensure that someone else isn't already hacking on it. Also when submitting the patch or module for inclusion into the ProFTPD source full documentation is needed.


    Chapter 3. Compatibility and Integration

    1. SQL
    2. SSH
    3. sendfile()
    4. IPv6
    5. Filename case sensitivity
    6. FXP

    1. SQL

    ProFTPD has support for authentication and logging via SQL databases using the mod_sql module as supplied in the main distribution.

    2. SSH

    There is a mini-HOWTO at http://www.castaglia.org/proftpd/doc/ detailing how to tunnel ftp connections over ssh.

    3. sendfile()

    sendfile() is a system call which streamlines the copying of data between the disk and the tcp socket. The call copied from the page cache directly rather than requiring a kernel -> user space -> kernel space copy for every read() and write() call. Generally the advantages are only felt on heavily loaded servers. The call is supported in ProFTPD for Linux and FreeBSD.

    Linux 2.0.x

    sendfile is not supported under 2.0.x, this is not an issue when compiling for 2.0.x on a 2.0.x system. However when compiling on a 2.2.x system for use on 2.0.x use the --disable-sendfile flag.

    Runtime detection of sendfile()

    Johnie Ingram (aka netgod)'s: http://www.proftpd.org/proftpd-devel-archive/99-10/msg00073.html

    John Pierce <hawkfan@pyrotechnics.com> http://www.proftpd.org/proftpd-devel-archive/99-10/msg00112.html

    Problems with sendfile

    There appear to be a number of problems with sendfile() particularly with the directives and features which require accurate determination of filesize. Such as the Rate* functions and downloading large files, the best advice at the moment appears to be to disable sendfile by default ( --disable-sendfile ).

    Sendfile() also appears to be the source of a number of file corruption problems.

    4. IPv6

    There is currently no official support for IPv6 within the 1.2.x code tree, however there is an http://www.t17.ds.pwr.wroc.pl/~misiek/ipv6/ and more comprehensive support will probably be developed during the 1.3.x development cycle.

    5. Filename case sensitivity

    ProFTPD is utterly dependant on the underlying OS to handle filename case sensitivity. If the underlying OS is case sensitive then ProFTPD will be, there are currently no plans for a module to handle this.

    6. FXP

    FXP is capable of bouncing data between websites. There have been a number of reports of problems in configuring ProFTPD to function cleanly with this program (http://flashfxp.skuz.net/).

    To support FXP when connecting as a user place "AllowForeignAddress on" in the Global or VirtualHost context.

    To support FXP when connecting as anon "AllowForeignAddress on" must be placed in the Anonymous context.

    The config will happily support "AllowForeignAddress on" in multiple places within the config.


    Chapter 4. Common Running problems

    1. ProFTPD doesn't seem to work.
    2. "inet_create_connection() failed: Operation not permitted".
    3. Unable to bind to port/Address already in use
    4. "(Login failed): Invalid shell"
    5. "Fatal: Socket operation on non-socket"
    6. "Fatal: unable to determine IP address of "hostname:
    7. I'm having problems with FTP clients behind firewalls
    8. Can I run more that one VirtualHost on a single IP?
    9. How do I run ProFTPD from inetd?
    10. Can I use tcp-wrappers with ProFTPD?
    11. Can I run an FTP server on a non-standard port?
    12. Can control upload/download ratios?
    13. Slow logins
    14. Lots of "FTP session closed" messages
    15. How do I see who is connected?
    16. Can I force ProFTPD to listen on only one IP?
    17. "FTP server shut down ... please try again later."
    18. How do I shutdown the server without killing proftpd?
    19. Is is possible to shutdown a single VirtualHost?
    20. Error 421
    21. proftpd doesn't show in the processlist
    22. How do I restart/reload the server?
    23. 503 No PORT command issued
    24. Fatal: unable to determine IP address of
    25. 451 append/restart not permitted, try again
    26. 501 REST not compatible with server configuration
    27. The time being displayed is wrong
    28. Authentication is taking too long
    29. Corrupted files
    30. Can I upgrade ProFTPD without terminating the current sessions?
    31. No such group "nogroup"
    32. Why do I see "unable to set groups: Invalid argument"?
    33. Why do I see error messages like these when I logout?

    1. ProFTPD doesn't seem to work.

    Starting ProFTPD in standalone mode it doesn't show in "ps" It could be many things, possibly something like not running ProFTPD as root (it needs to be run as root initially, but will switch to a non-privileged user). Regardless, ProFTPD logs all errors via the standard syslog mechanism. You need to check your system logs in order to determine what the problem is.

    It doesn't work!

    There are many times when there's a completely random problem which appears to be insoluble. The best place to ask for help is definately the mailing list (proftpd-l) but it's not productive to ask for help without giving enough information for intelligent debugging.

    Have you?

    • Checked your logs

    • Tried the server in debug mode

    • Read the FAQ?

    • Checked the mailing list archive?

    • Are you running the latest version?

    When posting try giving enough information, this might include but not be limited to.

    • OS and server version (proftpd -vv)

    • List of included modules (proftpd -l)

    • Appropriate log extracts

    • Output fom debug mode

    • Configration fragment

    2. "inet_create_connection() failed: Operation not permitted".

    You aren't starting ProFTPD as root, or you have inetd configured to run ProFTPD as a user other than root. The ProFTPD daemon must be started as root in order to bind to tcp ports lower than 1024, or to open your shadow password file when authenticating users. The daemon switches uid/gids to the user and group specified by the User/Group directives during normal operation, so a "ps" will show it running as the user you specified.

    3. Unable to bind to port/Address already in use

    0.0.0.0 is INADDR_ANY, which means to bind to any interface. The "address in use" will normally mean that something has already bound to that address.

    Under linux it is possible to run:

    fuser -n tcp 21
                

    to get the PID of the process currently bound to port ProFTPD is configured to run as.

    The most common cause is that ProFTPD is configured standalone and inetd is still configured for port 21. Comment out the line starting "ftp" in /etc/inetd.conf and restart (killall -HUP inetd or something similar should do the trick) and try again.

    4. "(Login failed): Invalid shell"

    The user attempting to login has been given a shell that is not listed in the system's /etc/shells file. By default, proftpd will require that users logging in have valid shells. Use the RequireValidShell directive to turn off this requirement:

    RequireValidShell off
    	    

    5. "Fatal: Socket operation on non-socket"

    You have ProFTPD configured to run in inetd mode rather than standalone. In this mode, ProFTPD expects that it will be run from the inetd super-server, which implies that stdin/stdout will be sockets instead of terminals. As a result, socket operations will fail and the above error will be printed. If you wish to run ProFTPD from the shell, in standalone mode, you'll need to modify your proftpd.conf configuration file and add or edit the ServerType directive to read:

    ServerType standalone
                

    6. "Fatal: unable to determine IP address of "hostname:

    The hosting machine has a poorly configured hostname setup to the point where the resolver library cannot determine the IP from the name. Solutions include, fixing the DNS for the domain, fixing the hostname, fixing the /etc/hosts file. Which one works for you will largely depend on your OS and exactly what is wrong.

    7. I'm having problems with FTP clients behind firewalls

    The FTP Specification defines that two sockets should be used for all communications. The first runs over port 21 and is the control channel over which all commands and response codes are sent. Whenever data is required to be transfered, for example for a file download, a directory listing etc etc. A second channel is created on demand, this socket can take one of two forms.

    non-Passive

    The server end of the data socket uses port 20. This is nice and easy to work into a firewall configuration.

    Passive

    The port at either end is dynamically allocated. This is virtually impossible to cater for in a firewall configuration given that the port mapping will be different for every data connection.

    The solution is to force the users to configure their clients to use the non-passive mode (ie port 20)

    8. Can I run more that one VirtualHost on a single IP?

    No, or at least not in the HTTP/1.1 manner of virtual hosting. This is an inbuilt limitation of the current FTP RFC., unlike the HTTP/1.1 spec there is no mechanism comparable to the "Host: foo.bar.com" HTTP header for specifying which host the connection is for. Therefore the only method for determining which VirtualHost the connection is destined for is by the destination IP.

    The one exception to this is if you host multiple servers on the same IP but using different ports, however this requires that the connecting client uses a non-standard port and therefore is probably not a good solution for mass hosting.

    Is there anything in the pipeline to fix this?

    There is a draft standard http://search.ietf.org/internet-drafts/draft-ietf-ftpext-mlst-12.txt with the IETF which extends and improves on the FTP specification including support for a HOST command. However given that the IP crunch is coming from websites and not virtual ftp servers this is unlikely to be pushed through any time soon.

    9. How do I run ProFTPD from inetd?

    Find the line in /etc/inetd.conf that looks something like this:

    ftp stream tcp nowait root in.ftpd in.ftpd

    Replace it with:

    ftp stream tcp nowait root in.proftpd in.proftpd

    Then, find your inetd process in the process listing and send it the SIGHUP signal so that it will rehash and reconfigure itself. You may also need to add in.ProFTPD to hosts.allow on your system.

    10. Can I use tcp-wrappers with ProFTPD?

    Yup. Although ProFTPD has built-in IP access control (see the Deny and Allow directives), many admins choose to consolidate IP access control in one place via in.tcpd. Just configure ProFTPD to run from inetd as any other tcp-wrapper wrapped daemon and add the appropriate lines to hosts.allow/deny files.

    If running ProFTPD in standalone mode, mod_wrap can be used to direct the server to use the normal hosts.allow/deny files.

    11. Can I run an FTP server on a non-standard port?

    Yes. Use a <VirtualHost> block with your machine's FQDN (Fully Qualified Domain Name) or IP address, and a Port directive inside the <VirtualHost> block. For example, if your host is named "myhost.mydomain.com" and you want to run an additional FTP server on port 2001, you would:

    ...
    <VirtualHost myhost.mydomain.com>
    Port 2001
    ...
    </VirtualHost>
                

    12. Can control upload/download ratios?

    Yes the mod_ratio module provides for doing just this.

    The ratio directives take four numbers: file ratio, initial file credit, byte ratio, and initial byte credit. Setting either ratio to 0 disables that check.

    The directives are HostRatio (matches FQDN, wildcards allowed), AnonRatio (matches password entered at login), UserRatio (accepts "*" for "any user"), and GroupRatio.

    Ratios on                                    # enable module
    UserRatio ftp 0 0 0 0
    HostRatio master.debian.org 0 0 0 0          # leech access (default)
    GroupRatio proftpd 100 10 5 100000           # 100:1 files, 10 file cred 5:1 bytes, 100k byte cred
    AnonRatio billg@microsoft.com 1 0 1 0        # 1:1 ratio, no credits
    UserRatio * 5 5 5 50000                      # special default case
                  

    This example is for someone who (1) has downloaded 1 file of 82k, (2) has uploaded nothing, (3) has a ratio of 5:1 files and 5:1 bytes, (4) has 4 files and 17k credit remaining, and (5) is now changing directory to /art/nudes/young/carla. The initial credit, not shown, was 5 files and 100k (UserRatio * 5 5 5 100000).

    Version 2.0 and above of this module integrate with mod_sql.

    Limitations of mod_ratio

    It appears that the ratio limits in mod_ratio are only maintained on a per session basis and there is no ongoing tracking of usage.

    13. Slow logins

    This is probably caused by a firewall or DNS timeout. By default ProFTPD will try to do both DNS and ident lookups against the incoming connection. If these are blocked or excessively delayed a slower than normal login will result. To turn off DNS and ident use:

    UseReverseDNS off
    IdentLookups                    off
                

    IdentLookups and tcpwrappers ***

    14. Lots of "FTP session closed" messages

    Oct 7 12:30:48 salvage2 proftpd[8874]: FTP session closed. Oct 7 12:30:48 salvage2 proftpd[8874]: FTP session closed. Oct 7 12:30:48 salvage2 proftpd[8874]: FTP session closed. Oct 7 12:30:48 salvage2 proftpd[8874]: FTP session closed.

    The above log extract is likely to be caused by a local monitoring system or a particularly aggressive DoS attack. Most service monitoring systems try opening the ftp port on the target server to detect whether it is active and running. Most of the time these tests are followed by an immediate "QUIT" or disconnection.

    TCPdump/TCPshow on the server in question should show which machine on your network is is generating these connections.

    15. How do I see who is connected?

    The ftpwho command lists the state of each ftp connection to the server and what it's current activity is. However this does not detail the connection information on a virtual by virtual basis.

    16. Can I force ProFTPD to listen on only one IP?

    Sort, of it's not quite as clean as the socket binding under Apache but the principle works something like this.

    Standalone mode

    To listen on the primary IP of a host use the SocketBindTight directive

    To listen on a interfaces which are not the primary host interface use the SocketBindTight directive, place your server configuration in a <VirtualHost ftp.mydomain.com> block and use "Port 0" for the main host configuration and and "Port 21" inside the VirtualHost block.

    inetd

    There are two approaches possible, the first is to use the patch from Daniel Roesen <droesen@entire-systems.com> (check the mailing list archives).

    The second method is to run ProFTPD from xinetd (http://synack.net/xinetd/), a more advanced replacement of inetd. An entry for this in xinetd.conf would be something like this:

    service ftp
    {
            disable = no
            flags			= REUSE
            socket_type             = stream
            wait                    = no
            user                    = root
            server                  = /usr/sbin/proftpd
            log_on_success          += DURATION USERID
            log_on_failure          += USERID
            nice                    = 10
    	#bind			= [IP to bind to]
    }
                

    17. "FTP server shut down ... please try again later."

    Check for /etc/shutmsg and delete it.

    18. How do I shutdown the server without killing proftpd?

    ftpshut, allows the server to disallow connections with a message without actually taking down the service. The shutdown can be scheduled for a point in the future or right now, existing connections can be allowed to finish, or be terminated now. Re-enabling is done by removing the /etc/shutmsg file.

    19. Is is possible to shutdown a single VirtualHost?

    No, the shutmsg file works at a daemon level not at a virtual host level.

    20. Error 421

    This appears to be a general catch all error code meaning "something nasty has gone wrong".

    • Connection has timed out

    • The DefaultRoot specified doesn't exist

    • The parent server has been killed

    • Check /etc/services

    • Wrong permissions on the DefaultRoot

    You get the idea...

    21. proftpd doesn't show in the processlist

    Two possible reasons, first that it's simply not running, try proftpd -n -d2 to run in debug mode and see what happens. The other is that it's running from inetd and there are no active sessions at the moment.

    22. How do I restart/reload the server?

    This depends on the mode you're running the server in.

    inetd

    Unless you're making a configuration change to inetd itself nothing needs doing. The server reloads the configuration everytime a new connection is made.

    Standalone

    Either stop and start the server completely (a little aggressive for most admins tastes) or send a SIGHUP to the master daemon process.

    23. 503 No PORT command issued

    A bug was introduced in 1.2.0rc2 which prevented the PORT command working properly and therefore breaking the data socket under certain conditions. The bug was documented as bug 240 and has been fixed in CVS. A rc3 release is due before the end of Jan 2001.

    24. Fatal: unable to determine IP address of

    Proftpd was unable to work out what IP is associated with the hostname in the VirtualHost block. Normally caused by a problem with the DNS resolution of the host, check the resolv.conf file and that your chosen nameservers are functional.

    25. 451 append/restart not permitted, try again

    AllowStoreRestart is disabled by default because it will allow any writable file to be corrupted by a malicious user. It is recommended that this option is only used with authenticated users and then only in certain directories.

    26. 501 REST not compatible with server configuration

    As mentioned in the description of the HiddenStor configuration directive, use of that directive is incompatible with the FTP command REST. Either disable use of REST with the AllowRetrieveRestart and AllowStoreRestart directives, or do not use HiddenStor.

    27. The time being displayed is wrong

    The default behaviour for ProFTPD is to display all times relative to GMT. To use local time set "TimesGMT off" in the server section of the config. There is a known issue with Redhat 7, with regard to time handling. http://www.redhat.com/support/errata/rh7-errata-bugfixes.html

    28. Authentication is taking too long

    Make sure that ReverseDNS is disabled, turn off ident lookups. Additionally check the size of your /etc/passwd (or shadow) file, if it is large then the only solution may be to move to another authentication scheme.

    29. Corrupted files

    There appear to be some problems with both the use of sendfile() in ProFTPD and with the implementation within certain operating systems.

    30. Can I upgrade ProFTPD without terminating the current sessions?

    Short answer, no. Longer answer is no, but you can minimise the effects. The cleanest approach on servers which have significant amounts of traffic appears to be to use ftpshut to block new connections and terminate existing ones after a pre-determined time period and then to upgrade and restart. This approach limits the number of downloads which are terminated part way through.

    31. No such group "nogroup"

    The default ProFTPD configuration file uses the user "nouser" and the group "nogroup", some systems / distributions do not have the group "nogroup" defined. The solution is to either add the group "nogroup" to /etc/groups or to change the "nogroup" entry in the proftpd.conf to a group which does exist.

    32. Why do I see "unable to set groups: Invalid argument"?

    The setting of the group privileges for a process uses the setgroups(2) system call. This call will fail with the above error message for one of two reasons: there is a negative GID value for one of the groups, or the maximum number of groups for a single user has been exceeded.

    Ideally, all IDs, both UID and GID, will be positive. Unfortunately, it is common on many systems to use -1 or -2, especially for such users as 'nobody', or group 'nogroup'. Use of these values uses C's treatment of data types to make the actual numeric value very high; some functions, like setgroups(), do not like this, though. In general, always use positive ID numbers.

    The other limitation is the number of supplemental groups for a user (eg non-primary groups, the ones configured in /etc/group). The maximum number of supplemental groups to which a user may belong is defined by the operating system constant NGROUPS_MAX. On some operating systems, such as Solaris, this limitation may be tunable.

    Some other applications may not encounter this error if they use the initgroups(3) function, which reads the /etc/group file for a user's supplemental group memberships, and sets those groups. This function, however, silently ignores any supplemental groups for user greater than NGROUPS_MAX, unlike setgroups(2), which complains.

    If this is the cause of your error message, any solution will most likely involve reducing the number of groups your users are members of, or tuning the NGROUPS_MAX value, if your operating system allows it.

    33. Why do I see error messages like these when I logout?

                PAM(exit): Permission denied
                open_module: stat(/usr/lib/security/pam_unix.so.1) failed: No such file or directory
                load_modules: can not open module /usr/lib/security/pam_unix.so.1
                PAM(exit): Dlopen failure.
              

    These messages appear when the DefaultRoot configuration directive is in effect. This directive causes a user to be confined using the chroot(2) system call. This call, however, affects other system utilities, such as PAM. In this case, PAM's configuration is causing the PAM library to attempt to open PAM modules using a path that is no longer valid, thus the errors. This happens on logout because the chroot has already happened by that point; on login, the PAM modules are successfully found and loaded before the chroot, so no errors. These are merely cosmetic reporting errors, and do not really affect the functionality or security of the server.


    Chapter 5. Configuration problems

    1. How do I add another anonymous login or guest account?
    2. How do I ftp as root?
    3. How do I provide a secure upload facility?
    4. How can I stop my users from using their space as a warez repository
    5. Can I rotate files out of an upload directory after upload?
    6. How can I hide a directory from anonymous clients.
    7. File/Directory hiding isn't working for me!
    8. I want to prevent users from accessing a hidden directory
    9. How do I setup a virtual FTP server?
    10. I only want to allow anonymous access to a virtual server.
    11. How does <Limit LOGIN> work, and where should I use it?
    12. How can I limit users to a particular directory tree?
    13. How do I create individual anonymous FTP sites for my users?
    14. I want to support normal login and Anonymous under a particular user
    15. Why doesn't Anonymous ftp work (550 login incorrect)?
    16. Bandwidth control
    17. CHMOD isn't working
    18. How can I limit the size of uploaded files?
    19. Can I disable Anonymous logins?
    20. Limiting the connections per loginID
    21. How do I configure proftpd to allow transfer resumption (for downloads and uploads)?
    22. When should the Bind directive be used?

    Problems encountered in trying to make the server behave exactly as required after compilation and installation are complete and the server is running.

    1. How do I add another anonymous login or guest account?

    You should look in the sample-configurations/ directory from your distribution tarball. Basically, you'll need to create another user on your system for the guest/anonymous ftp login. For security reasons, it's very important that you make sure the user account either has a password or has an "unmatchable" password. The root directory of the guest/anonymous account doesn't have to be the user's directory, but it makes sense to do so. After you have created the account, put something like the following in your /etc/proftpd.conf file (assuming the new user/group name is private/private):

    <Anonymous ~private>
    AnonRequirePassword off
    User private
    Group private
    RequireValidShell off
    <Directory *>
    <Limit WRITE>
    DenyAll
    </Limit>
    </Directory>
    </Anonymous>
              

    This will allow ftp clients to login to your site with the username "private" and their e-mail address as a password. You can change the AnonRequirePassword directive to "on" if you want clients to be forced to transmit the correct password for the "private" account. This sample configuration allows clients to change into, list and read all directories, but denies write access of any kind.

    2. How do I ftp as root?

    First off this is a bad idea ftping as root is insecure, there are better more secure ways of shifting files as root.

    To enable root ftp ensure that the directive "RootLogin on" is included in your configuration.

    3. How do I provide a secure upload facility?

    The following snippet from a sample configuration file illustrates how to protect an "upload" directory in such a fashion (which is a very good idea if you don't want people using your site for "warez"):

    <Anonymous /home/ftp>
      # All files uploaded are set to username.usergroup ownership
      User username
      Group usergroup
      UserAlias ftp username
      AuthAliasOnly on
      RequireValidShell off
    
      <Directory pub/incoming/>
         <Limit STOR CWD>
            AllowAll
         </Limit>
         <Limit READ RMD DELE MKD>
            DenyAll
         </Limit>
      </Directory>
    </Anonymous>
              

    This denies all write operations to the anonymous root directory and sub-directories, except "incoming/" where the permissions are reversed and the client can store but not read. If you used <Limit WRITE> instead of <Limit STOR> on <Directory incoming>, ftp clients would be allowed to perform all write operations to the sub-dir, including deleting, renaming and creating directories.

    4. How can I stop my users from using their space as a warez repository

    The above fragment will control anonymous users however if a local user with a full account with up and download capability is abusing their space then the technical measures which can be taken are limited. Applying a sane system quota is a good start, using the mod_quota and mod_ratio modules may control the rates of upload/download making it less useful as a warez repository. In the end it comes down to system monitoring and good site AUP's and enforcement.

    5. Can I rotate files out of an upload directory after upload?

    Yes. You'll need to write a script which either checks the contents of the directory regularly and moves once it's detected no size change in a file for xyz seconds. Or a script which monitors an upload log. There is no automatic method for doing this.

    6. How can I hide a directory from anonymous clients.

    Use the HideUser or HideGroup directive in combination with the proper user/group ownership on the directive. For example, if you have the follow directory in your anonymous ftp directory tree:

    drwxrwxr-x 3 ftp staff 6144 Apr 21 16:40 private
              

    You can use a directive such as "HideGroup staff" to hide the private directory from a directory listing. For example:

    <Anonymous ~ftp>
    ...
    <Directory Private>
    HideGroup staff
    </Directory>
    ...
    </Anonymous>
              

    7. File/Directory hiding isn't working for me!

    You need to make sure that the group you are hiding isn't the anonymous ftp user's primary group, or HideGroup won't apply.

    8. I want to prevent users from accessing a hidden directory

    You can either change the permissions on the directory to prevent the anonymous FTP user from accessing it, or if you want to make it appear completely invisible (as though there is no such directory), use the IgnoreHidden directive inside a <Limit> block for one or more commands that you want to completely ignore the hidden directory entries (ignore = act as if the directory entry does not exist).

    9. How do I setup a virtual FTP server?

    You'll need to configure your host to be able to handle multiple IP addresses. This is often called "aliasing", and can generally be configured through an IP alias or dummy interface. You need to read your operating system documentation to figure out how to do this. Once your have the host configured to accept the additional IP address that you wish to offer a virtual FTP server on, use the <VirtualHost> configuration directive to create the virtual server:

    <VirtualHost 10.0.0.1>
    ServerName "My virtual FTP server"
    </VirtualHost>
              

    You can add additional directive blocks into the <VirtualHost> block in order to create anonymous/guest logins and the like which are only available on the virtual host.

    10. I only want to allow anonymous access to a virtual server.

    Use a <Limit LOGIN> block to deny access at the top-level of the virtual host, then use <Limit LOGIN> again in your <Anonymous> block to allow access to the anonymous login. This permits logins to a virtual anonymous server, but denies to everything else. Example:

    <VirtualHost 10.0.0.1>
    ServerName "My virtual FTP server"
    <Limit LOGIN>
    DenyAll
    </Limit>
    <Anonymous /usr/local/private>
    User private
    Group private
    <Limit LOGIN>
    AllowAll
    </Limit>
    ...
    </Anonymous>
    </VirtualHost>
              

    11. How does <Limit LOGIN> work, and where should I use it?

    The <LOGIN> directive is used to control connection or login access to a particular context (the directive block which contains it). When a client initially connects to ProFTPD, the daemon searches the configuration tree for <Limit LOGIN> directives, and attached parameters (such as Allow, Deny, etc). If it determines that there is no possible way for the client to ever be allowed to login, such as a "Deny from" matching the client's source address, without an overriding "Allow from" at a lower level, the client is disconnected without being offered the opportunity to transmit a user and password.

    However, if it is possible for the client to be allowed a login, ProFTPD continues as per normal, allowing the client to login only if the proper <Limit LOGIN> applies. Normally, <Limit> directive blocks are allowed in the server config, <VirtualHost>, <Anonymous> and <Directory> contexts. However, <Limit LOGIN> should not be used in a <Directory> context, as clients do not connect/login to a directory (and thus it is meaningless).

    By way of example, the following configuration snippet illustrates a <Limit LOGIN> deny which will cause any incoming connections from the 10.1.1.x subnet to be immediately disconnected, without a welcome message:

    ...
    <Limit LOGIN>
    Order deny,allow
    Deny from 10.1.1.
    Allow from all
    </Limit>
    ...
              

    Next, an example of a configuration using <Limit LOGIN> that will not immediately disconnect an incoming client, but will return "Login invalid" for all login attempts except anonymous.

    ...
    <Limit LOGIN>
    DenyAll
    </Limit>
    <Anonymous ~ftp>
    ...
    <Limit LOGIN>
    AllowAll
    </Limit>
    ...
              

    12. How can I limit users to a particular directory tree?

    For general open access you can use an <Anonymous> directive context block, possibly in combination with a UserPassword/AnonRequirePassword directive.

    However if you wish to jail an entire group (or groups) of users, you can use the DefaultRoot directive. DefaultRoot lets you specify a root jailed directory (or "~" for the user's home directory), and an optional group-expression argument which can be used to control which groups of users the jail will be applied to. For example:

    ...
    <VirtualHost myhost.mynet.foo>
    DefaultRoot ~
    ...
    </VirtualHost>
              

    This creates a configuration where all users who log into myhost.mynet.foo are jailed into their home directories (cannot chdir into a higher level directory). Alternatively, you could:

    ...
    <VirtualHost myhost.mynet.foo>
    DefaultRoot /u2/public users,!staff
    ...
    </VirtualHost>
              

    In this example, all users who are members of group "users", but not members of group "staff" are jailed into /u2/public. If a user does not meet the group-expression requirements, they login as per normal (not jailed, default directory is their home). You can use multiple DefaultRoot directives to create multiple jails inside the same directive context. If two DefaultRoot directives apply to the same user, ProFTPD arbitrarily chooses one (based on how the configuration file was parsed).

    Security Implications

    The DefaultRoot directive is implemented using the chroot(2) system call. This moves the "/" (or root) directory to a specified point within the file system and jails the user into this sub-tree. However this is not the holy grail of security, a chroot jail can be broken, it is not a trivial matter but it's nowhere near impossible. DefaultRoot should be used as part of a general system of security not the only security measure.

    A more detailed http://www.bpfh.net/simes/computing/chroot-break.html on this subject and on the breaking of chroot jails has been written by Simon Burr

    Non-root server issues

    The chroot() system call will not work under a non-root ftp server process, the call requires root privaliges. Without them it simply doesn't work, there doesn't appear to be any checking in the code of the uid/gid before calling chroot so using DefaultRoot in such a setup will cause the server to fail.

    Symlinks

    Symlinks will not work from within a chrooted area. The reason should be clear from a casual inspection of the nature of the chroot command. It is not possible to have a symbolic link to a directory which can"t be reached beacuse it's outside of the current chroot. Work arounds to allow access to other parts of the file system include exporting the part of the filesystem to be accessed from inside the chroot and mounting via NFS, using hard file links or (on Solaris) using lofs to mount the directory via the loopback.

    mount -Flofs /home/data1 /ftp/data1
    mount -Flofs /home/data2 /ftp/data2
              

    As of the 2.4.x Linux kernel tree it is possible to mount filesystems multiple times and to mount subdirectories of filesystems elsewhere on the filesystem.

    13. How do I create individual anonymous FTP sites for my users?

    There are two methods of accomplishing this (possibly more). First, you can create a directory structure inside your anonymous FTP root directory, creating a single directory for each user and setting ownership/permissions as appropriate. Then, either create a symlink from each user's home directory into the FTP site, or instruct your users on how to access their directory.

    The alternate method (and more versatile) of accomplishing per-user anonymous FTP is to use AnonymousGroup in combination with the DefaultRoot directory. You'll probably want to do this inside a <VirtualHost>, otherwise none of your users will be able to access your system without being stuck inside their per-user FTP site. Additionally, you'll want to use a deferred <Directory> block to carefully limit outside access to each user's site.

    1. Create a new unix group on your system named `anonftp". Please each user who will have per-user anonymous FTP in this group.

    2. Create an `anon-ftp" and `anon-ftp/incoming" directory in each user's home directory.

    3. Modify your /etc/proftpd.conf file to look something like this (you'll probably want to customize this to your needs):

       <VirtualHost my.per-user.virtual.host.address>
       
       # the next line limits all logins to this virtual host, so that only
       anonftp users can connect
       
       <Limit LOGIN>
       DenyGroup !anonftp
       </Limit>
       
       # limit access to each user's anon-ftp directory, we want read-only
       except on incoming
       
       <Directory ~/anon-ftp>
       
       <Limit WRITE>
       DenyAll
       </Limit>
       
       </Directory>
       
       # permit stor access to each user's anon-ftp/incoming directory,
       but deny everything else
       
       <Directory ~/anon-ftp/incoming>
       
       <Limit STOR>
       AllowAll
       </Limit>
       <Limit READ WRITE>
       DenyAll
       </Limit>
       
       </Directory>
       
       # provide a default root for all logins to this virtual host.
       DefaultRoot ~/anon-ftp
       # Finally, force all logins to be anonymous for the anonftp group
       AnonymousGroup anonftp
       
       </VirtualHost>
                    

    14. I want to support normal login and Anonymous under a particular user

    You can use the AuthAliasOnly directive to control how and where real usernames get authenticated (as opposed to aliased names, via the UserAlias directive). Note that it is still impossible to have two identical aliased names login to different anonymous sites; for that you would need <VirtualHost>.

    Example:

    ...
    <Anonymous ~jrluser>
    
     User jrluser
     Group jrluser
     UserAlias ftp jrluser
     UserAlias anonymous jrluser
     AuthAliasOnly on
     ...
     
    </Anonymous>
              

    Here, the <Anonymous> configuration for ~jrluser is set to allow alias authentication only. Thus, if a client attempts to authenticate as "jrluser", the anonymous config will be ignored and the client will be authenticated as if they were a normal user (typically resulting in `jrluser" logging in normally). However, if the client uses the aliased username `ftp" or `anonymous", the anonymous block is applied.

    15. Why doesn't Anonymous ftp work (550 login incorrect)?

    Things to check

    Check the following first:

    • Make sure the user/group you specified inside the <Anonymous> block actually exists. This must be a real user and group, as it is used to control whom the daemon runs as and authenticates as.

    • If RequireValidShell is not specifically turned off, make sure that your "ftp user" (as specified by the User directive inside an <Anonymous> block), has a valid shell listed in /etc/shells. If you do not wish to give the user a valid shell, you can always use "RequireValidShell off" to disable this check.

    • If UseFtpUsers is not specifically turned off, make sure that your "ftp user" is not listed in /etc/ftpusers.

    If all else fails, you should check your syslog. When authentication fails for any reason, ProFTPD uses the syslog mechanism to log the reason for failure; using the AUTH (or AUTHPRIV) facility. If you need further assistance, you can send email, including related syslog entries and your configuration file, to the ProFTPD mailing list mentioned elsewhere in this FAQ.

    16. Bandwidth control

    A new patch providing the TransferRate directive has been provided and is slated for inclusion in 1.2.8, this gives per-connection bandwidth limits with Class support. The limits are more effective against downloads than uploads.

    There is no method to control the total bandwidth a single VirtualHost context can use.

    17. CHMOD isn't working

    AllowChmod is deprecated and has been replaced with the SITE_CHMOD expansion for controlling this functionality.

    18. How can I limit the size of uploaded files?

    As of 1.2.7rc1 there are two new directives MaxRetrieveFileSize and MaxStoreFileSize to control the maximum size of files being transfered to or from the server.

    19. Can I disable Anonymous logins?

    Yes, just remove all the <Anonymous> sections from your configuration file and reload the daemon.

    20. Limiting the connections per loginID

    As of 1.2.7rc1 MaxClientsPerUser has been implemented.

    21. How do I configure proftpd to allow transfer resumption (for downloads and uploads)?

    To allow downloads to be resumed, you need to use the AllowRetrieveRestart configuration directive.

    To allow uploads to be resumed, you need to use both the AllowOverwrite and AllowStoreRestart directives. The reason that both need to be allowed is that a restarted/resumed upload is a form of overwriting the file.

    Also note that using HiddenStor and AllowStoreRestart is incompatible, as mentioned in the documentation for the AllowStoreRestart and HiddenStor directives.

    22. When should the Bind directive be used?

    The Bind directive is used to specify additional interfaces (addresses) for a given server; it is *not* used to configure the main interface for the server. For <VirtualHost> servers, this is not a problem, as the main interface for the server is set in the <VirtualHost> line.

    For the main "default" server, however, the controlling of the main interface is more problematic. There is currently a bug report opened for this issue:

    http://bugs.proftpd.org/show_bug.cgi?id=1253


    Chapter 6. Security

    1. General
    2. Surely running ProFTPD as non-root will help?
    3. How can I control what commands the server accepts?
    4. How can I prevent the server version from being displayed?
    5. I want to show a message prior to login
    6. I want to display a message after login
    7. Can I have a custom welcome response?
    8. External Programs
    9. Why do I see "No certificates found!"?
    10. I can delete files owned by root. Why is this?

    1. General

    As with all software there have been a number of security issues during the life of the project. The most recent information can always be found on http://www.proftpd.org/security.html

    Versions 1.2.0 and above should be considered to be production code and few if any new features will be added to this code branch to maintain stability.

    What about using Stackguard?

    Stackguard (http://immunix.org) is a gcc variant which can protect programs from stack-smashing attacks, programs compiled using Stackguard dies without executing the stack code. While this approach is a good first line of defense against future problems it"s not a complete cure-all. Some of the buffer overflows were found on static variables, which are not protected by stack protection mechanisms.

    2. Surely running ProFTPD as non-root will help?

    Running ProFTPD as a non-root user gives only a marginal security improvement on the normal case and adds some functional problems. Such as not being able to bind to ports 20 or 21, unless it's spawned from inetd.

    ProFTPD takes a middle road in terms of security. It only uses root privileges where required and drops to the UID defined in the config file at all other times. Times when root is required include, binding to ports < 1024, setting resource limits, reading configuration information and some network code.

    For Linux 2.2.x kernel systems there is the POSIX style mod_linuxprivs module which allows very fine grain control over privileges. This is highly recommended for security-conscious admins.

    3. How can I control what commands the server accepts?

    Use a sane Allow/DenyFilter, these directives use regular expressions to control all text sent over the control socket. (If anyone has some good examples please let me know.)

    4. How can I prevent the server version from being displayed?

    Setting SeverIdent to "off" should turn off the information about what type of server is running. To have maximum effect this directive should either be in the Global context or included in every virtual host block and the default block.

    ServerIdent  On "Linux.co.uk server"
    
    ServerIdent  Off
              

    5. I want to show a message prior to login

    Use the DisplayConnect directive to specify a file containing a message to be displayed prior to login.

    DisplayConnect /ftp/ftp.virtualhost/login.msg
              

    6. I want to display a message after login

    Use the DisplayLogin directive, this sends a specified ASCII file to the connected user.

    DisplayLogin       /etc/proftp.msg
              

    7. Can I have a custom welcome response?

    Use the AccessGrantMsg directive, this sends a simple single line message back to the user after a successful authentication. Magic cookies appear to be honoured in this directive.

    AccessGrantMsg "Guest access granted for %u."
              

    Note, this directive has an overriding default and needs to be specified in both VirtualHost and Anonymous blocks.

    8. External Programs

    ProFTPD has been designed to run as a secure ftp server, this means that it tries to keep as much as possible under it's control. An external program is a security risk in itself because it's behaviour is not controllable from within the ftpd code.

    9. Why do I see "No certificates found!"?

    This message is generated by mod_tls, the third-party module that can be used to encrypt both the control and data connections with TLS (Transport Layer Security), the next generation of SSL. Certificates are used to establish the security context for this secure transport.

    Generation of certifications is beyond the scope of this document; however, more information can be found here:

    http://en.tldp.org/HOWTO/SSL-Certificates-HOWTO/

    10. I can delete files owned by root. Why is this?

    ProPTPD follows the UNIX file permission rules when determining the level of access and/or control a user is granted when working with a file. UNIX systems divide the world into three classes when determining the permissions that a user is granted for a particular file:

    • User - the owner of the file

    • Group - a collection of users defined in /etc/group

    • Others - neither the owner, nor a member of the group

    Every file in a Unix filesystem has a permission definition associated with it. At a minimum, the permission established for a file will determine whether a particular user may READ, WRITE, or EXECUTE the file in question. A directory listing will show the permissions associated with a file in the format shown below:

    
  rwx  r-x  r-x
       |    |    |
       |    |    |_____________ Others:  READ/NO WRITE/EXECUTE
       |    |__________________ Group:   READ/NO WRITE/EXECUTE
       |_______________________ User:    READ/WRITE/EXECUTE

    In the sample directory listing shown below, READ/WRITE/EXECUTE privileges are granted to the owner of the directory, and READ/EXECUTE privileges are granted to members of the users group and everyone else. Note the letter "d" at the beginning of each entry, denoting that the entry is actually a directory.

      prince> ls -l /home/ftp
    
      total 8
      drwxr-xr-x    2 andrea   users        4096 May  3 00:40 andrea
      drwxr-xr-x    2 eve      users        4096 May  3 00:40 eve
    
      prince> ls -l /home/ftp/andrea 
    
      total 156
      -rw-r--r--    1 andrea   users       85991 May  3 01:12 bland.txt
      -rwxr-xr-x    1 root     root        65107 May  3 01:12 secret.txt

    The answer to this question is shown in the above example. When describing the permissions associated with a directory, WRITE means that permission is granted to modify the contents of a directory by adding or deleting files. Thus, the user andrea may delete the file secret.txt, even though she cannot modify the file itself.

    Refer to the documentation for the IgnoreHidden and HideNoAccess directives for a method to mitigate this hazard.


    Chapter 7. User Authentication

    1. Why is PAM the default authentication system?
    2. Authentication methods supported
    3. Problems with non-PAM authentication
    4. AuthPAMAuthorative is an unknown directive!
    5. Configuring PAM
    6. pam_sm_open_session errors
    7. Normal users can't login, only anon.
    8. AuthPAMAuthoritative
    9. LDAP
    10. Encrypted passwords
    11. SecureID
    12. One time passwords
    13. RADIUS
    14. Anonymous password checking
    15. Why do I see "PAM(name): Authentication failure", but I can login anyway?

    This section is being re-written due to major structural changes to the SQL module prior to 1.2.0

    1. Why is PAM the default authentication system?

    Security, pure and simple. PAM is the most secure (or securable) of the available authentication systems. Many of the issues and configuration hints for PAM are contained in README.PAM which is bundled with the server source and in the various packaged builds. To use /etc/passwd manual compilation will be required with the configure script being run with the --without-pam flag. Unless the PAM subsystem is properly configured authentication will fail.

    2. Authentication methods supported

  • PAM

  • Standard /etc/passwd lookups

  • NIS

  • Shadow passwords

  • Indvidual passwd/group files for each virtual

  • SQL databases

  • If these don't fit in with your system then writing a custom module or using such as the "ld.so.preload" approach to intercept getpwbynam() system calls works happily with ProFTPD.

    3. Problems with non-PAM authentication

    Generally these problems will be cured by either disabling PAM completely or by ensuring that these directives are set

    PersistentPasswd   off
    AuthPAMAuthoritative off
              

    4. AuthPAMAuthorative is an unknown directive!

    Check the spelling it should be AuthPAMAuthoritative not AuthPAMAuthorative or any other variation.

    5. Configuring PAM

    There is a README.Pam in the top directory of the ProFTPD install directory :

    Redhat Linux

    #%PAM-1.0
    auth       required     /lib/security/pam_listfile.so item=user
    sense=deny file=/etc/ftpusers onerr=succeed
    auth       required     /lib/security/pam_pwdb.so shadow nullok
    account    required     /lib/security/pam_pwdb.so
    session    required     /lib/security/pam_pwdb.so
              

    SuSE Linux

    SuSE appears to uses pam_unix rather than pam_pwdb which is the Redhat approach. All references to pam_pwdb should be replaced with "pam_unix" on SuSE systems.

    The following fragment is reported to work fine on SuSE 6.2

    /etc/pam.d/ftpd
    #%PAM-1.0
    
    # Uncomment this to achieve what used to be ftpd -A.
    # auth       required     /lib/security/pam_listfile.so item=user sense=allow file=/etc/ftpchroot onerr=fail
    
    auth     required       /lib/security/pam_listfile.so item=user
    sense=deny file=/etc/ftpusers onerr=succeed
    auth     sufficient     /lib/security/pam_ftp.so
    auth     required       /lib/security/pam_unix.so
    auth     required       /lib/security/pam_shells.so
    account  required       /lib/security/pam_unix.so
    password required       /lib/security/pam_unix.so
    session  required       /lib/security/pam_unix.so
              

    FreeBSD

    FreeBSD does not support PAM session directives. If you remove the following line from the FreeBSD section of README.PAM, PAM should work properly under recent versions of FreeBSD.

     ftp session required    pam_unix.so         try_first_pass
              

    6. pam_sm_open_session errors

    ProFTPD requires PAM version 0.59 or better. pam_sm_open_session is not part of previous versions.

    7. Normal users can't login, only anon.

    Check that the /etc/pam.d/ftp file exists on the system and is configured as detailed in README.PAM

    8. AuthPAMAuthoritative

    Currently AuthPAMAuthoritative defaults on "ON" resulting in login failures if PAM cannot authenticate the user. This breaks the AuthUserFile directive as it never gets a chance to authenticate the user unless the AuthPAMAuthoritative directive is set to "OFF"

    The reasoning behind the current default is to ensure that the system is secure by default requiring that the admin explicitly and knowingly has to disable it. There are discussions underway which may result in the directive flipping to a default of "Off" if AuthUserFile is specified.

    Note: as of the current CVS and the forthcoming pre9 release the default has changed to "Off"

    9. LDAP

    mod_ldap is currently stable; there were a couple bugs that were squashed after release 1.0 of the module. it is still udner development , check the http://horde.net/~jwm/software/mod_ldap/ for more information. There is an example config fragment on the author's site which gives a reasonable idea on how to use this module.

    10. Encrypted passwords

    There are patches which are being merged in at the moment to provide SHA encryption. The plan is to have the server get all user information except passwords via an anonymous bind. The server will then reconnect as a user is logging in and attempt to get the password via an encrypted connection. This should be in the next major release (2.5)

    11. SecureID

    No support yet

    12. One time passwords

    This is possible using either PAM or the Opie modules. The module passes back a challenge which the user puts into a key generator along with their "pass phrase" and it gives them back 5 words which get sent as the password. As long as you do it correctly it will never repeat.

    It requires http://inner.net/opie/ to be installed on the server. There are key gen clients for win95/98, *nix, mac.

    ftp://ftp.urbanrage.com/pub/c/mod_opie.c

    13. RADIUS

    The new mod_radius module provides RADIUS authentication and accounting support to ProFTPD.

    14. Anonymous password checking

    Is it possible to check an offered email address in an anonymous login before allowing access. Simple answer, not a hope in hell, anonymous access is pretty much designed to be freely open without checks and restrictions other than those placed on upload/download from the site. The best that can be hoped for is decent logging and tracking of accesses, and the requesting IP.

    15. Why do I see "PAM(name): Authentication failure", but I can login anyway?

    If the operating system supports PAM (Pluggable Authentication Modules) proftpd will perform PAM authentication by default. However, this authentication is not "authoritative" by default, meaning that a PAM authentication failure will not necessary cause a login to fail. The use of PAM can be configured using the AuthPAM configuration directive; the "authoritativeness" of any PAM checks is controlled via the AuthPAMAuthoritative configuration directive.


    Chapter 8. FAQ Notes

    1. History
    2. Acknowledgements and Thanks

    1. History

    The original text for this document was based on the configuration FAQ on www.proftpd.org. It was taken over in Sept 1999 when the maintainer of the software changed.

    The faq is maintained by a group of people (usually lurking on irc or on proftpd-docs) using CVS and Docbook.

    2. Acknowledgements and Thanks

    Thanks to the developers, anyone who's posted useful information to the mailing lists and those who've mailed me direct.

    This document couldn't have been maintained without the Sgml Tools package and the document layout defined by the Linux HOWTO maintainers.

    Some specific mentions, in no particular order, and I've missed anyone please drop me a line.

    Updates to the SQL section, Michael Grabenstein <mgrabens@popd.isinet.com>
    Matt Mozur, who's been cleaning up some of my mess and generally stuffing patches in my direction.
    TJ Saunders, for the HOWTOs and other docs.

    proftpd-dfsg-1.3.5~rc3/doc/modules/0000755000175000017500000000000012156653653016776 5ustar frankiefrankieproftpd-dfsg-1.3.5~rc3/doc/modules/mod_delay.html0000644000175000017500000002337611153351020021607 0ustar frankiefrankie ProFTPD module mod_delay

    ProFTPD module mod_delay



    The mod_delay module is designed to make a certain type of information leak, known as a "timing attack", harder.

    When proftpd processes the USER and PASS FTP commands from a client, it has to perform checks against configured ACLs, look up user and group information, etc. These checks are not done if the given username is known to not exist for the server, in order to not tie up system resources needlessly. However, this does mean that more work is done when handling "good" users than when handling "bad" users. This difference can be detected in the time it takes for proftpd to send a response to the USER and PASS commands. This means it is possible for an attacker to look for these statistical timing differences, and determine which users are "good" and which are "bad". From there, a determined attacker can focus their attention on the known good usernames. Note that the timings will vary depending on server load, number of users in the user base, type of storage of user data (e.g. LDAP directories, SQL tables, RADIUS servers, flat files, etc).

    The mod_delay module attempts to prevent such timing differences by keeping track of the time taken to process the USER and PASS commands. It does this for the most recent USER and PASS commands. The timing data are stored in the module's DelayTable. If the module detects that proftpd has not taken enough time to handle one of these commands, compared to its past response times, a small delay will be added to the response cycle. The amount of delay is determined by the difference between the current time spent handling the command and the median time spent handling the same command in the past.

    The most current version of mod_delay can be found in the ProFTPD source distribution:

      http://www.proftpd.org/
    

    Thanks

    2004-10-18: Thanks to Michael Renner for testing out various versions of the module as it was developed.

    Directives

    Control Actions


    DelayControlsACLs

    Syntax: DelayControlsACLs actions|"all" "allow"|"deny" "user"|"group" list
    Default: None
    Context: server config
    Module: mod_delay
    Compatibility: 1.3.1rc1 and later

    The DelayControlsACLs directive configures access lists of users or groups who are allowed (or denied) the ability to use the actions implemented by mod_delay. The default behavior is to deny everyone unless an ACL allowing access has been explicitly configured.

    If "allow" is used, then list, a comma-delimited list of users or groups, can use the given actions; all others are denied. If "deny" is used, then the list of users or groups cannot use actions all others are allowed. Multiple DelayControlsACLs directives may be used to configure ACLs for different control actions, and for both users and groups.


    DelayEngine

    Syntax: DelayEngine on|off
    Default: DelayEngine on
    Context: "server config"
    Module: mod_delay
    Compatibility: 1.2.10rc1 and later

    The DelayEngine directive enables or disables the module's runtime delaying calculations. If it is set to off this module does no delaying. Use this directive to disable the module.

    Example:

      <IfModule mod_delay.c>
        DelayEngine off
      </IfModule>
    

    DelayTable

    Syntax: DelayTable path
    Default: DelayTable var/proftpd/proftpd.delay
    Context: "server config"
    Module: mod_delay
    Compatibility: 1.2.10rc1 and later

    The DelayTable directive configures a path to a file that mod_delay uses for storing its timing data. The given path must be an absolute path. It is recommended that this file not be on an NFS mounted partition.

    Note that timing data is kept across daemon stop/starts. When new <VirtualHost>s are added to the configuration, though, mod_delay will detect that it does not have a suitable DelayTable for the new configuration, and will clear all stored data.


    Control Actions


    delay info

    Syntax: ftpdctl delay info
    Purpose: Display data from the DelayTable

    The delay info control action can be used to view the timing data currently stored in the DelayTable file. This can help to determine why the mod_delay module might be adding longer-than-expected delays to the login sequence for FTP sessions.


    delay reset

    Syntax: ftpdctl delay reset
    Purpose: Reset the DelayTable, clearing all data

    The delay reset control action can be used to clear the DelayTable of all timing information, resetting the table. This can be used if the table starts to collect delays that are too long to be useful.


    Usage

    The mod_delay module provides protection against a very specific problem. However, the module may not be appropriate for all situations.

    For some sites, the delay added by mod_delay is not helpful, and in fact can annoy users. To disable mod_delay, simply add the following to your proftpd.conf file:

      <IfModule mod_delay.c>
        DelayEngine off
      </IfModule>
    

    For other sites, malicious users may notice that they can add arbitrarily long delays to all users' sessions by "poisoning" mod_delay's cache of timing information. For example, a malicious client might connect, send a USER command, and then not disconnect for long time. After a few such clients have connected, mod_delay will add a delay for all clients, such that some legitimate clients may time out. In effect, this may look like a sort of denial of service (DoS).

    To guard against the above situation, there are two possible solutions. First, you can disable the mod_delay module entirely (see above); if the timing information leak is not of concern for your FTP site, this is the recommended approach. Second, you can use the mod_ifsession module and its <IfClass> sections so that the mod_delay module applies only to certain DNS names and IP address ranges. For example:

      # Define a class which identifies trusted clients
      <Class trusted>
        From a.b.c.d
        From e.f.g.h
      </Class>
    
      <IfModule mod_delay.c>
        <IfClass trusted>
          DelayEngine off
        </IfClass>
    
        <IfClass !trusted>
          DelayEngine on
        </IfClass>
      </IfModule>
    
    More information on defining classes can be found here.

    Frequently Asked Questions

    Question: My client times out, after a couple of minutes, after sending the USER command. After disabling mod_delay, the login succeeds quickly. Isn't this a bug in mod_delay?
    Answer: No.

    The DelayTable file can, over time, build up a store of long delay values. A series of logins which take a while (e.g. SSL/TLS handshakes over slow network connections) can cause this sort of behavior. You can delete the DelayTable file or use the delay reset ftpdctl action to clear the stored data.

    Question: Shouldn't mod_delay have some sort of maximum delay value, so that it doesn't cause timeouts?
    Answer: No. There is no single value, hardcoded or configurable, that will work well for all sites and achieve mod_delay's purpose at the same time. What seems like a normal delay time for one site will be unacceptably long for another site.


    Installation

    The mod_delay module is compiled by default.



    Author: $Author: castaglia $
    Last Updated: $Date: 2009/03/04 00:57:52 $


    © Copyright 2004-2009 TJ Saunders
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/modules/mod_cap.html0000644000175000017500000002043412066631006021255 0ustar frankiefrankie ProFTPD module mod_cap

    ProFTPD module mod_cap



    Linux capabilities is a project aimed at providing the POSIX.1e security model under Linux. Documentation for this project can be found here:

      ftp://ftp.kernel.org/pub/linux/libs/security/linux-privs
    
    Without going into gory detail, POSIX.1e basically specifies an interface to such goodies as capabilities, capability sets, access control lists, mandatory access control and much, much more. The end result of this security model allows compliant systems and daemons to have very fine-grained control over what operations are allowed by which services on the system.

    The best part of the whole story is that Linux kernels (since 2.1) already have two important facets of the security model in place, namely capabilities and capability sets. Using these features allows a userland program to specifically drop capabilities (which can be thought of as "privileges") which it does not need. Once such capabilities are completely dropped, neither the userland program nor any binary it should spawn will be allowed to perform privileged operations, regardless of whether the program is running as root or not. Essentially, this limits the power of root to only those specific functions that are necessary, with the end effect of making the program much more secure.

    A contributed module has been added in the proftpd distribution, named mod_cap. It can be found in the modules/ directory.

    The libcap library provides the interface between mod_cap and the capability syscalls present in Linux kernels. (Note that this library can be found at www.kernel.org or sourceforge.net/projects/linux-privs).

    When proftpd runs with mod_cap installed, its operation changes slightly:

    • The master proftpd process runs as normal, with full capabilities.
    • The child proftpd processes, the ones that handle FTP sessions, drop all capabilities-except for CAP_NET_BIND_SERVICE (which allows a process to bind to port less than 1024) and CAP_CHOWN (which allows a process to change a file's ownership)-immediately after a client has authenticated.

      Additionally, switching back and forth between root privileges and the authenticated user's privileges is no longer possible.

    Installation instructions for mod_cap can be found here.

    The most current version of mod_cap can be found in the ProFTPD source distribution:

      http://www.proftpd.org/
    

    Directives


    CapabilitiesEngine

    Syntax: CapabilitiesEngine on|off
    Default: on
    Context: server config, <VirtualHost>, <Global>
    Module: mod_cap
    Compatibility: 1.2.8rc2 and later

    The CapabilitesEngine directive enables or disables the module's runtime capabilities engine. If it is set to off this module does no runtime capabilities processing at all. Use this directive to disable the module.


    CapabilitiesRootRevoke

    Syntax: CapabilitiesRootRevoke on|off
    Default: CapabilitiesRootRevoke on
    Context: server config, <VirtualHost>, <Global>
    Module: mod_cap
    Compatibility: 1.3.5rc1 and later

    By default, the mod_cap module will revoke (i.e. drop) root privileges entirely, once the necessary capabilities have been set. Use the CapabilitiesRootRevoke directive to change this default behavior, e.g.:

      CapabilitiesRootRevoke off
    


    CapabilitiesSet

    Syntax: CapabilitiesSet [+|- cap] ...
    Default: None
    Context: server config, <VirtualHost>, <Global>
    Module: mod_cap
    Compatibility: 1.2.8rc2 and later

    The CapabilitiesSet directive is used to manipulate the set of capabilities that mod_cap grants.

    By default, mod_cap removes all but a few capabilities from the session-handling process: CAP_NET_BIND_SERVICE, for binding to ports lower than 1024 (required for active data transfers), and CAP_CHOWN, for allowing a process to change a file's ownership to a different user. The CAP_CHOWN capability is only strictly necessary if the UserOwner configuration directive is in use; if not being used, the CAP_CHOWN capability is best removed. Additionally, CAP_AUDIT_WRITE is retained if the mod_auth_pam module is present, as this capability is needed for some PAM modules such as pam_loginuid.

    To remove a capability, prefix the name with a '-'; to enable a capability, use '+'. This directive supports the following capabilities:

    • CAP_CHOWN
    • CAP_DAC_OVERRIDE (override all directory access controls)
    • CAP_DAC_READ_SEARCH (allow read and search directory access)
    • CAP_FOWNER

    Example:

      <IfModule mod_cap.c>
        CapabilitiesEngine on
        CapabilitiesSet -CAP_CHOWN +CAP_DAC_READ_SEARCH +CAP_FOWNER
      </IfModule>
    


    Installation

    The mod_cap module is automatically included when proftpd is built on a Linux system that supports capabilities; to disable this automatic inclusion, use the --disable-cap configure option.


    FAQ

    Question: Why do I see the following in my system logs?

      warning: `proftpd' uses 32-bit capabilities (legacy support in use)
    
    Answer: This warning is coming from the use of the libcap library. A newer version of the libcap library (called the "libcap2" or "libcap2-dev" package on some Linux distributions) is now available.

    To remove the above warning, you will need to update/install the newer libcap2 or libcap2-dev package on your system, and re-build proftpd (using version 1.3.2rc1 or later) in order to compile and link against the newer libcap library.

    Question: What does the following mean?

      chown() as root failed: Operation not permitted
    
    Answer: The purpose of the mod_cap module is to restrict the capabilities of the all-powerful root user. Thus when mod_cap is in effect, operations like chown() are restricted.

    The message above usually happens when your configuration uses the UserOwner or GroupOwner configuration directives. To enable those directives to function and still use mod_cap, you will need to use a configuration such as:

      <IfModule mod_cap.c>
        # Allow root to use chown(2)
        CapabilitiesSet -CAP_CHOWN
      </IfModule>
    



    Author: $Author: castaglia $
    Last Updated: $Date: 2012/12/26 17:21:10 $


    © Copyright 2000-2012 TJ Saunders
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/modules/mod_auth.html0000644000175000017500000003240112071636112021447 0ustar frankiefrankie ProFTPD module mod_auth

    ProFTPD module mod_auth



    This module is contained in the mod_auth.c file for ProFTPD 1.3.x, and is compiled by default.

    Directives


    AllowChrootSymlinks

    Syntax: AllowChrootSymlinks on|off
    Default: AllowChrootSymlinks on
    Context: server config, <VirtualHost>, <Global>
    Module: mod_auth
    Compatibility: 1.3.5rc1 and later

    The AllowChrootSymlinks directive configures whether proftpd will follow a symlink to the destination directory when performing a chroot(2) call. This applies both to DefaultRoot directives and to <Anonymous> sections.

    Security note: If you permit your users the ability to remove directories which might be FTP users' home directories (or <Anonymous> directories) and create symlinks, then you should use:

      AllowChrootSymlinks off
    
    This includes sites which are hosting providers, i.e. which allow users to run their untrusted webapps (e.g. PHP, Perl, Ruby, Python, etc apps) on the servers.


    CreateHome

    Syntax: CreateHome off|on [mode] [skel path] [dirmode mode]
    Default: None
    Context: server config, <VirtualHost>, <Global>
    Module: mod_auth
    Compatibility: 1.2.8rc2 and later

    The CreateHome directive configures the server to automatically create a user's home directory, if that directory does not exist, during the login process.

    The mode parameter is used to configure the absolute mode of the home directory created. If not specified, the mode will default to 700.

    The optional skel path parameters can be used to configure an /etc/skel-like directory containing account initialization files and directories. The parameter must be the full path to the skeleton directory. The directory must not be world-writeable. Files copied from this directory into the new home directory will have ownership set to the UID and GID of the logging-in user. Note that sockets and FIFOs in the skeleton directory will not be copied; any setuid or setgid bits on files will be removed from the copied files in the target home directory.

    The optional dirmode parameter can be used to specify the mode for intermediate directories that may need to be created in order to create the target home directory. By default, the mode for such intermediate directories will be 711. Note: using a mode that does not include the execute bit to be enabled can cause havoc. You have been warned.

    Examples:

      # Use the CreateHome default settings
      CreateHome on
    
      # Specify a skeleton directory
      CreateHome on skel /etc/ftpd/skel
    
      # No skeleton, but make sure that intermediate directories have 755
      # permissions.
      CreateHome on dirmode 755
    
      # Skeleton directory, with 700 intermediate directories
      CreateHome on skel /etc/ftpd/skel dirmode 700
    

    A fuller description of the CreateHome directive and its uses, with more examples, can be read here.


    DefaultRoot

    Syntax: DefaultRoot path [group-expression]
    Default: None
    Context: server config, <VirtualHost>, <Global>
    Module: mod_auth
    Compatibility: 1.2.0rc1

    The DefaultRoot directive is used to chroot() the session process for the connecting client. A fuller explanation can be found in the Chroot howto.


    MaxLoginAttempts

    Syntax: MaxLoginAttempts count
    Default: 3
    Context: server config, <VirtualHost>, <Global>
    Module: mod_auth
    Compatibility: 0.99.0 and later

    The MaxLoginAttempts directive configures the maximum number of times a client may attempt to authenticate to the server on the same TCP connection. After the number of attempts exceeds the configured count, the client is disconnected and an appropriate message is logged.


    RewriteHome

    Syntax: RewriteHome on|off
    Default: None
    Context: server config, <VirtualHost>, <Global> Module: mod_auth
    Compatibility: 1.3.3rc1 and later

    The RewriteHome directive can be used to support rewriting the home directory for a user, based on regular expression rules. One such use case is where some portion of the home directory is retrieved e.g. from an LDAP directory, but you need to apply some custom prefix to the LDAP attribute. Note that this feature requires that the mod_rewrite module also be present in your proftpd daemon.

    To enable this feature, first you need to add the following to your proftpd.conf:

      RewriteHome on
    
    Next, you need to configure the mod_rewrite rules for rewriting your home directory; this feature depends on the mod_rewrite module for the rewriting. The pseudo-command used by mod_rewrite for rewriting home directories is "REWRITE_HOME". Thus would you use:
      <IfModule mod_rewrite.c>
        RewriteEngine on
        RewrlteLog /path/to/rewrite.log
    
        RewriteCondition %m REWRITE_HOME
        RewriteRule (.*) /my/new/prefix$1
     </IfModule>
    


    RootRevoke

    Syntax: RootRevoke on|off|UseNonCompliantActiveTransfers
    Default: None
    Context: server config, <VirtualHost>, <Global>, <Anonymous>
    Module: mod_auth
    Compatibility: 1.2.9rc1 and later

    The RootRevoke directive causes all root privileges to be dropped once a user is authenticated. This will also cause active data transfers (e.g. via the PORT/EPRT FTP commands) to be disabled if the server is listening on a port less than 1024. Note that this only affects active data transfers; passive transfers will not be blocked.

    The reason for rejecting active data transfers in these cases is because of a requirement in RFC 959 (which defines the File Transfer Protocol) that for active data transfers, the data connection must have a source port of L-1, where L is the control connection port (see RFC 959, Section 3.2 "Establishing Data Connections"). Thus if the FTP server listens on port 21, then a client requesting an active data transfer from that server will have a data connection whose source port (on the server) is port 20 (L = 21, L-1 = 20).

    Even though passive data transfers are highly preferable, many FTP clients may still require/expect to be able to do an active data transfer. One question, though, is how many FTP clients actually check that the source port of the active data transfer connection is actually L-1. Or how many networking appliances along the way (i.e. firewalls, NATs, routers, etc) enforce this restriction as well.

    If not for that requirement, then with "RootRevoke on" in the proftpd.conf, proftpd would not be required to use root privileges for binding to a privileged port like port 20.

    Thus the RootRevoke directive also accepts (as of proftpd-1.3.5rc1) a parameter of "UseNonCompliantActiveTransfers", e.g.:

      # Drop root privs, but allow active data tranfers (only use a non-standard
      # source port for the active data connection).
      RootRevoke UseNonCompliantActiveTranfers
    
    With this configuration, proftpd will drop root privileges, but would not reject PORT/EPRT commands at all. Instead, the active data transfers would be allowed as per normal, except that proftpd would not try to bind to the L-1 port for those active transfers.

    This RootRevoke parameter is valuable because it helps in getting proftpd to drop root privileges for sessions more often, which is a far more secure configuration. Exploits such as the "Roaring Beast" attack would not be possible in a session where root privileges have been dropped completely.


    TimeoutLogin

    Syntax: TimeoutLogin seconds
    Default: 300 seconds
    Context: server config, <VirtualHost>, <Global>
    Module: mod_auth
    Compatibility: 0.99.0 and later

    The TimeoutLogin directive configures the maximum number of seconds a client is allowed to spend authenticating, i.e. from the time when the client connects to the time when the client has successfully authenticated. The login timer is not reset when a client transmits data, and is only removed once a client has transmitted an acceptable combination of USER/PASS commands. The maximum allowed seconds value is 65535 (108 minutes).

    See also: TimeoutIdle, TimeoutNoTransfer, TimeoutStalled


    TimeoutSession

    Syntax: TimeoutSessions seconds
    Default: None
    Context: server config, <VirtualHost>, <Global>, <Anonymous>
    Module: mod_auth
    Compatibility: 1.2.6rc1 and later

    The TimeoutSession directive sets the maximum number of seconds a control connection between the proftpd server and client can exist, after the client has successfully authenticated. If the seconds argument is set to zero, sessions are allowed to last indefinitely; this is the default. There is no maxium value for the seconds parameter.


    UserPassword

    Syntax: UserPassword user encrypted-password
    Default: None
    Context: server config, <VirtualHost>, <Global>, <Anonymous>
    Module: mod_auth
    Compatibility: 0.99.0pl5 and later

    The UserPassword directive creates a password for a particular user; this configured password will override the user's normal password in /etc/passwd (or whichever auth module handles that user). Note that the user configured is a real user, and not a UserAlias.

    The encrypted-password parameter is a string which has been passed through the standard Unix crypt(3) function. Do not use a cleartext password. To obtain this encrypted-password value, you can use the ftpasswd script's --hash option, e.g.:

      # ftpasswd --hash
    
      Password: 
      Re-type password: 
    
      ftpasswd: $1$EsnXxyD6$tsO2YwTAT/Tl5u1NYPHIw1
    

    Example configuration:

      # Override user bob's password with a hash version of "password"
      UserPassword bob $1$EsnXxyD6$tsO2YwTAT/Tl5u1NYPHIw1
    


    Installation

    The mod_auth module is compiled by default.



    Author: $Author: castaglia $
    Last Updated: $Date: 2013/01/04 20:32:10 $


    © Copyright 2002-2013
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/modules/mod_site.html0000644000175000017500000000214311530272062021451 0ustar frankiefrankie ProFTPD module mod_site

    ProFTPD module mod_site



    This module is contained in the mod_site.c file for ProFTPD 1.3.x, and is compiled by default.


    Installation

    The mod_site module is compiled by default.


    Usage

    Example configurations:

      # Block use of the SITE CHMOD command for changing file permissions
      <Limit SITE_CHMOD>
        DenyAll
      </Limit>
    
      # Block use of the SITE CHGRP command for changing group ownership
      <Limit SITE_CHGRP>
        DenyAll
      </Limit>
    



    Author: $Author: castaglia $
    Last Updated: $Date: 2011/02/20 20:06:10 $


    © Copyright 2002-2011
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/modules/index.html0000644000175000017500000001115612111475722020765 0ustar frankiefrankie ProFTPD Core Module Documentation

    ProFTPD Core Module Documentation


    The following is a collection of HTML documentation for modules and tools in the modules/ directory of the ProFTPD source distribution.

      The mod_auth module
      Handles the login process/interaction with connecting clients

      The mod_auth_file module
      Handles authentication using AuthUserFile and AuthGroupFile

      The mod_auth_pam module
      Provides additional authentication checks via PAM

      The mod_auth_unix module
      Handles authentication using the system files, e.g. /etc/passwd and /etc/group

      The mod_cap module
      Adds additional privilege restrictions based on Linux capabilities and the libcap library

      The mod_core module
      Handles the core configuration directives and FTP commands

      The mod_ctrls module
      Implements the configuration and handling of control actions; see the Controls documentation for more details

      The mod_delay module
      Helps mitigate timing-based information leaks by automatically adding tuned delays to the login process

      The mod_dso module
      Handles the configuration of DSO modules

      The mod_facl module
      Implements POSIX ACL support

      The mod_facts module
      Handles the MFF, MFMT, MLSD and MLST FTP commands

      The mod_ident module
      Handles the IdentLookups configuration directive and IDENTD protocol lookups

      The mod_lang module
      Provides UTF8 and localised response string support, and handles the LANG FTP command

      The mod_log module
      Handles logging via syslog and directly to log files

      The mod_ls module
      Handles directory listings via the LIST, NLST, and STAT FTP commands

      The mod_memcache module
      Handles memcache configuration

      The mod_rlimit module
      Handles resource limits

      The mod_site module
      Handles basic FTP SITE commands: SITE CHGRP, SITE CHMOD, and SITE HELP

      The mod_xfer module
      Handles FTP uploads and downloads via the APPE, RETR, STOR, and STOU FTP commands

    If your question or issue is not covered by any of these pages, please send a request to the ProFTPD documentation list. Directions for subscribing to the docs list, as well as the other ProFTPD mailing lists, are at:

      http://www.proftpd.org/lists.html
    
    If you are looking to see if ProFTPD supports a particular feature, the first place to look as the complete list of configuration directives:
      http://www.proftpd.org/docs/directives/linked/by-name.html
    
    The list may be intimidatingly long, but it is well worth scanning through all of the directives to see everything that ProFTPD is capable of supporting.


    Last Updated: $Date: 2013/02/21 19:56:02 $

    proftpd-dfsg-1.3.5~rc3/doc/modules/mod_xfer.html0000644000175000017500000004457012120140234021452 0ustar frankiefrankie ProFTPD module mod_xfer

    ProFTPD module mod_xfer



    The mod_xfer module handles most of the FTP commands related to file transfers.

    Directives


    AllowOverwrite

    Syntax: AllowOverwrite on|off
    Default: AllowOverwrite off
    Context: server config, <VirtualHost>, <Global>, <Anonymous>, <Directory>, .ftpaccess
    Module: mod_xfer
    Compatibility: 0.99.0 and later

    The AllowOverwrite directive permits newly transfered files to overwrite existing files. By default, FTP clients cannot overwrite existing files.


    AllowRetrieveRestart

    Syntax: AllowRetrieveRestart on|off
    Default: AllowRetrieveRestart on
    Context: server config, <VirtualHost>, <Global>, <Anonymous>, <Directory>, .ftpaccess
    Module: mod_xfer
    Compatibility: 0.99.0 and later

    The AllowRetrieveRestart directive permits (or denies) clients from performing "restart" download (retrieve) file transfers via the FTP REST command. By default, restarted downloads are allowed, so that clients may resume interrupted file transfers at a later time without losing previously collected data.

    See also: AllowStoreRestart


    AllowStoreRestart

    Syntax: AllowStoreRestart on|off
    Default: AllowStoreRestart on
    Context: server config, <VirtualHost>, <Global>, <Anonymous>, <Directory>, .ftpaccess
    Module: mod_xfer
    Compatibility: 0.99.0 and later

    The AllowStoreRestart directive permits (or denies) clients from "restarting" interrupted upload (store) transfers. By default restarting (via the FTP REST command) is not permitted when uploading files to the server. Care should be taken to disallow anonymous FTP "incoming" transfers to be restarted, as this will allow clients to corrupt or increase the size of previously stored files (even if not their own).

    The FTP REST command is automatically blocked when HiddenStores is enabled, with the server returning a 501 error code to the client.

    See also: AllowRetrieveRestart, DeleteAbortedStore, HiddenStores


    DeleteAbortedStores

    Syntax: DeleteAbortedStores on|off
    Default: DeleteAbortedStores off
    Context: server config, <VirtualHost>, <Global>, <Anonymous>, <Directory>, .ftpaccess
    Module: mod_xfer
    Compatibility: 1.2.0rc2 and later

    The DeleteAbortedStores directive controls whether ProFTPD deletes partially uploaded files if the transfer is stopped via the FTP ABOR command (as opposed to a connection failure). By default, DeleteAbortedStores is off; however when HiddenStores is enabled, then DeleteAbortedStores is automatically enabled as well.

    See also: HiddenStores


    HiddenStores

    Syntax: HiddenStores on|off|prefix [suffix]
    Default: HiddenStores off
    Context: server config, <VirtualHost>, <Global>, <Anonymous>, <Directory>
    Module: mod_xfer
    Compatibility: 1.2.7rc1 and later

    The HiddenStores directive enables two-step file uploads: files are uploaded as ".in.filename." and once the upload is complete, renamed to just filename. This provides a degree of atomicity and helps prevent 1) incomplete uploads and 2) files being used while they are still being uploaded. When HiddenStores is enabled, then DeleteAbortedStores is automatically enabled as well.

    Note that if the temporary file name is already in use (e.g., a server crash during upload), it will prevent the file from being uploaded.

    The FTP REST command is automatically blocked when HiddenStores is enabled, with the server returning a 501 error code to the client.

    In proftpd-1.3.3rc2 and later, the ".in." prefix can be customised via the HiddenStores directive, e.g.:

      # Use a different prefix for HiddenStores
      HiddenStores filepart-
    

    In proftpd-1.3.5rc2 and later, the "." suffix can be customised using the HiddenStores directive as well, e.g.:

      # Use a different prefix and suffix for HiddenStores
      HiddenStores incoming- .lock
    
    You can also use this capability to configure no prefix, and just a suffix:
      # Use an empty string as the prefix, and a suffix of ".filepart".
      HiddenStores "" ".filepart"
    
    Note that in order to specify the suffix, you must specify a prefix as well.

    Discussion
    When would you want or need to specify different prefix and suffix values for HiddenStores? You might need this when, for example, your proftpd writes files to an NFS-mounted filesystem. Another machine mounts that same filesystem remotely using a CIFS client (e.g. a NetApp machine). The trailing "." suffix causes the CIFS client to list the temporary filenames different (e.g. in a Windows 8.3 file format style): "in.test." becomes "INTES~1". This view confuses users/admins.

    By changing the default HiddenStores suffix, then, that modified CIFS client filename view can be avoided.

    See also: AllowStoreRestart, DeleteAbortedStores


    MaxRetrieveFileSize

    Syntax: MaxRetrieveFileSize [number|"*" units ["user"|"group"|"class" expression]]
    Default: None
    Context: server config, <VirtualHost>, <Global>, <Anonymous>, <Directory>, .ftpaccess
    Module: mod_xfer
    Compatibility: 1.2.7rc1 and later

    The MaxRetrieveFileSize directive sets a maximum limit on the size of a single file downloaded from proftpd. If the requested file size is larger than than the configured maximum limit, the data transfer will be rejected.

    A single "*" argument configures unlimited file sizes, and is used primarily to override any inherited restrictions from higher-level configuration sections. The given number is the number of bytes for the limit, and is followed by a units specifier of (case-insensitive) "Gb" (Gigabytes), "Mb" (Megabytes), "Kb" (Kilobytes), or "B" (bytes). The given number of bytes is multiplied by the appropriate factor.

    The optional parameters are used to restrict the file size limits only to specific users. If the "user" restriction is given, then expression is a user-expression specifying to which users the rule applies. Similarly for the "group" restriction. For the "class" restriction, the expression is simply the name of connection class for whom the rule will apply. If no matching user, group, or class expression (in that order) is found for the current user, then a limit with no expression (i.e. no "user", "group", or "class" identifier) is applied.

    Examples:

      # Restrict downloads to only 1 gigabyte
      MaxRetrieveFileSize 1 Gb
    
      # Restrict downloads for user fred, but allow unlimited download size for
      # everyone else
      MaxRetrieveFileSize 50 Kb user fred
      MaxRetrieveFileSize *
    

    See also: MaxStoreFileSize


    MaxStoreFileSize

    Syntax: MaxStoreFileSize [number|"*" units ["user"|"group"|"class" expression]]
    Default: None
    Context: server config, <VirtualHost>, <Global>, <Anonymous>, <Directory>, .ftpaccess
    Module: mod_xfer
    Compatibility: 1.2.7rc1 and later

    The MaxStoreFileSize directive sets a maximum limit on the size of a single file uploaded to proftpd. When the configured maximum limit is reached, the data transfer will be aborted.

    A single "*" argument configures unlimited file sizes, and is used primarily to override any inherited restrictions from higher-level configuration sections. The given number is the number of bytes for the limit, and is followed by a units specifier of (case-insensitive) "Gb" (Gigabytes), "Mb" (Megabytes), "Kb" (Kilobytes), or "B" (bytes). The given number of bytes is multiplied by the appropriate factor.

    The optional parameters are used to restrict the file size limits only to specific users. If the "user" restriction is given, then expression is a user-expression specifying to which users the rule applies. Similarly for the "group" restriction. For the "class" restriction, the expression is simply the name of connection class for whom the rule will apply. If no matching user, group, or class expression (in that order) is found for the current user, then a limit with no expression (i.e. no "user", "group", or "class" identifier) is applied.

    Examples:

      # Restrict upload to only 3 megabytes
      MaxStoreFileSize 3 Mb
    
      # Restrict anonymous uploads to 50k, but allow unlimited upload size for
      # everyone else
      MaxStoreFileSize 50 Kb user anonymous
      MaxStoreFileSize *
    

    NOTE: In FTP uploads, the size of the file being uploaded is not sent to the FTP server first; this means that the FTP server does not know in advance how much data the FTP client is going to send. The FTP server can only count the number of bytes being uploaded, and stop the transfer when a configured limit is reached. This means that MaxStoreFileSize cannot be used to prevent an FTP client from even sending the bytes over the network.

    See also: MaxRetrieveFileSize


    TimeoutNoTransfer

    Syntax: TimeoutNoTransfer seconds
    Default: 300 seconds
    Context: server config, <VirtualHost>, <Global>
    Module: mod_xfer
    Compatibility: 0.99.0 and later

    The TimeoutNoTransfer directive configures the maximum number of seconds a client is allowed to spend connected, after authentication, without issuing a data transfer command which results in a data connection (i.e. sending/receiving a file, or requesting a directory listing). The maximum allowed seconds value is 65535 (108 minutes).

    See also: TimeoutIdle, TimeoutLogin, TimeoutStalled.


    TimeoutStalled

    Syntax: TimeoutStalled seconds
    Default: 3600 seconds
    Context: server config, <VirtualHost>, <Global>
    Module: mod_xfer
    Compatibility: 1.1.6 and later

    The TimeoutStalled directive sets the maximum number of seconds a data connection between proftpd and a client can exist but have no actual data transferred (i.e. "stalled"). If the seconds parameter is set to zero, data transfers are allowed to stall indefinitely; note that this is not a recommended configuration. The maximum allowed seconds value is 65535 (108 minutes).


    TransferPriority

    Syntax: TransferPriority cmd-list "low"|"medium"|"high"|number
    Default: None
    Context: server config, <VirtualHost>, <Global>, <Anonymous>
    Module: mod_xfer
    Compatibility: 1.3.2rc1 and later

    The TransferPriority directive is used to tweak the process priority (a la nice(1)) of the session during data transfers. For example, large (or anonymous) data transfers can be configured to have lower priorities, so as to get lower priority than other applications from the kernel.

    The priority parameter can one of the convenient "high", "medium", or "low" keywords, or it can be an explicit number. As per the nice(1) man page, the higher the number, the lower the priority; the highest priority is -20, and the lower priority is 19.

    Examples:

      # All data transfers get a low priority
      TransferPriority APPE,RETR,STOR low
    
    Or maybe only downloads should have lower priorities, but uploads should be fine:
      TransferPriority RETR low
    


    TransferRate

    Syntax: TransferRate cmd-list kbytes-per-sec[:free-bytes]
    Default: None
    Context: server config, <VirtualHost>, <Global>, <Anonymous>, <Directory>, .ftpaccess
    Module: mod_xfer
    Compatibility: 1.2.8rc1 and later

    The TransferRate directive is used to set transfer rate limits on the transfer of data. This directive allows for transfer rates to be set in a wide variety of contexts, on a per-command basis, and for certain subsets of users (via mod_ifsession). Note that these limits only apply to an individual session, and do not apply to the overall transfer rate of the entire daemon.

    The cmd-list parameter may be an comma-separated list of any of the following commands: APPE, RETR, STOR, and STOU.

    The kbytes-per-sec parameter is the actual transfer rate to be applied.

    The free-bytes parameter, if configured, allows that number of bytes to be transferred before the rate limit is applied. This allows for clients transferring small files to be unthrottled, but for larger files, such as MP3s and ISO images, to be throttled.

    Here are some examples:

      # Limit downloads for everyone
      TransferRate RETR 1.5
    
      # Limit uploads (and appends!) to the prolific users in the
      # lotsofuploadfiles.net domain. This presumes that a Class has been defined
      # for that domain, and that that Class has been named "uploaders". Let them
      # upload small files without throttling, though.
    
      <IfClass uploaders>
        TransferRate APPE,STOR 8.0:1024
      </IfClass>
    


    UseSendfile

    Syntax: UseSendfile on|off|len units|percentage
    Default: None
    Context: server config, <VirtualHost>, <Global>, <Anonymous>, <Directory>, .ftpaccess
    Module: mod_xfer
    Compatibility: 1.3.0rc1 and later

    The UseSendfile directive controls use of sendfile(2) functionality, which is an optimization for sending files to clients. Use of sendfile(2) functionality avoids separate read and send kernel operations, and buffer allocations. Read this howto for more details.


    Installation

    The mod_xfermodule is always installed.



    Author: $Author: castaglia $
    Last Updated: $Date: 2013/03/13 18:08:28 $


    © Copyright 2000-2013 The ProFTPD Project
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/modules/mod_core.html0000644000175000017500000016753412073404616021462 0ustar frankiefrankie ProFTPD module mod_core

    ProFTPD module mod_core



    The mod_core module handles most of the core FTP commands.

    Directives


    AllowFilter

    Syntax: AllowFilter pattern [flags]
    Default: None
    Context: "server config", <VirtualHost>, <Global>, <Anonymous>, <Directory>, .ftpaccess
    Module: mod_core
    Compatibility: 1.2.0pre7 and later

    The AllowFilter allows the configuration of a regular expression pattern that must be matched for all command arguments sent to ProFTPD. It is extremely useful in controlling what characters may be sent in a command to ProFTPD, preventing some possible types of attacks against ProFTPD.

    The regular expression pattern is applied against the arguments to the command sent by the client, so care must be taken when creating a proper regex. Commands that fail the regex match result in a "Forbidden command" error being returned to the client. If the pattern contains whitespace, it must be enclosed in quotes.

    The optional flags parameter, if present, modifies how the givenpattern will be evaludated. The supported flags are:

    • nocase|NC (no case)
      This makes the pattern case-insensitive, i.e. there is no difference between 'A-Z' and 'a-z' when pattern is matched against the path

    The example below allows commands which contain alphanumeric characters and whitespace:

      AllowFilter "^[a-zA-Z0-9 ,]*$"
    

    The Filters howto covers filtering in greater detail.

    See also: DenyFilter, PathAllowFilter, PathDenyFilter


    AuthOrder

    Syntax: AuthOrder module-name1 ...
    Default: mod_auth_file.c mod_auth_unix.c
    Context: "server config", <VirtualHost>, <Global>
    Module: mod_core
    Compatibility: 1.2.8rc1 and later

    The AuthOrder directive configures the names of auth modules, and the order in which they will be checked when authenticating a client.

    At least one module name must be given; there is no maximum number of modules that can be listed. The listed module names must the full name of the source file, e.g. "mod_auth_unix.c". To see a full list of module names, use:

      $ proftpd -l
    
    Do not use "mod_auth.c", as that module is the authentication front end module, and is necessary. Also, do not use "mod_auth_pam.c" as the only module, as that module does not provide, by itself, all of the information needed by proftpd for authenticating a client.

    You can make an auth module be "authoritative" by appending an asterisk (*) after the module name. Usually this is done for the "mod_auth_pam.c" module, to ensure that the login fails if the PAM check fails.

    Examples

      # Use only AuthUserFiles when authenticating, and not the system's /etc/passwd
      AuthOrder mod_auth_file.c
    
      # If the user's information is not in LDAP, they're not a user to use
      # this server.
      AuthOrder mod_ldap.c
    
      # Use SQL tables first, then LDAP, for authentication
      AuthOrder mod_sql.c mod_ldap.c
    
      # Use the normal system /etc/passwd and PAM, but make sure that PAM is
      # authoritative about accepting or rejecting the login
      AuthOrder mod_auth_pam.c* mod_auth_unix.c
    


    DebugLevel

    Syntax: DebugLevel level
    Default: DebugLevel 0
    Context: "server config", <VirtualHost>, <Global>
    Module: mod_core
    Compatibility: 1.2.8rc1 and later

    The DebugLevel directive configures the debugging level the server will use when logging. The level parameter must be between 0 and 10. This directive will take precedence over any -d/--debug command-line debugging option used.

    The Logging howto covers logging in greater detail.


    DefaultAddress

    Syntax: DefaultAddress ip-address|dns-name [ip-address|dns-name ...]
    Default: None
    Context: "server config"
    Module: mod_core
    Compatibility: 1.2.7rc1 and later

    The DefaultAddress directive sets the the address to which the main server instance (i.e. the server configured by the "server config" context) will bind. The default behaviour is to select whatever IP address is reported by the operating system as the primary IP address.

    Starting with proftpd-1.3.0rc1, it is possible to use more than one FQDN or IP address.

    Examples

      ServerName "Default FTP Server"
      Port 21
    
      # We want the main server instance to listen on a specific IP
      DefaultAddress 192.168.10.30
    
      # Since 1.3.0rc1 it's also possible to use the following:
      DefaultAddress 192.168.10.30 my.domain.tld
    

    In proftpd-1.3.5rc1, the DefaultAddress directive also handles names which indicates the device-name (or interface-name); the IP address associated with this device/interface will be used. For example, you can use:

      DefaultAddress eth0
    
    Using the device/interface name is useful in cases where the same proftpd.conf file is going to be deployed to multiple different machines, which will have the same device/interface names but different IP addresses.

    See also: <VirtualHost>


    DenyFilter

    Syntax: DenyFilter pattern [flags]
    Default: None
    Context: "server config", <VirtualHost>, <Global>, <Anonymous>,<Directory>, .ftpaccess
    Module: mod_core
    Compatibility: 1.2.0pre7 and later

    The DenyFilter directive, like the AllowFilter directive, specifies a regular expression pattern which must not match any of the command arguments. If the pattern does match, a "Forbidden command" error is returned to the client. This can be especially useful for forbidding certain command argument combinations from ever reaching ProFTPD.

    Note that the PASV SFTP command cannot be blocked using this directive.

    The optional flags parameter, if present, modifies how the givenpattern will be evaludated. The supported flags are:

    • nocase|NC (no case)
      This makes the pattern case-insensitive, i.e. there is no difference between 'A-Z' and 'a-z' when pattern is matched against the path

    For example, to reject commands which contain the percent (%) character, you could use:

      DenyFilter "%"
    

    The Filters howto covers filtering in greater detail.

    See also: AllowFilter, PathAllowFilter, PathDenyFilter


    DisplayChdir

    Syntax: DisplayChdir filename ["on"|"off"]
    Default: None
    Context: "server config", <VirtualHost>, <Global>, <Anonymous>, <Directory>
    Module: mod_core
    Compatibility: 1.3.1rc1 and later

    The DisplayChdir directive configures the name of a text file that will be displayed to the user, every time they change into a directory. If the text file should only be displayed once to the client, the first time they change into the directory (or if proftpd detects that the DisplayChdir file has been changed since it was last displayed to the client), then set the optional second parameter to on or true.

    If the filename is relative, it is looked for in the directory that the user has changed into. Note that for anonymous ftp logins, filename must reside within the chroot()ed directory. If filename cannot be found or accessed, no error occurs and nothing is logged or displayed to the client.

    See the Display files howto for more information on the variables that can be used in a DisplayChdir file.

    See also: DisplayConnect, DisplayQuit


    DisplayConnect

    Syntax: DisplayConnect filename
    Default: None
    Context: "server config", <VirtualHost>, <Global>
    Module: mod_core
    Compatibility: 1.2.0pre2 and later

    The DisplayConnect directive configures the filename of a text file that will be displayed to the user when they initially connect, before they login. The filename can be either relative or absolute. In the case of a relative filename, the file is searched for starting in the home directory of the User as which the server is running. As this can lead confusion, absolute pathnames are highly recommended. If filename cannot be found or accessed, no error occurs and nothing is logged or displayed to the client.

    See the Display files howto for more information on the variables that can be used in a DisplayConnect file.

    See also: DisplayChdir, DisplayQuit


    DisplayQuit

    Syntax: DisplayQuit filename
    Default: None
    Context: "server config", <VirtualHost>, <Global>, <Anonymous>
    Module: mod_core
    Compatibility: 1.2.0pre8 and later

    The DisplayQuit directive configures the filename of a text file that will be displayed to the user when they explicitly end the FTP session using the QUIT command. The filename can be either relative or absolute. In the case of a relative filename, the file is searched for starting in the home directory of the logged-in user. Note: if the session is restricted via chroot, either by the DefaultRoot directive or because its an <Anonymous> login, then filename must reside within the chroot() directory. As this can lead confusion, absolute pathnames are highly recommended. If filename cannot be found or accessed, no error occurs and nothing is logged or displayed to the client.

    See the Display files howto for more information on the variables that can be used in a DisplayQuit file.

    See also: DisplayChdir, DisplayConnect


    GroupOwner

    Syntax: GroupOwner group-name|"~"
    Default: None
    Context: <Anonymous>, <Directory>, .ftpaccess
    Module: mod_core
    Compatibility: 0.99.0 and later

    The GroupOwner directive configures which group (via the group-name parameter) will own all newly created directories and files, within the configuration context that GroupOwner is set. The group ID of group-name cannot be 0.

    Note that GroupOwner cannot be used to override the operating system/filesystem user/group paradigm. If the current user is not a member of the specified group, new files and directories cannot be chown()ed to the GroupOwner group. If this happens, the STOR and MKD/XMKD FTP commands will succeed normally, however the new directory entries will be owned by the current user's default group (and a warning message logged). However, if you also use the UserOwner directive in the same configuration context, this restriction is lifted.

    Some operating systems (e.g. FreeBSD) will use the GID of the parent directory where the new file/directory is created, rather than GID of the logged-in user which creates the new file/directory. To force the GID of the newly created file to be that of the logged-in user, use:

      # The tilde (~) syntax uses the GID of the logged-in user
      GroupOwner ~
    

    See also: UserOwner


    HideGroup

    Syntax: HideGroup group-name
    Default: None
    Context: <Anonymous>, <Directory>
    Module: mod_core
    Compatibility: 0.99.0 and later

    The HideGroup directive configures a <Directory> or <Anonymous> section to hide all directory entries owned by the specified group-name. The group-name can also be ~ (tilde), which is evaluated as the group-name of the primary group of the logged-in user. This can be combined with a prefix ! (exclamation point) character, e.g. "!~", to mean "any group that is not the primary group of the logged-in-user".

    Normally, hidden directories and files cannot be seen via LIST or NLST commands but can be operated on via other FTP commands (CWD, DELE, RETR, etc). This behavior can be modified via the IgnoreHidden directive.

    Examples:

      <Directory path>
        # Hide all files belonging to group 'wheel'
        HideGroup wheel
    
        # Hide all files belonging to the primary group of the logged-in user
        HideGroup ~
    
        # Hide all files that are NOT owned by the primary group of the logged-in
        # user
        HideGroup !~
      </Directory>
    

    See also: HideUser, HideNoAccess, IgnoreHidden


    HideNoAccess

    Syntax: HideNoAccess on|off
    Default: None
    Context: <Anonymous>, <Directory>
    Module: mod_core
    Compatibility: 0.99.0 and later

    The HideNoAccess directive configures a <Directory> or <Anonymous> section to hide all directory entries in a directory listing (e.g. via the LIST or NLST FTP commands) to which the current logged-in, authenticated user has no access. Normal Unix-style permissions always apply, so that although a user may not be able to see a directory entry that has "HideNoAccess on" applied, they will receive a normal "Permission denied" error message when attempting to blindly manipulate the file system object. The directory or file can be made completely invisible to all FTP commands by applying IgnoreHidden in conjunction with HideNoAccess.

    See also: HideGroup, HideUser, IgnoreHidden


    HideUser

    Syntax: HideUser user-name
    Default: None
    Context: <Anonymous>, <Directory>
    Module: mod_core
    Compatibility: 0.99.0 and later

    The HideUser directive configures a <Directory> or <Anonymous> section to hide all directory entries owned by the specified user-name. The user-name can also be ~ (tilde), which is evaluated as the user-name of the logged-in user. This can be combined with a prefix ! (exclamation point) character, e.g. "!~", to mean "any user that is not the logged-in-user".

    Normally, hidden directories and files cannot be seen via LIST or NLST commands but can be operated on via other FTP commands (CWD, DELE, RETR, etc). This behavior can be modified via the IgnoreHidden directive.

    Examples:

      <Directory path>
        # Hide all files belonging to user 'root'
        HideUser root
    
        # Hide all files belonging to the logged-in user
        HideUser ~
    
        # Hide all files that are NOT owned by the logged-in user
        HideUser !~
      </Directory>
    

    See also: HideGroup, HideNoAccess, IgnoreHidden


    Include

    Syntax: Include path|pattern
    Default: None
    Context: server config, <VirtualHost>, <Global>, <Anonymous>, <Directory>
    Module: mod_core
    Compatibility: 1.2.10rc1 and later

    The Include directive allows inclusion of other configuration files from within the server configuration files.

    Shell-style (fnmatch(3)) wildcard characters can be used to include several files at once, in alphabetical order. (If no matches for the pattern are found, the Include directive is silently ignored.) In addition, if Include points to a directory, rather than a file, then proftpd will read all files in that directory. Note that including entire directories is not recommended, as it is easy to accidentally leave temporary files in a directory that can cause proftpd to fail.

    The path must be an absolute path. Examples:

      Include /etc/proftpd/conf/tls.conf
      Include /etc/proftpd/conf/vhosts/*.conf
    


    MasqueradeAddress

    Syntax: MasqueradeAddress ip-address|dns-name|device-name
    Default: None
    Context: server config, <VirtualHost>
    Module: mod_core
    Compatibility: 1.2.2 and later

    The MasqueradeAddress directive causes the server to display the network information for the specified IP address or DNS hostname to the client in the responses to PASV and EPSV FTP commands, on the assumption that that IP address or DNS host is acting as a NAT gateway or port forwarder for the server. For example:

      MasqueradeAddress nat-gw.mydomain.com 
    

    The MasqueradeAddress directive also handles a parameter which indicates the device-name (or interface-name); the IP address associated with this device/interface will be used. For example, you can use:

      MasqueradeAddress eth0
    
    Using the device/interface name is useful in cases where the same proftpd.conf file is going to be deployed to multiple different machines, which will have the same device/interface names but different IP addresses.


    MaxCommandRate

    Syntax: MaxCommandRate count [secs]
    Default: None
    Context: server config, <VirtualHost>, <Global>
    Module: mod_core
    Compatibility: 1.3.4rc2 and later

    The MaxCommandRate directive is used to configure a maximum number of commands per time interval, after which proftpd will start injecting a delay before handling the command. The more over the configured command/sec rate the client is, the longer the delay. This feature is used to "throttle" automated and/or malicious clients.

    For example:

      MaxCommandRate 200
    
    sets a maximum command rate of 200 commands per sec. Or:
      MaxCommandRate 500 2
    
    sets a maximum command rate of 500 commands every 2 secs.


    MaxInstances

    Syntax: MaxInstances count
    Default: None
    Context: server config
    Module: mod_core
    Compatibility: 1.1.6p11 and later

    The MaxInstances directive configures the maximum number of child (session) processes that may be spawned by the proftpd daemon process when running with "ServerType standalone" configured. The directive has no effect when proftpd is configured with "ServerType inetd".

    Each proftpd child process represents a single client connection, and thus this directive also controls the maximum number of simultaneous connections allowed. Additional connections beyond the configured limit are logged, and silently disconnected. The MaxInstances directive can be used to prevent undesirable denial-of-service attacks (e.g. by repeatedly connecting to the FTP control port, a malicious client could try to cause proftpd to repeatedly fork new processes, creating a "fork-bomb"). By default, no limit is placed on the number of child processes that may run at one time; it is highly recommended that a maximum number, suitable to your sites traffic, be configured.


    PassivePorts

    Syntax: PassivePorts min max
    Default: None
    Context: server config, <VirtualHost>, <Global>
    Module: mod_core
    Compatibility: 1.2.0rc2 and later

    The PassivePorts directive restricts the range of ports from which the server will select, when the client sends the PASV or EPSV commands (i.e. requesting a passive data transfer). The server will randomly choose a number from within the specified range until an open port is found. Should no open ports be found within the configured range, the server will default to a random kernel-assigned port, and a message logged.

    The port range configured must be in the non-privileged range (e.g. greater than or equal to 1024); it is STRONGLY RECOMMENDED that the chosen range be large enough to handle many simultaneous passive connections (for example, 49152-65534, the IANA-registered ephemeral port range). The smaller your configured port range is, the greater the chance that all of those ports will be in use (depending on the traffic to your FTP server), and thus the greater the chance that a port outside that range will be configured.

    Example:

      # Use the IANA registered ephemeral port range
      PassivePorts 49152 65534
    

    Note: Many admins wonder why the recommended port range is so large. The answer is that there is really no value in having a small range. ProFTPD does NOT automatically listen on these ports. For those people who are worried about port scanning, having a larger PassivePorts range will not mean that port scans will show those ports as being open AND that something is listening there. Conversely, the question to ask yourself as an administrator is: why do you think you need such a small PassivePorts range?


    PathAllowFilter

    Syntax: PathAllowFilter pattern [flags]
    Default: None
    Context: server config, <VirtualHost>, <Global>, <Anonymous>, <Directory>, .ftpaccess
    Module: mod_core
    Compatibility: 1.1.7 and later

    The PathAllowFilter directive allows the configuration of a regular expression pattern that must be matched for all newly uploaded (stored) files. The regular expression is applied against the entire pathname specified by the client, so care must be taken when creating a proper regex. Paths that fail the regex match result in a "Forbidden filename" error being returned to the client. If the regular expression pattern parameter contains whitespace, it must be enclosed in quotes.

    For example:

      # Only allow a-z 0-9 . - _ in file names
      PathAllowFilter ^[a-z0-9._-]+$
    
      # As above but with upper case characters as well
      PathAllowFilter ^[A-Za-z0-9._-]+$
    

    The optional flags parameter, if present, modifies how the given pattern will be evaludated. The supported flags are:

    • nocase|NC (no case)
      This makes the pattern case-insensitive, i.e. there is no difference between 'A-Z' and 'a-z' when pattern is matched against the path

    The Filters howto covers filtering in greater detail.

    See also: PathDenyFilter


    PathDenyFilter

    Syntax: PathDenyFilter pattern [flags]
    Default: None
    Context: server config, <VirtualHost>, <Global>, <Anonymous>, <Directory>, .ftpaccess
    Module: mod_core
    Compatibility: 1.1.7 and later

    Similar to the PathAllowFilter directive, PathDenyFilter specifies a regular expression pattern which must not match any uploaded pathnames. If the regex does match, a "Forbidden filename" error is returned to the client. This can be especially useful for forbidding .ftpaccess or .htaccess files.

    For example:

      # We don't want .ftpaccess or .htaccess files to be uploaded
      PathDenyFilter "(\\.ftpaccess|\\.htaccess)$"
    

    The optional flags parameter, if present, modifies how the given pattern will be evaludated. The supported flags are:

    • nocase|NC (no case)
      This makes the pattern case-insensitive, i.e. there is no difference between 'A-Z' and 'a-z' when pattern is matched against the path

    The Filters howto covers filtering in greater detail.

    See also: PathAllowFilter


    Port

    Syntax: Port number
    Default: Port 21
    Context: server config, <VirtualHost>
    Module: mod_core
    Compatibility: 0.99.0 and later

    The Port directive configures the TCP port to which proftpd will listen while running in standalone mode. This directive has no effect when used on a server running in inetd mode; see ServerType. The directive can be used in conjunction with <VirtualHost> in order to run a virtual server on the same IP address as the master server, but listening on a different port.

    For any server, either <VirtualHost> or "server config", using a number value of zero (0) will effectively disable/turn off that server:

      <VirtualHost ...>
        # This virtual server is disabled because of this Port setting
        Port 0
    
        ...
      </VirtualHost>
    


    ProcessTitles

    Syntax: ProcessTitles terse|verbose
    Default: ProcessTitles verbose
    Context: server config
    Module: mod_core
    Compatibility: 1.3.4rc2 and later

    The ProcessTitles directive is used to tweak how proftpd modifies the process title for session processes.

    By default, proftpd updates the process title to show the current FTP command and its arguments for every session, e.g.:

      # ps aux | grep proftpd
      proftpd  30667  0.0  0.1   7304  1584 ?        Ss   02:12   0:00 proftpd: (accepting connections)
      user1    31892  0.2  0.3   8004  3505 ?        SL   20:13   0:12 proftpd: user1 - remote.client1.com: RETR file1.doc
      user2    31934  0.0  0.3   8004  3500 ?        SL   21:27   0:00 proftpd: user2 - 4.3.2.1: STOR file2.zip
      user3    31891  0.2  0.3   8004  3504 ?        SL   20:11   0:09 proftpd: user3 - remote.client2.com: RETR whatever.iso
    
    This is the same as having:
      ProcessTitles verbose
    
    in your proftpd.conf.

    To obscure the process titles, you can use:

      ProcessTitles terse
    
    which results in process titles which look like:
      # ps aux | grep proftpd
      proftpd  30667  0.0  0.1   7304  1584 ?        Ss   02:12   0:00 proftpd: (accepting connections)
      user1    31892  0.2  0.3   8004  3505 ?        SL   20:13   0:12 proftpd: processing connection
      user2    31934  0.0  0.3   8004  3500 ?        SL   21:27   0:00 proftpd: processing connection
      user3    31891  0.2  0.3   8004  3504 ?        SL   20:11   0:09 proftpd: processing connection
    


    Protocols

    Syntax: Protocols protocol1 ...
    Default: None
    Context: server config, <VirtualHost>, <Global>
    Module: mod_core
    Compatibility: 1.3.4rc1 and later

    The Protocols directive is used to enable/disable specific protocols support by the proftpd and its collection of modules. This directive can be used, in conjunction with the mod_ifsession module, to enable certain features for specific users/groups/classes.

    The allowed protocols must be configured as a space-delimited list. For example:

      # Only enable FTPS and SFTP support, but not FTP or SCP
      Protocols ftps sftp
    

    The currently known/supported protocols include:


    ScoreboardFile

    Syntax: ScoreboardFile path|"none"
    Default: ScoreboardFile /usr/local/var/proftpd.scoreboard
    Context: server config
    Module: mod_core
    Compatibility: 1.2.7rc1 and later

    The ScoreboardFile directive sets the path to the file where the daemon will store its run-time "scoreboard" session information. This file is necessary for support features such as MaxClients to work properly, as well as other utilities (such as ftpwho, ftptop, and ftpcount). Note that the directory containing the scoreboard cannot be world-writable.

    For performance reasons, it is strongly recommended that the ScoreboardFile path not be located on a networked filesystem, but rather be located on a local physical disk.

    In order to disable scoreboarding (which can increase performance, at the cost of functionality), any of the following can be used:

      ScoreboardFile /dev/null
      ScoreboardFile none
      ScoreboardFile off
    
    Please read the Scoreboard howto before disabling scoreboarding.


    ScoreboardMutex

    Syntax: ScoreboardMutex path
    Default: ScoreboardMutex /usr/local/var/proftpd.scoreboard.lck
    Context: server config
    Module: mod_core
    Compatibility: 1.3.4rc1 and later

    The ScoreboardMutex directive sets the path to a "mutex" file which is used for scoreboard locking/synchronization; this mutex is used to increase the daemon's performance under load.

    For performance reasons, it is strongly recommended that the ScoreboardMutex path not be located on a networked filesystem, but rather be located on a local physical disk. It is best if the ScoreboardMutex be located in the same directory as the ScoreboardFile.


    ServerIdent

    Syntax: ServerIdent off|on "identification string"
    Default: ServerIdent on "ProFTPD [version] Server (server name) [hostname]"
    Context: server config, <VirtualHost>, <Global>
    Module: mod_core
    Compatibility: 1.2.0pre2 and later

    The ServerIdent directive sets the default message displayed when a new client connects. Setting this to off displays:

      [hostname] FTP server ready.
    
    If set to on, the directive can take an optional string argument, which will be displayed instead of the default text. Sites desiring to give out minimal information will probably want a setting like:
      ServerIdent on "FTP Server ready."
    
    which won't even reveal the hostname.

    An example of a custom identification string might be:

      ServerIdent on "Welcome to ftp.linux.co.uk"
    


    ServerType

    Syntax: ServerType "standalone"|"inetd"
    Default: ServerType standalone
    Context: server config
    Module: mod_core
    Compatibility: 0.99.0 and later

    The ServerType directive configures the proftpd server operating mode. The parameter can either be inetd or standalone.

    A parameter value of inetd configures proftpd to expect to be run from the inetd/xinetd "super server." New connections are passed from inetd/xinetd to proftpd and are processed immediately.

    A parameter value of standalone configures proftpd to start up on its own, and to begin listening to the configured addresses/ports for incoming connections. New connections result in forked child processes dedicated to processing all requests from the newly connected client.


    SocketOptions

    Syntax: SocketOptions [maxseg byte-count] [rcvbuf byte-count] [sndbuf byte-count] [keepalive "on"|"off"|spec]
    Default: None
    Context: server config, <VirtualHost>
    Module: mod_core
    Compatibility: 1.2.9rc1 and later

    The SocketOptions directive is used to tune various socket-level options. The rcvbuf and sndbuf parameters are used for setting the TCP send/receive window sizes. The maxseg parameter is used for setting a MSS (Maximum Segment Size) via setsockopt(2)'s TCP_MAXSEG option. If the MSS is larger than the network interface's MTU, it is ignored and has no effect.

    Examples:

      # Use buffer sizes of 32KB for both reading and writing
      SocketOptions rcvbuf 32768 sndbuf 32768
    

    In proftpd-1.3.5rc1, the SocketOptions directive gained support for the keepalive parameter. By default, proftpd enables TCP keepalives on all of its connections, both control and data. To disable use of TCP keepalives, use:

      SocketOptions keepalive off
    
    while to have TCP keepalives explicitly enabled in the config, you would use:
      SocketOptions keepalive on
    

    The keepalive parameter also handles an argument in the form of a "keepalive-spec", which is a colon-separated string of three numeric values: idle-secs, probe-count, and interval-secs. On most TCP stacks, the default TCP keepalive behavior uses 2 hours as the time (per recommendation in RFC 1122), with 9 probes at 75 seconds between each probe. Using the keepalive parameter, this would be configured as:

      SocketOption keepalive 7200:9:75
    
    The first number (idle-secs) indicates the number of seconds the TCP connection must be idle before the first TCP keepalive probe is sent. Once the idle-secs time has passed, the TCP stack will send a number of "probes", trying to elicit a response (ACK, RST, etc) from the remote peer; the number of probes sent is configured by the second number (probe-count). The probes will be sent out at intervals governed by the third number (interval-secs), which configures the number of seconds between each keepalive probe.

    Note that not all platforms support configuring the idle, count, and interval values of the TCP keepalive behavior in their TCP stack. On such platforms, if the keepalive spec format is used, e.g.:

      SocketOptions keepalive 7500:9:75
    
    and proftpd knows that it cannot alter the TCP keepalive values, then proftpd will assume that the keepalive configuration is equivalent to:
      SocketOptions keepalive on
    


    SyslogFacility

    Syntax: SyslogFacility facility
    Default: SyslogFacility daemon
    Context: server config
    Module: mod_core
    Compatibility: 1.1.6 and later

    By default, ProFTPD logs its activity via the Unix syslog mechanism, which allows for several different general classifications of logging messages, known as "facilities." Normally, all authentication related messages are logged with the AUTHPRIV (or AUTH) facility (since these messages are intended to be secure, and never seen by unwanted eyes), while normal operational messages are logged with the DAEMON facility. The SyslogFacility directive allows all logging messages to be directed to a different facility than the default.

    When this directive is used, all logging is done with the specified facility, both authentication (secure) and otherwise. The facility argument must be one of the following:

    • AUTH (or AUTHPRIV)
    • CRON
    • DAEMON
    • FTP
    • KERN
    • LPR
    • MAIL
    • NEWS
    • USER
    • UUCP
    • LOCAL0
    • LOCAL1
    • LOCAL2
    • LOCAL3
    • LOCAL4
    • LOCAL5
    • LOCAL6
    • LOCAL7
    For more information on syslog facilities, see the syslog.conf man page.

    The Logging howto covers logging in greater detail.

    See also: SyslogLevel, SystemLog


    SyslogLevel

    Syntax: SyslogLevel level
    Default: SyslogLevel debug
    Context: server config
    Module: mod_core
    Compatibility: 1.2.0rc2 and later

    The SyslogLevel directive adjusts the verbosity of the messages recorded via the default Unix syslog logging. The following levels are available, in order of decreasing significance:

    Level Description
    emerg Emergencies (e.g. the system is unusable)
    alert Action must be taken immediately
    crit Critical conditions
    error Error conditions
    warn Warning conditions
    notice Normal but significant conditions
    info Informational
    debug Debug-level messages

    When a particular level is specified, messages from all other levels of higher significance will be reported as well. For example, when:

      SyslogLevel info
    
    is configured, then messages with log levels of notice and warn will also be logged. Using a level of at least crit is recommended.

    The Logging howto covers logging in greater detail.

    See also: SyslogFacility, SystemLog


    TCPBacklog

    Syntax: TCPBacklog backlog-size
    Default: 5
    Context: server config
    Module: mod_core
    Compatibility: 0.99.0 and later

    The TCPBacklog directive controls the TCP connection queue size for listening sockets; this directive only applies to proftpd when it is configured with "ServerType standalone". It has no effect if "ServerType inetd" is configured.

    When a TCP connection is established by the TCP/IP stack within the kernel, there is a short period of time between the actual establishment of the TCP connection and when that connection is accepted for use by the listening daemon via the accept(2) system call. The duration of this period of time can vary quite a bit, and can depend upon several factors (e.g. hardware, system load, etc). Any TCP connection which hasn't been accepted by the listening daemon is placed in a "backlog" or queue of pending connections. The TCPBacklog directive controls how the size of this queue of pending connections.

    If this queue of pending connections becomes full, new TCP connections cannot be estaslished. Under heavy load, this can result in occasional (or even frequent) errors seen by clients, such as "Connection refused", even though the daemon is clearly running.

    The larger the backlog-size, the more TCP connections can be established to the daemon. This also means more kernel memory and other kernel resources.

    The issue is complicated further by the fact that different operating systems handle the backlog-size value differently. The pending connection queue is a critical kernel-level structure, and is sensitive to TCP syn floods. Each operating system, then, has different ways of handling incoming and pending connections, to attempt to guard against such attacks. For Linux systems, read the tcp(7) man page and specifically about tcp_abort_on_overflow, tcp_max_syn_backlog, and tcp_syncookies. On FreeBSD, read the syncookies(4) man page. And read here for additional tuning considerations on Solaris.


    TimeoutIdle

    Syntax: TimeoutIdle seconds
    Default: 600 seconds
    Context: server config, <VirtualHost>, <Global>, <Anonymous>
    Module: mod_core
    Compatibility: 0.99.0 and later

    The TimeoutIdle directive configures the maximum number of seconds that proftpd will allow clients to stay connected without receiving any data on either the control or data connection. If data are received on either connection, the idle timer is reset. Setting TimeoutIdle to zero disables the idle timer completely, meaning that clients can stay connected forever, without sending data. Note: this is generally a very bad idea, as a "hung" TCP connection which is never properly disconnected (e.g. the remote network may have become disconnected from the Internet, etc) will cause a session process to never exit, until manually killed. This session process will thus linger, using up one of the MaxInstances as well as any of the other configured limits. The maximum allowed seconds value is 65535 (108 minutes).

    See also: TimeoutLogin, TimeoutNoTransfer, TimeoutStalled.


    TimeoutLinger

    Syntax: TimeoutLinger seconds
    Default: 30
    Context: server config, <VirtualHost>, <Global>
    Module: mod_core
    Compatibility: 1.2.10rc2 and later

    The TimeoutLinger directive configures the maximum number of seconds that proftpd will wait (or "linger") when closing a data connection (i.e. for uploads, downloads, and directory listings). Once the data connection is closed, proftpd will send a response message ("226 Transfer complete") on the control connection indicating the closure. This delay is necessary for properly handling some FTP clients.

    If the client aborts a transfer and there is a long delay, this lingering close is the most likely culprit. So if you encounter this delay, set TimeoutLinger to a low number to remove the delay. The maximum allowed seconds is 65535 (108 minutes).

    For the curious, here are the full details: some FTP clients will close their end of a data connection as soon as they are done sending their data; other FTP clients will wait until the server closes its end of the data connection, and some will close their side of the data connection only after they receive the "226 Transfer complete" message on the control connection. In order to ensure that all of the data has been transferred on a data connection, proftpd will "linger" for a certain amount of time (governed by the TimeoutLinger directive) before sending that "226 Transfer complete" response, thus giving all client behaviors a chance to do the right thing. However, this means that some clients will see a this TimeoutLinger delay unnecessarily. The proftpd daemon can't detect which type of behavior the client will use, so it is up to the site admin to configure proftpd to work best with their FTP clients.


    Trace

    Syntax: Trace channel1:level1 ...
    Default: None
    Context: server config, <VirtualHost>, <Global>
    Module: mod_core
    Compatibility: 1.3.1rc1 and later

    The Trace directive is used to configure which trace channels are logged to the TraceLog file, and which log levels for messages in that trace channel.

    For example, to get the default trace channels logged:

      Trace DEFAULT:10
    

    To disable logging of a particular trace channel entirely, use a log level of zero, e.g.:

      # Log all of the default trace channels except for 'lock' and
      # 'scoreboard'
      Trace DEFAULT:10 lock:0 scoreboard:0
    

    To see only a certain range of log levels in a given trace channel, you can specify the log level range like this:

      # Log only messages at levels 7-10 for the default channels
      TraceLog DEFAULT:7-10
    

    See the Tracing howto for more information.


    TraceLog

    Syntax: TraceLog path
    Default: None
    Context: server config
    Module: mod_core
    Compatibility: 1.3.1rc1 and later

    The TraceLog directive is used to specify a log file for trace logging messages. The path parameter given must be the full path to the file to use for logging.

    Note that this path must not be to a world-writable directory and, unless AllowLogSymlinks is explicitly set to on (generally a bad idea), the path must not be a symbolic link.

    See the Tracing howto for more information.


    TraceOptions

    Syntax: TraceOptions opt1 ... optN
    Default: None
    Context: "server config", <VirtualHost>, <Global>
    Module: mod_core
    Compatibility: 1.3.4rc2 and later

    The TraceOptions directive can be used to change the format of the TraceLog messages, e.g. adding/remove certain fields of data.

    The options supported by the TraceOptions directive are:

    • ConnIPs
    • TimestampMillis
    These options are all disabled by default.

    To enable an option, preface the option name with a '+' (plus) character; to disable the option, use a '-' (minus) character prefix. For example:

      # Log timestamps inncluding millisecs, but do not include the connection
      # IP address/port information
      TraceOptions +TimestampMillis -ConnIPs
    


    TransferLog

    Syntax: TransferLog path|"none"
    Default: None
    Context: "server config", <VirtualHost>, <Global>, <Anonymous>
    Module: mod_core
    Compatibility: 1.1.4 and later

    The TransferLog directive configures the full path to the "wu-ftpd style" file transfer log; see the xferlog(5) man page for a description of this log file format. Separate log files can be created for each <Anonymous> and/or <VirtualHost>. Additionally, the special keyword "none" (available in proftpd-1.1.7 and later) can be used, which disables wu-ftpd style transfer logging for the context in which the directive is used.

    See also: ExtendedLog, LogFormat


    Umask

    Syntax: Umask file-umask [dir-umask]
    Default: None
    Context: "server config", <VirtualHost>, <Global>, <Anonymous>, .ftpaccess
    Module: mod_core
    Compatibility: 0.99.0 and later

    The Umask directive sets the mask applied to newly created file and directory permissions. Any parameters supplied must be an octal number, in the format 0xxx.

    An optional second dir-umask parameter can specify a different Umask to be used when creating directories, rather than files. If this second parameter is not used, directories are created using the file-umask value from the first parameter. For more information on umasks, consult your operating system documentation/man pages.

    Note: ProFTPD will not create files that have the executable bit enabled; this is a security-driven design decision. The permissions of an uploaded file can be changed by issuing a SITE CHMOD command, e.g.:

      SITE CHMOD 0755 /path/to/uploaded/file
    

    The Umask howto also talks about umasks in greater detail.


    <VirtualHost>

    Syntax: <VirtualHost ip-address|dns-name [ip-address|dns-name ...]>
    Default: None
    Context: "server config"
    Module: mod_core
    Compatibility: 0.99.0 and later

    The <VirtualHost> configuration section is used to create an independent set of configuration directives that apply to a particular hostname or IP address. It is often used in conjunction with system level IP aliasing or dummy network interfaces in order to establish one or more virtual servers which all run on the same physical machine. The section is terminated with a </VirtualHost> directive.

    By using the Port directive inside a <VirtualHost> section, it is possible to create a virtual server which uses the same IP address as the master server, but which listens on a different TCP port (Note, however, that this approach is incompatible with a ServerType of "inetd").

    When proftpd starts up, virtual server connections are handled in one of two ways, depending on the ServerType setting:

    • inetd

      The daemon examines the destination address and port of the incoming connection being handed off from inetd/xinetd. If the connection matches one of the configured <VirtualHost> sections, the connection is handled by that matching configuration. If no <VirtualHost> section matches, and the main server does not match, the client is informed that no server is available to handle their requests, and the client is disconnected.

    • standalone

      After parsing the configuration file, the daemon begins listening for connections on all configured ports, spawning child processes as necessary to handle connections for either the main server or any <VirtualHost> sections.

      Because of the method that the daemon uses to listen for connections when in standalone mode, it is possible to support an exceedingly large number of virtual servers, potentially exceeding the number of per-process file descriptors. This is due to the fact that a single file descriptor is used to listen to each configured port, regardless of the number of addresses being monitored. Note that it may be necessary to increase the TCPBackLog value on heavily loaded servers in order to avoid kernel-rejected client connections; clients will receive a "Connection refused" error when this condition happens.

    Starting with proftpd-1.3.0rc1, it is possible to use more than one DNS name or IP address. And starting with proftpd-1.3.5rc1, a device/interface name can also be used.

    Examples:

      <VirtualHost host1.domain.com host2.domain.com>
        ...
      </VirtualHost>
    
      # Establish a virtual server for the eth1 interface
      <VirtualHost eth1>
        ...
      </VirtualHost>
    
    
    The virtual server howto also talks about virtual servers in greater detail.

    See also: DefaultAddress


    Installation

    The mod_core module is always installed.



    Author: $Author: castaglia $
    Last Updated: $Date: 2013/01/10 00:21:34 $


    © Copyright 2000-2013 The ProFTPD Project
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/modules/mod_auth_file.html0000644000175000017500000002052612115676130022456 0ustar frankiefrankie ProFTPD module mod_auth_file

    ProFTPD module mod_auth_file



    This module is contained in the mod_auth_file.c file for ProFTPD 1.3.x, and is compiled by default.

    Directives


    AuthGroupFile

    Syntax: AuthGroupFile path [id min-max] [name regex]
    Default: None
    Context: server config, <VirtualHost>, <Global>
    Module: mod_auth_file
    Compatibility: 1.2.7rc2

    The AuthGroupFile directive configures an alternate group file for providing group membership information; the specified file must have the same format as the system /etc/group file, and if specified is used during authentication and group lookups for directory/access control operations. The path argument should be the full path to the specified file. This directive can be configured on a per-server basis, so that virtual FTP servers can each have their own authentication file, often in conjunction with an AuthUserFile.

    Note that this file does not need to reside inside a chroot()ed directory structure for anonymous or DefaultRoot logins, as it is held open for the duration of a session.

    The optional parameters are used to set restrictions on the contents of the specified file. The id restriction is used to specify a range of GIDs that may appear in the file; when doing a lookup, if a group entry has a GID that is less than the minimum or greater than the maximum is encountered, that entry is ignored. The name restriction is used to specify a regular expression that is applied to the name of a group entry. If the group name does not match the regular expression, the group entry is ignored. A leading ! in the regular expression can be used to negate the given expression.

    Example:

      # This makes an AuthGroupFile that can only have GIDs 2000 to 4000, and
      # whose groups must start with 'cust'
      AuthGroupFile /etc/ftpd/group id 2000-4000 name ^cust
    

    Note: In order to prevent other users from modifying the AuthGroupFile, the mod_auth_file module requires that the permissions on the file not be world-readable or world-writable, and that the directory containing the file not be world-writable. In addition, if the file is not a file (e.g. the path points to a symlink, or a FIFO, etc), a warning will be logged on server startup/restart.


    AuthUserFile

    Syntax: AuthUserFile path [id min-max] [home regex] [name regex]
    Default: None
    Context: server config, <VirtualHost>, <Global>
    Module: mod_auth_file
    Compatibility: 1.2.7rc2

    The AuthUserFile directive configures an alternate passwd file for providing user account information; the specified file must have the same format as the system /etc/passwd file, and if specified is used during authentication and user lookups for directory/access control operations. The path argument should be the full path to the specified file. This directive can be configured on a per-server basis, so that virtual FTP servers can each have their own authentication file, often in conjunction with an AuthGroupFile.

    Note that this file does not need to reside inside a chroot()ed directory structure for anonymous or DefaultRoot logins, as it is held open for the duration of a session.

    The optional parameters are used to set restrictions on the contents of the specified file. The id restriction is used to specify a range of UIDs that may appear in the file; when doing a lookup, if a user entry has a UID that is less than the minimum or greater than the maximum is encountered, that entry is ignored. The home restriction is used to specify a regular expression that is applied to the home directory of a user entry. If the home does not match the regular expression, the user entry is ignored. The name restriction is used to specify a regular expression that is applied to the name of a user entry. If the user name does not match the regular expression, the user entry is ignored. A leading ! in these regular expressions can be used to negate the given expression.

    Example:

      # This makes an AuthUserFile whose user names must start with 'ftp', and
      # whose homes cannot start with /home.
      AuthUserFile /etc/ftpd/passwd name ^ftp home !^/home
    

    Note: In order to prevent other users from modifying the AuthUserFile, the mod_auth_file module requires that the permissions on the file not be world-readable or world-writable, and that the directory containing the file not be world-writable. In addition, if the file is not a file (e.g. the path points to a symlink, or a FIFO, etc), a warning will be logged on server startup/restart.


    Installation

    The mod_auth_file module is compiled by default.

    Frequently Asked Questions

    Question: I found that only the first 8 characters of passwords are used! This is a security bug!
    Answer: No, it is not.

    The default Unix password hashing scheme uses the Data Encryption Standard (DES) algorithm. As per the crypt(3) man page, only the first 8 characters of the password are used. Thus this 8 character limitation comes from the underlying system authentication, not from proftpd. The whole purpose of the PAM system was to enable replacing the use of DES with other authentication algorithms, which do not have this 8 character limitation.

    Later, other crypt(3) implementations were made which can also support algorithms such as MD5, or Blowfish. Some platforms support these enhanced versions of crypt(3), some do not. The ftpasswd script can generate AuthUserFiles which use the MD5 algorithm instead of DES.

    Question: Why does mod_auth_file refuse to use an AuthUserFile (or AuthGroupFile that is world-writable?
    Answer: If an AuthUserFile or AuthGroupFile is world-writable, then any user on the system can edit that file. They can create new users, or change the entries for existing users such that those users have different privileges, perhaps even root privileges. In short, having AuthUserFile or AuthGroupFile with world-writable permissions is an unsafe configuration, and now mod_auth_file prevents this.

    Similarly, mod_auth_file will refuse to use an AuthUserFile or AuthGroupFile if that file lives in a directory, and that directory has world-writable permissions (even if the configured file itself is not world-writable). A world-writable directory would allow any system user to delete the AuthUserFile, and add their own, or to add a symlink, etc. It is another unsafe configuration against which mod_auth_file now guards.



    Author: $Author: castaglia $
    Last Updated: $Date: 2013/03/06 17:26:48 $


    © Copyright 2002-2013
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/modules/mod_dso.html0000644000175000017500000003615412142617360021307 0ustar frankiefrankie ProFTPD module mod_dso

    ProFTPD module mod_dso



    What are DSO modules?
    "On modern Unix derivatives there exists a nifty mechanism usually called dynamic linking/loading of Dynamic Shared Objects (DSO) which provides a way to build a piece of program code in a special format for loading it at run-time into the address space of an executable program.

    This loading can usually be done in two ways: Automatically by a system program called ld.so when an executable program is started, or manually from within the executing program via a programmatic system interface to the Unix loader through the system calls dlopen()/dlsym().

    In the first way the DSO's are usually called shared libraries or DSO libraries and named libfoo.so or libfoo.so.1.2. They reside in a system directory (usually /usr/lib/) and the link to the executable program is established at build-time by specifying -lfoo to the linker command. This hard-codes library references into the executable program file so that at start-time the Unix loader is able to locate libfoo.so in /usr/lib/, in paths hard-coded via linker-options like -R or in paths configured via the environment variable LD_LIBRARY_PATH. It then resolves any (yet unresolved) symbols in the executable program which are available in the DSO.

    Symbols in the executable program are usually not referenced by the DSO (because it's a reusable library of general code) and hence no further resolving has to be done. The executable program has no need to do anything on its own to use the symbols from the DSO because the complete resolving is done by the Unix loader. (In fact, the code to invoke ld.so is part of the run-time startup code which is linked into every executable program which has been bound non-static.) The advantage of dynamic loading of common library code is obvious: the library code needs to be stored only once, in a system library like libc.so, saving disk space for every program.

    In the second way the DSO's are usually called shared objects or DSO files and can be named with an arbitrary extension (although the canonical name is foo.so). These files usually stay inside a program-specific directory and there is no automatically established link to the executable program where they are used. Instead the executable program manually loads the DSO at run-time into its address space via dlopen(). At this time no resolving of symbols from the DSO for the executable program is done. Instead the Unix loader automatically resolves any (yet unresolved) symbols in the DSO from the set of symbols exported by the executable program and its already loaded DSO libraries (especially all symbols from the ubiquitous libc.so). This way the DSO gets knowledge of the executable program's symbol set as if it had been statically linked with it in the first place."

    (Taken from http://httpd.apache.org/docs/dso.html)

    The mod_dso module is ProFTPD's module for handling the dynamic loading of modules. This module is contained in the mod_dso.c file for ProFTPD 1.3.x, and is not compiled by default. Installation instructions are discussed here.

    The most current version of mod_dso can be found in the ProFTPD source distribution:

      http://www.proftpd.org/
    

    Directives

    Control Actions


    LoadFile

    Syntax: LoadFile path
    Default: None
    Context: "server config"
    Module: mod_dso
    Compatibility: 1.3.0rc1 and later

    The LoadFile directive is used to load any shared object (.so file extension), such as shared libraries. On some platforms, it may be necessary to load all of the libraries needed by a DSO module, using LoadFile, prior to loading the module itself.

    The path parameter must be the absolute path to the shared object to load.

    Example:

      # Load the zlib library
      LoadFile /usr/lib/libz.so
    


    LoadModule

    Syntax: LoadModule name
    Default: None
    Context: "server config"
    Module: mod_dso
    Compatibility: 1.3.0rc1 and later

    The LoadModule directive is used to dynamically load a module from the configuration file.

    Example:

      LoadModule mod_test.c
    


    ModuleControlsACLs

    Syntax: ModuleControlsACLs actions|all allow|deny user|group list
    Default: None
    Context: "server config"
    Module: mod_dso
    Compatibility: 1.3.0rc1 and later

    The ModuleControlsACLs directive configures access lists of users or groups who are allowed (or denied) the ability to use the actions implemented by mod_dso. The default behavior is to deny everyone unless an ACL allowing access has been explicitly configured.

    If "allow" is used, then list, a comma-delimited list of users or groups, can use the given actions; all others are denied. If "deny" is used, then the list of users or groups cannot use actions all others are allowed. Multiple ModuleControlsACLs directives may be used to configure ACLs for different control actions, and for both users and groups.

    The actions provided by mod_dso are "insmod" "lsmod", and "rmmod".

    Example:

      # Allow only user root to load and unload modules, but allow everyone
      # to see which modules have been loaded
      ModuleControlsACLs insmod,rmmod allow user root
      ModuleControlsACLs lsmod allow user *
    


    ModuleOrder

    Syntax: ModuleOrder ...
    Default: None
    Context: "server config"
    Module: mod_dso
    Compatibility: 1.3.0rc1 and later

    The ModuleOrder directive can be used to explicitly set the module order. Note: do not use this directive unless you know what you are doing. It is very easy to configure a non-working server with this directive.

    If you are going to use ModuleOrder, make sure it is the very first directive in your proftpd.conf file.

    Example:

      # Make this one the very first things, if you're going to use it.
      ModuleOrder \
        mod_core.c \
        mod_cap.c \
        mod_auth_unix.c \
        mod_auth_pam.c \
        mod_ls.c \
        mod_log.c \
        mod_site.c \
        mod_xfer.c \
        mod_auth.c \
        mod_ifsession.c \
        mod_auth_file.c
    


    ModulePath

    Syntax: ModulePath path
    Default: None
    Context: "server config"
    Module: mod_dso
    Compatibility: 1.3.0rc1 and later

    The ModulePath directive is used to configure an alternative directory from which mod_dso will load DSO modules. By default, mod_dso uses $prefix/libexec/, where $prefix is where you installed proftpd, e.g. /usr/local/.

    The path parameter must be an absolute path.

    Example:

      ModulePath /etc/proftpd/libexec
    


    Control Actions


    insmod

    Syntax: ftpdctl insmod module
    Purpose: Load a DSO module

    The insmod control action can be used to load a DSO module into the running proftpd daemon.

    A module cannot be loaded multiple times.

    Example:

      ftpdctl rmmod mod_test.c
      ftpdctl: 'mod_test.c' loaded
    


    lsmod

    Syntax: ftpdctl lsmod
    Purpose: Display list of all loaded modules

    The lsmod control action is used to display a list of all loaded modules.

    Example:

      ftpdctl lsmod           
      ftpdctl: Loaded Modules:
      ftpdctl:   mod_core.c
      ftpdctl:   mod_xfer.c
      ftpdctl:   mod_auth_unix.c
      ftpdctl:   mod_auth_file.c
      ftpdctl:   mod_auth.c
      ftpdctl:   mod_ls.c
      ftpdctl:   mod_log.c
      ftpdctl:   mod_site.c
      ftpdctl:   mod_dso.c
      ftpdctl:   mod_ctrls.c
      ftpdctl:   mod_auth_pam.c
      ftpdctl:   mod_cap.c
    


    rmmod

    Syntax: ftpdctl rmmod module
    Purpose: Unload a DSO module

    The rmmod control action can be used to unload a DSO module from the running proftpd daemon. Note that it is also possible to "unload" one of the staticly-linked modules; this does not remove that module from the process' memory space, but does remove that module from the core engine, such that proftpd will act as if the module is not present.

    Example:

      ftpdctl rmmod mod_test.c
      ftpdctl: 'mod_test.c' unloaded
    


    Usage

    Note that mod_dso's control actions are only available if your proftpd has been compiled with Controls support.


    Installation

    The mod_dso module is distributed with ProFTPD. To enable use of DSO modules, use the --enable-dso configure option:
      ./configure --enable-dso
      make
      make install
    
    This option causes mod_dso to be compiled into proftpd.

    Frequently Asked Questions

    Question: When I try to start proftpd, it fails like this:

      proftpd[1234]: mod_dso/0.5: module 'mod_radius.c' already loaded
      proftpd[1234]: Fatal: LoadModule: error loading module 'mod_radius.c': Operation not permitted on line 9 of '/etc/proftpd/proftpd.conf'
    
    How do I fix this "module already loaded" error?
    Answer: This happens when the proftpd configuration either a) uses the
    LoadModule on a module which was compiled in as a static module, or b) is inadvertently using LoadModule on the same module multiple times.

    To check if the module has been statically compiled into your proftpd executable, use the -l command-line parameter, e.g.:

      # proftpd -l
      Compiled-in modules:
        mod_core.c
        mod_xfer.c
        mod_auth_unix.c
        mod_auth_file.c
        mod_auth.c
        mod_ls.c
        mod_log.c
        mod_site.c
        mod_delay.c
        mod_facts.c
        mod_dso.c
        mod_ident.c
        mod_auth_pam.c
        mod_tls.c
        mod_cap.c
    
    The modules listed via the command are the static modules. So if your LoadModule directive is used for one of the modules in this list, you can remove that LoadModule directive; that module will already be loaded.

    The other cause, that of having multiple LoadModule directives for the same module, usually happens when your proftpd.conf file includes other config files, e.g.:

      Include /path/to/modules.conf
    
    and it is those other config files which have LoadModule directives of their own.

    If you find yourself needs to change the configuration to work around this error, you can use the following to see if the module has already been loaded, and if not, load it:

      <IfModule !mod_radius.c>
        LoadModule mod_radius.c
      </IfModule>
    

    Question: When I try to start proftpd, it fails like this:

      proftpd[1234]: mod_dso/0.5: module 'mod_ctrls.c' already loaded
      proftpd[1234]: Fatal: LoadModule: error loading module 'mod_ctrls.c': Operation not permitted on line 9 of '/etc/proftpd/proftpd.conf'
    
    I do not have any other LoadModule directives in my config, nor is the mod_ctrls module in my --with-modules configure option.

    Answer: In this particular case, the mod_ctrls module is automatically compiled in, as a static module, when the --enable-ctrls configure option is used. There are only a few such modules with this special handling:
    • mod_ctrls (via the --enable-ctrls configure option)
    • mod_dso (via the --enable-dso configure option)
    • mod_lang (via the --enable-nls configure option)
    • mod_memcache (via the --enable-memcache configure option)
    All of these modules would appear in the `proftpd -l' static module list.

    Question: If I use prxs to compile a module like mod_ldap, which is already built into my proftpd as a static module, and then I use:

      LoadModule mod_ldap.c
    
    in my proftpd.conf, then which mod_ldap code is used, the static module or the shared module?
    Answer: Excellent question. The short answer is: the static module wins.

    When mod_dso goes to load a module, it first checks to see whether that module is already loaded -- and if so, the module will not be loaded again. Static modules, by definition, are always "already loaded". This means that your mod_ldap shared module code would not be loaded, and thus would not override the static module.



    Author: $Author: castaglia $
    Last Updated: $Date: 2013/05/09 03:58:40 $


    © Copyright 2004-2013 TJ Saunders
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/modules/mod_ident.html0000644000175000017500000000430210737555714021627 0ustar frankiefrankie ProFTPD module mod_ident

    ProFTPD module mod_ident



    RFC1413 Identification Support

    The mod_ident module is ProFTPD's module for performing lookups of authenticated user IDs, as per RFC 1413.

    This module is contained in the mod_ident.c file for ProFTPD 1.3.x, and is compiled by default. See the installation section for more details.

    The most current version of mod_ident can be found in the ProFTPD source distribution:

      http://www.proftpd.org/
    

    Directives


    IdentLookups

    Syntax: IdentLookups on|off
    Default: IdentLookups on
    Context: "server config", <VirtualHost>, <Global>
    Module: mod_ident
    Compatibility: 1.3.2rc1

    The IdentLookups directive enables or disables the module's lookup of an "authenticated" user identity using RFC1413.


    Installation

    The mod_ident module is compiled into proftpd by default. To build a proftpd which does not include the mod_ident module, use:
      ./configure --disable-ident ...
    
    Note that the mod_ident module can also be built as a shared module, rather than be statically linked into proftpd:
      ./configure --enable-dso --with-shared=mod_ident ...
    



    Author: $Author: castaglia $
    Last Updated: $Date: 2008/01/05 01:22:20 $


    © Copyright 2008 TJ Saunders
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/modules/mod_log.html0000644000175000017500000003616212120774541021303 0ustar frankiefrankie ProFTPD module mod_log

    ProFTPD module mod_log



    This module is contained in the mod_log.c file for ProFTPD 1.3.x, and is compiled by default.

    Directives


    AllowLogSymlinks

    Syntax: AllowLogSymlinks on|off
    Default: None
    Context: server config, <VirtualHost>, <Global>
    Module: mod_log
    Compatibility: 1.2.2rc2 and later

    By default, the server will the path of any configured SystemLog, any configured TransferLogs, and any configured ExtendedLogs to see if they are symbolic links. If the paths are symbolic links, proftpd will refuse to log to that link unless explicitly configured to do so via this AllowLogSymlinks directive.

    Security Note: This behaviour should not be allowed unless for a very good reason. By allowing the server to open symbolic links with its root privileges, you are allowing a potential symlink attack where the server could be tricked into overwriting arbitrary system files. You have been warned.


    ExtendedLog

    Syntax: ExtendedLog path [cmd-classes [format-nickname]]
    Default: None
    Context: server config, <VirtualHost>, <Global>, <Anonymous>
    Module: mod_log
    Compatibility: 1.1.6p11 and later

    The ExtendedLog directive allows customizable logfiles to be generated, either globally or per <VirtualHost>. The path argument should contain an absolute pathname to a logfile which will be appended to when proftpd starts; the pathname should not be to a file in a nonexistent directory, to a world-writable directory, or be a symbolic link (unless AllowLogSymlinks is set to on). Multiple logfiles, potentially with different command classes and formats) can be created. Optionally, the cmd-classes parameter can be used to control which types of commands are logged. If no command classes are specified, proftpd logs all commands by default. Note that passwords are hidden. If used, the cmd-classes parameter is a comma-delimited (with no whitespace) list of which commands to log.

    In proftpd-1.2.8rc1 and later, the path argument can be of the form "syslog:level". The "syslog:" prefix configures mod_log to write the ExtendedLog data to syslog rather than to a file. The level configures the syslog level at which to log the data. For example:

      ExtendedLog syslog:info ALL default
    

    This table shows the supported command classes:

    Command Class FTP Commands
    ALL All commands except the EXIT pseudo-command (default)
    NONE No commands
    AUTH Authentication commands: ACCT, PASS, REIN, USER
    INFO Informational commands: FEAT, HELP, MDTM, QUIT, PWD, STAT, SIZE, SYST, XPWD
    DIRS Directory commands: CDUP, CWD, LIST, MKD, MLSD, MLST, NLST, RMD, XCWD, XCUP, XMKD, XRMD
    READ File reading: RETR
    WRITE File/directory writing or creation: APPE, MFF, MFMT, MKD, RMD, RNFR, RNTO, STOR, STOU, XMKD, XRMD
    MISC Miscellaneous commands: ABOR, ALLO, EPRT, EPSV, MODE, NOOP, OPTS, PASV, PORT, REST, RNFR, RNTO, SITE, SMNT, STRU, TYPE
    SEC RFC2228-related security FTP commands: AUTH, CCC, PBSZ, PROT
    EXIT Logs the configured LogFormat at session exit.
    NOTE: EXIT is not part of the ALL command class, in order to preserve backward-compatible ALL behavior.

    If a format-nickname parameter is used, ExtendedLog will use the named LogFormat. Otherwise, the default format of "%h %l %u %t \"%r\" %s %b" is used.

    For example, to log all read and write operations to /var/log/ftp.log using the default format, use:

      ExtendedLog /var/log/ftp.log READ,WRITE
    

    See also: AllowLogSymlinks, LogFormat, TransferLog


    LogFormat

    Syntax: LogFormat format-nickname format-string
    Default: LogFormat default "%h %l %u %t \"%r\" %s %b"
    Context: server config
    Module: mod_log
    Compatibility: 1.1.6p11 and later

    The LogFormat directive can be used to create a custom logging format for use with the ExtendedLog directive. Once created, the format can be referenced by the specified format-nickname. The format-string parameter can consist of any combination of letters, numbers and symbols. The special character '%' is used to start a meta sequence/variable (see below). To insert a literal '%' character, use "%%".

    The default LogFormat is:

      "%h %l %u %t \"%r\" %s %b"
    
    which produces log entries in the Common Log Format.

    The following meta sequences/variables are available and are replaced as indicated when logging.

    Variable Value
     %a  Remote client IP address
     %A  Anonymous login password, or "UNKNOWN" for regular logins
     %b  Number of bytes sent for this command
     %c  Client connection class, or "-" if undefined
     %d  Directory name (not full path) for: CDUP, CWD, MKD, RMD, XCWD, XCUP, XMKD, XRMD
     %D  Directory name (full path) for: CDUP, CWD, MKD, RMD, XCWD, XCUP, XMKD, XRMD
     %E  End-of-session reason
     %{NAME}e  Contents of environment variable NAME
     %f  Absolute path of the filename stored or retrieved (not chrooted)
     %F  Filename stored or retrieved, as the client sees it
     %{file-modified}  Indicates whether a file is modified (i.e. already exists): "true" or "false"
     %{gid}  GID of authenticated user
     %g  Primary group of authenticated user
     %h  Remote client DNS name
     %H  Local IP address of vhost/server hosting/handling the session
     %I  Total number of "raw" bytes read in from network
     %{iso8601}  shorthand form of %{%Y-%m-%d %H:%M:%S}t,%{millisecs}, e.g. "2013-01-30 20:14:05,670"
     %J  Command arguments received from client, e.g. "file.txt"
     %l  Remote username (from identd), or "UNKNOWN" if IdentLookup failed
     %L  Local IP address contacted by client
     %m  Command (method) name received from client, e.g. RETR
     %{microsecs}  6 digit value of the microseconds of the current time
     %{millisecs}  3 digit value of the milliseconds of the current time
     %O  Total number of "raw" bytes written out to network
     %p  Local server IP address
     %P  Local server process ID (pid)
     %{protocol}  Current protocol: "ftp", "ftps", "ssh2", "sftp", "scp"
     %r  Full command received from client
     %s  Numeric FTP response code (status); see RFC 959 Section 4.2.1
     %S  Response message sent to client (available since 1.3.1rc1)
     %t  Current local time
     %{format}t  Current local time using strftime(3) format
     %T  Time taken to send/receive file, in seconds
     %{transfer-failure}  Reason for transfer failure (if applicable), or "-"
     %{transfer-status}  Status of data transfer: "success", "failed", "cancelled", "timeout", or "-"
     %u  Authenticated local username
     %U  USER name originally sent by client
     %{uid}  UID of authenticated user
     %v  Local server ServerName
     %V  Local server DNS name
     %{version}  ProFTPD version
     %w  Absolute path for the RNFR path ("whence" a rename comes)

    See also: ExtendedLog, TransferLog


    ServerLog

    Syntax: ServerLog path|"none"
    Default: None
    Context: server config, <VirtualHost>, <Global>
    Module: mod_log
    Compatibility: 1.2.8rc1 and later

    The ServerLog directive is used to configure a <VirtualHost>-specific logfile at the given path, rather than a single SystemLog for the entire configuration.

    A path value of "none" will disable file logging for that vhost; this can be used to override a global ServerLog setting.


    SystemLog

    Syntax: SystemLog path|"none"
    Default: None
    Context: server config
    Module: mod_log
    Compatibility: 1.1.6p11 and later

    The SystemLog directive disables proftpd's use of the syslog mechanism and instead redirects all logging output to the specified path. The path should contain an absolute path, and should not be to a file in a nonexistent directory, in a world-writable directory, or be a symbolic link (unless AllowLogSymlinks is set to on).

    Use of this directive overrides any facility set by the SyslogFacility directive.

    A path value of "none" will disable logging for the entire daemon.


    Installation

    The mod_log module is compiled by default.



    Author: $Author: castaglia $
    Last Updated: $Date: 2013/03/16 04:47:29 $


    © Copyright 2002-2013
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/modules/mod_ls.html0000644000175000017500000001021511714011763021125 0ustar frankiefrankie ProFTPD module mod_ls

    ProFTPD module mod_ls



    The mod_ls module handles the LIST, NLST, and STAT FTP commands.

    Directives


    DirFakeGroup

    Syntax: DirFakeGroup off|on display-name
    Default: None
    Context: server config, <VirtualHost>, <Global>, <Anonymous>, <Directory>, .ftpaccess
    Module: mod_ls
    Compatibility: All versions

    The DirFakeGroup directive

    Examples:

    
    
    


    DirFakeMode

    Syntax: DirFakeMode display-mode
    Default: None
    Context: server config, <VirtualHost>, <Global>, <Anonymous>, <Directory>, .ftpaccess
    Module: mod_ls
    Compatibility: All versions

    The DirFakeMode directive

    Examples:

      # Display everything as read-only
      DirFakeMode 0444
    


    DirFakeUser

    Syntax: DirFakeUser off|on display-name
    Default: None
    Context: server config, <VirtualHost>, <Global>, <Anonymous>, <Directory>, .ftpaccess
    Module: mod_ls
    Compatibility: All versions

    The DirFakeUser directive

    Examples:

    
    
    


    ListOptions

    Syntax: ListOptions options [strict [maxdepth depth] [maxfiles count] [maxdirs count] [LISTOnly] [NLSTOnly] [NoErrorIfAbsent]
    Default: None
    Context: server config, <VirtualHost>, <Global>, <Anonymous>, <Directory>, .ftpaccess
    Module: mod_ls
    Compatibility: 1.2.8rc1 and later

    The ListOptions directive

    See also: ListOptions


    ShowSymlinks

    Syntax: ShowSymlinks on|off
    Default: None
    Context: server config, <VirtualHost>, <Global>, <Anonymous>
    Module: mod_ls
    Compatibility: All versions

    The ShowSymlinks directive

    Examples:

    
    
    


    UseGlobbing

    Syntax: UseGlobbing on|off
    Default: None
    Context: server config, <VirtualHost>, <Global>, <Anonymous>
    Module: mod_ls
    Compatibility: All versions

    The UseGlobbing directive

    Examples:

      # Turn off support for globs in LIST/NLST commands
      UseGlobbing off
    


    Installation

    The mod_lsmodule is always installed.



    Author: $Author: castaglia $
    Last Updated: $Date: 2012/02/06 17:54:59 $


    © Copyright 2000-2012 The ProFTPD Project
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/modules/mod_rlimit.html0000644000175000017500000001422412155374565022027 0ustar frankiefrankie ProFTPD module mod_rlimit

    ProFTPD module mod_rlimit



    The mod_rlimit module handles setting and enforcement of resource limits such as CPU, memory, and file descriptor usage.

    By default, the mod_rlimit module will impose one resource restriction on new session processes: the RLIMIT_NPROC (see getrlimit(2) limit, which controls the number of processes which can be forked from this process, is set to zero. There is absolutely no reason for a proftpd session process to need to create a new process via fork(2).

    This module is contained in the mod_rlimit.c file for ProFTPD 1.3.x, and is compiled by default. See the installation section for more details.

    The most current version of mod_rlimit can be found in the ProFTPD source distribution:

      http://www.proftpd.org/
    

    Directives


    RLimitCPU

    Syntax: RLimitCPU [scope] soft-limit|"max" [hard-limit|"max"]
    Default: System defaults
    Context: "server config", <VirtualHost>, <Global>
    Module: mod_rlimit
    Compatibility: 1.3.5rc2

    The RLimitCPU directive is used to set a limit on the CPU usage, expressed as a maximum number of seconds.

    RLimitCPU takes from one to three parameters. The first parameter is an optional scope parameter, indicating the scope of the resource limit. The scope parameter may be one of:

    • "daemon" (applies the resource limit only to the daemon process)
    • "session" (which applies the limit only to session processes handling each client)
    • "none" (which disables any possibly inherited limits)
    If none of these keywords are used, the resource limit is assumed to apply to both daemon and session processes.

    The next parameters indicate the actual resource limits, both the so-called "soft limit" and any "hard limit". These parameters may be a number (indicating the number of seconds), or the value "max" to indicate that maximum resource limit value allowed is to be used.

    Example:

      # Limit a given session to 30 minutes of CPU time (which can take
      # considerably longer than 30 minutes of wall time, due to CPU scheduling)
      RLimitCPU 1800
    


    RLimitMemory

    Syntax: RLimitMemory [scope] soft-limit|"max" [hard-limit|"max"]
    Default: System defaults
    Context: "server config", <VirtualHost>, <Global>
    Module: mod_rlimit
    Compatibility: 1.3.5rc2

    The RLimitMemory directive is used to set a limit on the memory usage, expressed as a maximum number of bytes.

    RLimitMemory takes from one to three parameters. The first parameter is an optional scope parameter, indicating the scope of the resource limit. The scope parameter may be one of:

    • "daemon" (applies the resource limit only to the daemon process)
    • "session" (which applies the limit only to session processes handling each client)
    • "none" (which disables any possibly inherited limits)
    If none of these keywords are used, the resource limit is assumed to apply to both daemon and session processes.

    The next parameters indicate the actual resource limits, both the so-called "soft limit" and any "hard limit". These parameters may be a number (indicating the number of bytes), or the value "max" to indicate that maximum resource limit value allowed is to be used.

    Example:

      # Limit a given session to 128MB minutes of memory
      RLimitMemory 128MB
    


    RLimitOpenFiles

    Syntax: RLimitOpenFiles [scope] soft-limit|"max" [hard-limit|"max"]
    Default: System defaults
    Context: "server config", <VirtualHost>, <Global>
    Module: mod_rlimit
    Compatibility: 1.3.5rc2

    The RLimitOpenFiles directive is used to set a limit on the file descriptors, expressed as counts.

    RLimitOpenFiles takes from one to three parameters. The first parameter is an optional scope parameter, indicating the scope of the resource limit. The scope parameter may be one of:

    • "daemon" (applies the resource limit only to the daemon process)
    • "session" (which applies the limit only to session processes handling each client)
    • "none" (which disables any possibly inherited limits)
    If none of these keywords are used, the resource limit is assumed to apply to both daemon and session processes.

    The next parameters indicate the actual resource limits, both the so-called "soft limit" and any "hard limit". These parameters may be a number, or the value "max" to indicate that maximum resource limit value allowed is to be used.

    Example:

      # Limit a given session to 12 open file descriptors
      RLimitMemory session 12
    


    Installation

    The mod_rlimit module is compiled into proftpd by default.



    Author: $Author: castaglia $
    Last Updated: $Date: 2013/06/10 16:06:13 $


    © Copyright 2013 TJ Saunders
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/modules/mod_lang.html0000644000175000017500000002475712035147311021444 0ustar frankiefrankie ProFTPD module mod_lang

    ProFTPD module mod_lang



    Internalization and Localization
    The mod_lang module is ProFTPD's module for handling the LANG and OPTS UTF8 commands, in support of RFC 2640. The mod_lang module also supports character sets other than UTF-8, for those sites which do not require RFC 2640 support, but do use character sets other than ASCII. This module is contained in the mod_lang.c file for ProFTPD 1.3.x, and is compiled in whenever the --enable-nls configure option is used. Installation instructions are discussed here. Examples of using mod_lang for various encodings and character sets can be seen here.

    The most current version of mod_lang can be found in the ProFTPD source distribution:

      http://www.proftpd.org/
    

    Directives


    LangDefault

    Syntax: LangDefault language
    Default: LangDefault en_US
    Context: "server config", <VirtualHost>, <Global>
    Module: mod_lang
    Compatibility: 1.3.1rc1

    The LangDefault directive is used to specify the default language of specific server configuration. Note that the specified language must be listed in the output from:

      $ locale -a
    

    Example:

      <IfModule mod_lang.c>
        # Set the default to be Italian
        LangDefault it_IT
      </IfModule>
    


    LangEngine

    Syntax: LangEngine on|off
    Default: LangEngine on
    Context: "server config", <VirtualHost>, <Global>
    Module: mod_lang
    Compatibility: 1.3.1rc1

    The LangEngine directive enables or disables the module's handling of the LANG command. If it is set to off this module does no localization of responses.

    Note that setting LangEngine to off also keeps proftpd from advertisting "UTF8" in its FEAT response. As required by RFC 2640, proftpd can only show "UTF8" in response to a FEAT command if the LANG command is also supported. Hence why it is the LangEngine directive, and not UseUTF8, which controls the appearance of "UTF8".


    LangPath

    Syntax: LangPath path
    Default: None
    Context: "server config"
    Module: mod_lang
    Compatibility: 1.3.1rc1

    The LangPath directive is used to configure an alternative directory from which mod_lang will load locale files. By default, mod_lang uses $prefix/locale/, where $prefix is where you installed proftpd, e.g. /usr/local/.

    The path parameter must be an absolute path.

    Example:

      LangPath /etc/proftpd/locale
    

    Example:

      LangPath /path/to/ftpd/locale
    


    UseEncoding

    Syntax: UseEncoding on|off|local-charset client-charset ["strict"]
    Default: None
    Context: "server config", <VirtualHost>, <Global>
    Module: mod_lang
    Compatibility: 1.3.2rc1

    The UseEncoding directive is used to explicitly configure which character sets should be used for encoding. By default, the mod_lang module will automatically discover the local character set, and will use UTF-8 for the client character set. The module will also allow the use of UTF-8 encoding to be changed by clients using the OPTS UTF8 command (as per RFC 2640). However, if the UseEncoding directive is explicitly used to indicate the character sets to use (or not use) and the "strict" keyword is used, then any OPTS UTF8 commands used by clients will be refused.

    For example, to disable all use of encoding, use the following in your proftpd.conf:

      UseEncoding off
    
    Similarly, to enable use of UTF8 encoding and to not allow clients to change the use of UTF8, you would use:
      UseEncoding on
    

    In addition to the on|off parameters, the UseEncoding directive allows administrators to specify exactly which character sets to use locally (i.e. for paths on local disks) and for dealing with clients. One such usage this way might look like:

      UseEncoding koi8-r cp1251
    
    With the above, a client could still request a switch from koi8-r encoding to UTF-8 via the OPTS UTF8 command. If, however, you wished to prevent clients from changing the encoding to UTF-8, the above configuration would instead look like:
      UseEncoding koi8-r cp1251 strict
    

    For a full list of the character sets which are supported, use:

      $ iconv --list
    


    Installation

    The mod_lang module is distributed with ProFTPD. To enable use of NLS (Natural Language Support) in your proftpd daemon, use the --enable-nls configure option:
      ./configure --enable-nls
      make
      make install
    
    This option causes mod_lang to be compiled into proftpd.


    Usage

    One common request of proftpd is to properly handle Cyrillic characters in file and directory names. The usual character sets which contain Cyrillic characters use the same codes as used for Telnet control codes, unfortunately. RFC 959 (which defines FTP) mandates that the Telnet control codes be supported in FTP implementations.

    The mod_lang module, however, can be used to deal with this situation. If the UseEncoding directive is used to translate between local and client character sets, and the client character set is one of the known Cyrillic character sets, then proftpd will disable support of the Telnet control codes.

    To make a long explanation short, if you want to use Cyrillic characters in paths with proftpd, compile your proftpd using the --enable-nls configure option (to enable the use of mod_lang), then use something like the following in your proftpd.conf:

      <IfModule mod_lang.c>
        UseEncoding utf8 cp1251
      </IfModule>
    
    The current list of character sets for which Telnet code support is disabled is listed below; the names are not case-sensitive:
    • cp866
    • cp1251
    • iso-8859-1
    • koi8-r
    • windows-1251

    Frequently Asked Questions

    Question: What translations for proftpd currently exist?
    Answer: ProFTPD has currently been translated into:

    If you are interested in providing more translations, please read this howto.

    Question: When I upload a file with special characters (e.g. umlauts, accents, cedillas, etc) in the file name, the special characters are turned into '?' on the server. What's wrong?
    Answer: There are a couple of things to check when this happens.

    First, make sure that your proftpd has been compiled with NLS support. Type proftpd -V, and make sure you see:

      + NLS support
    
    appear in the output.

    Next, make sure that the LANG environment variable is set before starting the server. Special characters require that UTF-8 or ISO-8859-1 be used, thus you might use things like:

      # export LANG=de_DE.utf8
      # export LANG=fr_FR.ISO8859-1
    

    Last, check that any routers/firewalls/NAT between the clients and the server are not interfering. ProFTPD lists "UTF8" in its FEAT response data; many FTP clients use the OPTS UTF8 ON command to inform the server that UTF8 filenames will be sent. Some routers, firewalls, and NATs have been known to filter both the FEAT response and/or block commands like OPTS UTF8, thus interfering with the protocol and causing encoding problems.

    Question: I have configured my mod_lang module to use a language, but when I start proftpd, I see an error like this:

      mod_lang/0.9: LangDefault 'language', configured for server 'serverName', is not a supported language, removing
    
    Answer: This usually happens for one of two reasons: Both of these conditions must be true, otherwise you will see the "not a supported language" error.



    Author: $Author: castaglia $
    Last Updated: $Date: 2012/10/10 01:26:33 $


    © Copyright 2006-2012 TJ Saunders
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/modules/mod_facl.html0000644000175000017500000000375410513220023021411 0ustar frankiefrankie ProFTPD module mod_facl

    ProFTPD module mod_facl



    The mod_facl module adds support to ProFTPD for POSIX ACLs. For more information on what POSIX ACLs are and how they work, see "POSIX ACLs on Linux":

        http://www.suse.de/~agruen/acl/linux-acls/online/
    
    POSIX ACLs are supported and implemented differently on Linux, BSD, and Solaris. ProFTPD attempts to work properly with POSIX ACLs on all of these platforms.

    Installation instructions for mod_facl can be found here.

    The most current version of mod_facl can be found in the ProFTPD source distribution:

      http://www.proftpd.org/
    

    Directives


    FACLEngine

    Syntax: FACLEngine on|off
    Default: on
    Context: server config
    Module: mod_facl
    Compatibility: 1.3.1rc1 and later

    The FACLEngine directive enables or disables the module's runtime checking of POSIX ACLs. Use this directive to disable the module.


    Installation

    To use the mod_facl module, configure proftpd using the following:
      ./configure --enable-facl --with-modules=mod_facl ...
    



    Author: $Author: castaglia $
    Last Updated: $Date: 2006/10/11 16:47:15 $


    © Copyright 2000-2006 TJ Saunders
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/modules/mod_memcache.html0000644000175000017500000001256312142106414022253 0ustar frankiefrankie ProFTPD module mod_memcache

    ProFTPD module mod_memcache



    The mod_memcache module enables ProFTPD support for caching data in memcached servers, using the libmemcached client library. Note that libmemcached version 0.41 or later is required.

    Directives


    MemcacheEngine

    Syntax: MemcacheEngine on|off
    Default: MemcacheEngine off
    Context: "server config", <VirtualHost>, <Global>
    Module: mod_memcache
    Compatibility: 1.3.4rc2 and later

    The MemcacheEngine directive enables or disables the mod_memcache module, and thus the configuration of memcache support for the proftpd daemon.


    MemcacheLog

    Syntax: MemcacheLog path|"none"
    Default: None
    Context: "server config", <VirtualHost>, <Global>
    Module: mod_memcache
    Compatibility: 1.3.4rc2 and later

    The MemcacheLog directive is used to specify a log file for mod_memcache's reporting on a per-server basis. The file parameter given must be the full path to the file to use for logging.

    Note that this path must not be to a world-writable directory and, unless AllowLogSymlinks is explicitly set to on (generally a bad idea), the path must not be a symbolic link.


    MemcacheOptions

    Syntax: MemcacheOptions opt1 ... optN
    Default: None
    Context: "server config", <VirtualHost>, <Global>
    Module: mod_memcache
    Compatibility: 1.3.4rc2 and later

    The currently supported MemcacheOptions are:

    • NoBinaryProtocol


    MemcacheReplicas

    Syntax: MemcacheReplicas count
    Default: None
    Context: "server config", <VirtualHost>, <Global>
    Module: mod_memcache
    Compatibility: 1.3.4rc2 and later

    Experimental feature


    MemcacheServers

    Syntax: MemcacheServers servers
    Default: None
    Context: "server config", <VirtualHost>, <Global>
    Module: mod_memcache
    Compatibility: 1.3.4rc2 and later

    The MemcacheServers directive is used to configure the IP addresses/ports of the memcached servers that the mod_memcache module is to use. The list of servers is expressed as a space-delimited list. For example:

      MemcacheServers 1.2.3.4:11211 1.2.3.5:22422
    

    Alternatively, you can configure a Unix domain socket path using e.g.:

      MemcacheServers /var/run/memcached.sock
    


    MemcacheTimeouts

    Syntax: MemcacheTimeouts connect read write
    Default: None
    Context: "server config", <VirtualHost>, <Global>
    Module: mod_memcache
    Compatibility: 1.3.4rc2 and later

    Experimental feature


    Installation

    The mod_memcache module is distributed with ProFTPD. To enable support and use of the memcache protocol in your proftpd daemon, use the --enable-memcache configure option:
      # ./configure --enable-memcache ...
      # make
      # make install
    
    This option causes the mod_memcache module to be compiled into proftpd.

    You may also need to tell configure how to find the libmemcached header and library files:

      # ./configure --enable-memcache \
        --with-includes=/path/to/libmemcached/include \
        --with-libraries=/path/to/libmemcached/lib
    



    Author: $Author: castaglia $
    Last Updated: $Date: 2013/05/07 05:11:40 $


    © Copyright 2011-2013 The ProFTPD Project
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/modules/mod_facts.html0000644000175000017500000002033612050542376021617 0ustar frankiefrankie ProFTPD module mod_facts

    ProFTPD module mod_facts



    File "Facts" Support

    The mod_facts module is ProFTPD's module for handling the MLSD and MLST commands, in support of RFC 3659. In addition, the mod_facts module implements the MFF and MFMT commands defined in:

      http://tools.ietf.org/html/draft-somers-ftp-mfxx-04
    

    This module is contained in the mod_facts.c file for ProFTPD 1.3.x, and is compiled by default.

    The most current version of mod_facts can be found in the ProFTPD source distribution:

      http://www.proftpd.org/
    

    Directives


    FactsAdvertise

    Syntax: FactsAdvertise on|off
    Default: FactsAdvertise on
    Context: server config, <VirtualHost>, <Global>
    Module: mod_facts
    Compatibility: 1.3.2rc2 and later

    The FactsAdvertise directive is used to control whether the mod_facts module advertises its MLST support via the FEAT command.

    By default, the mod_facts module will list MLST in the FEAT response. FTP clients use this to determine whether to use the newer MLSD/MLST commands, or the older LIST/NLST commands. Some FTP clients, though, will attempt to use the newer commands just as if they were equivalent to the older commands, including supporting glob/wildcard characters. Section 2.2.2 of RFC3659, which explicitly states that wildcard characters are not supported in the MLSD and MLST commands. Thus, to prevent problems when using such FTP clients with proftpd, you can disable the advertising of support for those commands using e.g. the following in your proftpd.conf:

      <IfModule mod_facts.c>
        FactsAdvertise off
      </IfModule>
    

    FactsOptions

    Syntax: FactsOptions opt1 ...
    Default: None
    Context: server config, <VirtualHost>, <Global>
    Module: mod_facts
    Compatibility: 1.3.4b and later

    The FactsOptions directive is used to configure various optional behavior of mod_facts. Note: all of the configured FactsOptions parameters must appear on the same line in the configuration; only the first FactsOptions directive that appears in the configuration is used.

    The currently implemented options are:

    • UseSlink

      Use this option to have mod_facts use the broken "OS.unix=slink" syntax, preferred by FTP clients such as FileZilla, for indicating symlinks, rather than the more correct "OS.unix=symlink" syntax. See Bug#3318 for a more detailed discussion.

      Note that this option first appeared in proftpd-1.3.4b.

    Frequently Asked Questions

    Question: Why does MLSD list all of the files in a directory, including the "hidden" files, where the LIST command does not?
    Answer: The MLSD and MLST commands do not have any notions of "options" like the LIST and NLST commands do; there is no way for a client, in the request to list the files in a directory, to ask the server to filter the list of files somehow. Instead, MLSD contains a list of "facts" for each file in its list; the client then has to to decide how to filter the list of files based on those facts. This is why the ListOptions directive has no influence over the MLSD and MLST commands.

    Question: Why does MLST show the UIDs/GIDs for listed files, where LIST/NLST show the user/group names?
    Answer: The list of "facts" defined by RFC 3659 does not include a fact for the stringified version of user/group owner names, unfortunately. This means that the MLSD/MLST commands do not have a good way of obtaining the user/group names.

    To work around this issue, you can add the following to your proftpd.conf:

      <IfModule mod_facts.c>
        FactsAdvertise off
      </IfModule>
    
    This tells proftpd to not advertise to the client that it can support the MLSD/MLST commands. The client will then usually fall back to using the older LIST command, which does include the file owner user/group names.

    Question: Why does FileZilla not display symlinks properly, even though I have "ShowSymlinks on" in my proftpd.conf?
    Answer: Newer versions of FileZilla (and other FTP clients) use the MLSD command for listing files, rather than the older LIST command. And FileZilla and the mod_facts disagree on the proper syntax for indicating when a file is a symlink.

    To work around this issue, you can add the following to your proftpd.conf:

      <IfModule mod_facts.c>
        FactsOptions UseSlink
      </IfModule>
    
    This tells the mod_facts module to use the improper "OS.unix=slink:path" syntax for symlinks; this is the syntax preferred by FileZilla (and perhaps other FTP clients). By default, the mod_facts module uses the better "OS.unix=symlink" syntax.

    Question: How can I hide dotfiles (e.g. ".msg") from the MLSD command?
    Answer: There are two possible ways of dealing with FTP clients which use the MLSD command for listing directories, as opposed to the LIST/NLST commands.

    Since the MLSD command does not have the concept of "options", unlike LIST/NLST, the ListOptions directive does not apply to MLSD as some would expect. Thus using a configuration like so:

      ListOptions +a
    
    to hide dotfiles from LIST commands does not work for MLSD. How, then, to hide dotfiles from MLSD commands? You can configure proftpd so that it does not advertise the fact that it can support the MLSD command, via:
      <IfModule mod_facts.c>
        FactsAdvertise off
      </IfModule>
    
    Alternatively, you can use the HideFiles and IgnoreHidden directives:
      <Directory />
        # Hide files whose names start with "."
        HideFiles ^\.
    
        <Limit LIST MLSD NLST>
          # Do not include hidden files for LIST, MLSD, and NLST
          IgnoreHidden on
        </Limit>
      </Directory>
    
    This latter configuration will apply to LIST, NLST, and MLSD equally.



    Author: $Author: castaglia $
    Last Updated: $Date: 2012/11/13 22:09:02 $


    © Copyright 2007-2012 TJ Saunders
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/modules/mod_ctrls.html0000644000175000017500000002651312145443413021646 0ustar frankiefrankie ProFTPD module mod_ctrls

    ProFTPD module mod_ctrls



    This module is contained in the mod_ctrls.c and mod_ctrls.h files for ProFTPD 1.2, and is not compiled by default. Installation instructions are discussed
    here.

    This module implements the server side of a Unix domain socket, used for communication with a running proftpd daemon. The client used for this communication is ftpdctl, part of the Controls API. See the ftpdctl man page for details on using that program; details on the usage of this module follow the directive descriptions.

    The most current version of mod_ctrls can be found in the ProFTPD source distribution:

      http://www.proftpd.org/
    

    Author

    Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.

    Directives

    Control Actions


    Directives


    ControlsACLs

    Syntax: ControlsACLs actions|all allow|deny user|group list
    Default: None
    Context: server config
    Module: mod_ctrls
    Compatibility: 1.2.10rc1 and later

    The ControlsACLs directive configures access lists of users or groups who are allowed (or denied) the ability to use the actions implemented by mod_ctrls. The default behavior is to deny everyone unless an ACL allowing access has been explicitly configured.

    If "allow" is used, then list, a comma-delimited list of users or groups, can use the given actions; all others are denied. If "deny" is used, then the list of users or groups cannot use actions all others are allowed. Multiple ControlsACLs directives may be used to configure ACLs for different control actions, and for both users and groups.


    ControlsAuthFreshness

    Syntax: ControlsAuthFreshness seconds
    Default: ControlsAuthFreshness 10
    Context: server config
    Module: mod_ctrls
    Compatibility: 1.2.10rc1 and later

    The ControlsAuthFreshness directive configures the maximum age, in seconds, for the client's end of a connection. If the client-specific file is older than the configured age, the connection is denied.


    ControlsEngine

    Syntax: ControlsEngine on|off
    Default: ControlsEngine on
    Context: server config
    Module: mod_ctrls
    Compatibility: 1.2.10rc1 and later

    The ControlsEngine directive enables or disables the mod_ctrls module, and thus the processing of ftpdctl requests.


    ControlsInterval

    Syntax: ControlsInterval seconds
    Default: ControlsInterval 10
    Context: server config
    Module: mod_ctrls
    Compatibility: 1.2.10rc1 and later

    The ControlsInterval directives configures the interval at which mod_ctrls will check and handle pending ftpdctl action requests on the Controls socket. seconds must be a positive number.


    ControlsLog

    Syntax: ControlsLog file
    Default: None
    Context: server config
    Module: mod_ctrls
    Compatibility: 1.2.10rc1 and later

    The ControlsLog directive configures a file used for logging by mod_ctrls and possibly other Controls modules. The configured file must be an absolute path.


    ControlsMaxClients

    Syntax: ControlsMaxClients number
    Default: ControlsMaxClients 5
    Context: server config
    Module: mod_ctrls
    Compatibility: 1.2.10rc1 and later

    The ControlsMaxClients directive configures the maximum number of pending client requests that will be handled when mod_ctrls checks the socket. number must be a positive number.


    ControlsSocket

    Syntax: ControlsSocket file
    Default: ControlsSocket var/run/proftpd.sock
    Context: server config
    Module: mod_ctrls
    Compatibility: 1.2.10rc1 and later

    The ControlsSocket directive configures the file to be used as the Unix domain socket, rather than the default. file must be an absolute path. Note that if used, ftpdctl's -s option will also need to be used.


    ControlsSocketACL

    Syntax: ControlsSocketACL allow|deny user|group list
    Default: None
    Context: server config
    Module: mod_ctrls
    Compatibility: 1.2.10rc1 and later

    The ControlsSocketACL directive configures an access list of users or groups who are allowed (or denied) access to the Unix domain server socket used for receiving action requests. The default behavior is to deny everyone unless an ACL allowing access has been explicitly configured.

    If "allow" is used, then list, a comma-delimited list of users or groups, can use the control socket; all others are denied. If "deny" is used, then the list of users or groups cannot use the control socket; all others are allowed. A ControlsSocketACL directive with "user" and one using "group" may be used simultaneously.


    ControlsSocketOwner

    Syntax: ControlsSocketOwner user group
    Default: ControlsSocketOwner root root
    Context: server config
    Module: mod_ctrls
    Compatibility: 1.2.10rc1 and later

    The ControlsSocketOwner directive configures the ownership of the Unix domain socket file created when mod_ctrls starts up. The ownership of this file (and its mode) can also be used as a form of access control.


    Control Actions


    help

    Syntax: ftpdctl help
    Purpose: Display a sorted list of active controls and their descriptions

    The help control action can be used to obtain a sorted list of all active control actions, and their descriptions.


    insctrl

    Syntax: ftpdctl insctrl action|all [module]
    Purpose: Enable control actions

    The insctrl control action can be used to enable any disabled control action by name. The special "insctrl all" enables all disabled control actions. Once a specific action has been enabled (most control actions are enabled by default) , the "rmctrl" control action can be used to disable it.

    Example:

      ftpdctl insctrl debug
    


    lsctrl

    Syntax: ftpdctl lsctrl
    Purpose: Display a sorted list of all active control actions

    The lsctrl control action can be used obtain a sorted list of all active control actions. The list will include the name of the action as well as the module that implements that action.


    rmctrl

    Syntax: ftpdctl rmctrl action|all [module]
    Purpose: Disable control actions

    The rmctrl control action can be used to disable any registered control action by name, except for the actions registered by mod_ctrls: "insctrl", "lsctrl", and "rmctrl". The exception to this is the special "rmctrl all", which disables all actions and effectively turns mod_ctrls off. A daemon restart is then necessary to reenable actions. Once a specific action has been disabled, the "insctrl" control action can be used to reenable it.

    Example:

      ftpdctl rmctrl memory
    
    This disables all actions registered under the name "memory". If there was such an action registered by a specific module, mod_ctrls_common for example, that the administor wished to disable, but to leave the "memory" actions of other modules enabled:
      ftpdctl rmctrl memory mod_ctrls_common.c
    


    Usage

    The determination of "freshness" is part of determining client credentials. The method used by mod_ctrls comes from Stevens' Advanced Programming in the Unix Environment, chapter 15. Admittedly having kernel-provided client credentials would be much nicer, but portably obtaining them is next to impossible. On some flavors of Unix it simply cannot be done. Stevens' method is the next best thing right now.


    Installation

    The mod_ctrls module is distributed with ProFTPD. To enable use of Controls, use the --enable-ctrls configure option:
      ./configure --enable-ctrls
      make
      make install
    
    This option causes mod_ctrls to be compiled into proftpd.


    Author: $Author: castaglia $
    Last Updated: $Date: 2013/05/17 15:04:43 $


    © Copyright 2000-2011 TJ Saunders
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/modules/mod_auth_unix.html0000644000175000017500000002146311745304025022522 0ustar frankiefrankie ProFTPD module mod_auth_unix

    ProFTPD module mod_auth_unix



    This module is contained in the mod_auth_unix.c file for ProFTPD 1.3.x, and is compiled by default.

    Directives


    AuthUnixOptions

    Syntax: AuthUnixOptions opt1 ...
    Default: None
    Context: server config, <VirtualHost>, <Global>
    Module: mod_auth_unix
    Compatibility: 1.3.3rc2

    The AuthUnixOptions directive is used to tweak various Unix-specific authentication behaviors in mod_auth_unix. The currently implemented options are:

    • aixNoRLogin

      In Bug#1896, support for checking some AIX-specific functions for whether a login should be accepted was added; this happens only on AIX servers, of course.

      However, some AIX admins like to configure "rlogin=false", yet still want to allow FTP logins. To enable this specific behavior, a new AuthUnixOptions setting (only honored on AIX) was added:

              AuthUnixOptions aixNoRLogin
      
      If this setting is used on any other server, it is silently ignored. Bug#3300 has the full details.
    • magicTokenChroot

      This option causes mod_auth_unix to examine the home directory retrieved for a user for the magic "/./" token. If found, the portion of the directory before the token will be used for the chroot() for the process; the portion after the token will be the default directory for the process.

      Note that this will override any configured DefaultRoot and DefaultChdir directives.

      This option is intended for use for sites which are migrating from old wuftpd-based installations.

    • noGetgrouplist

      On systems which support it, the getgrouplist(3) function can be used to get the group membership list of a user in a much faster way. However, use of this function can have strange interactions with NSS modules, depending on the NSS modules used (see Bug#3475). Use this option to disable use of the getgrouplist(3) function, e.g.:

              AuthUnixOptions noGetgrouplist
      
      This setting has no effect on systems which do not support the getgrouplist(3) function.


    PersistentPasswd

    Syntax: PersistentPasswd on|off
    Default: None
    Context: server config, <VirtualHost>, <Global>
    Module: mod_auth_unix
    Compatibility: 1.2.0

    The PersistentPasswd directive controls how mod_auth_unix handles authentication, user/group lookups, and user/group to name mapping. If set to on, mod_auth_unix will attempt to open the system-wide /etc/passwd, /etc/group (and potentially /etc/shadow) files itself, holding them open even during a chroot()ed login. (Note that /etc/shadow is never held open, for security reasons).

    On some platforms, you must turn this option on, as the libc functions are incapable of accessing these databases from inside of a chroot(). At compile-time, the configure script will attempt to detect whether or not you need this support, and set the default accordingly.. However, such "guessing" may fail, and you will have to manually enable/disable the feature. If you cannot see user or group names when performing a directory listing inside a chroot()ed login, this indicates you must enable the directive. Use of the AuthUserFile or AuthGroupFile directives will force partial support for persistent user or group database files, regardless of PersistentPasswd's setting.

    Note: NIS/NIS+ and NSS users will most likely want to disable this feature, regardless of proftpd's detected configuration defaults. Failure to disable this will make your NIS/NIS+ maps and NSS lookups not work! On certain systems, you may also need to use the --enable-autoshadow option in order to authenticate both users from NIS maps or NSS lookups, and local users.


    Installation

    The mod_auth_unix module is compiled by default.

    Frequently Asked Questions

    Question: I found that only the first 8 characters of passwords are used! This is a security bug!
    Answer: No, it is not.

    The default Unix password hashing scheme uses the Data Encryption Standard (DES) algorithm. As per the crypt(3) man page, only the first 8 characters of the password are used. Thus this 8 character limitation comes from the underlying system authentication, not from proftpd. The whole purpose of the PAM system was to enable replacing the use of DES with other authentication algorithms, which do not have this 8 character limitation.

    Later, other crypt(3) implementations were made which can also support algorithms such as MD5, or Blowfish. Some platforms support these enhanced versions of crypt(3), some do not.

    Question: It appears that the handling of expired passwords by mod_auth_unix is wrong. Is this a bug?
    Answer: Not really. Different implementations have implemented expired passwords differently. One particular implementation even has special values, e.g. for the date of last password change:

    The value 0 has a special meaning, which is that the user should change her pasword the next time she will log in the system.

    These special cases vary from implementation to implementation; in the end, it is better to use the mod_auth_pam module and a PAM configuration which can better handle password expiration according to your site's needs.

    Question: I've added new user to my system (i.e. in the /etc/passwd file), but my proftpd does not see the new user until I have restarted it. Is there any way to not have to restart proftpd, to disable its caching of system users?
    Answer: ProFTPD is not caching system users, per se. Instead, this behavior is a side-effect of the
    PersistentPasswd setting. Check to see if you have:

      PersistentPasswd on
    
    in your proftpd.conf. If you do (or if you do not have PersistentPasswd in your config at all), then change your proftpd.conf to have:
      PersistentPasswd off
    

    Why is this necessary? When you use PersistentPasswd on, then proftpd will open a file descriptor on the system /etc/passwd file during server startup. This descriptor is kept open during the lifetime of the daemon. Later, when you add a new user to the system /etc/passwd file, the system tools create a new version of that file, then rename the new file to have the /etc/passwd name. But proftpd still has a descriptor to the old file, and does not see/know that the file has changed. That is why it can look like proftpd is "caching" your system users.



    Author: $Author: castaglia $
    Last Updated: $Date: 2012/04/23 16:49:25 $


    © Copyright 2010-2012
    All Rights Reserved


    proftpd-dfsg-1.3.5~rc3/doc/modules/mod_auth_pam.html0000644000175000017500000001257511536076641022330 0ustar frankiefrankie ProFTPD module mod_auth_pam

    ProFTPD module mod_auth_pam



    PAM stands for Pluggable Authentication Modules, and is used to configure ways for authenticating users. Now "authenticating" a user usually means comparing a password they give with some other information, and returning a "yes/no"-style answer. PAM does not provide all of the other information for a user, such as UID, GID, home, and shell. This means that mod_auth_pam cannot be used, by itself, as an auth module for proftpd; mod_auth_pam is used to supplement other auth modules by providing access to PAM's additional authentication checks.

    Installation instructions for mod_auth_pam can be found here.

    The most current version of mod_auth_pam is distributed in the ProFTPD source distribution.

    Directives


    AuthPAM

    Syntax: AuthPAM on|off
    Default: AuthPAM on
    Context: server config, <VirtualHost>, <Global>
    Module: mod_auth_pam
    Compatibility: 1.2.8rc2 and later

    The AuthPAM directive enables or disables the module's runtime PAM check. If it is set to off this module does not consult PAM when authenticating a user.


    AuthPAMConfig

    Syntax: AuthPAMConfig service
    Default: AuthPAMConfig ftp
    Context: server config, <VirtualHost>, <Global>
    Module: mod_auth_pam
    Compatibility: 1.2.8rc2 and later

    The AuthPAMConfig directive is used to specify the name of the service used when performing the PAM check; PAM configurations can vary depending on the service. By default, the "ftp" service is used. Note that on some platforms, e.g. FreeBSD, this may need to be set to "ftpd", depending on the PAM configuration involved.

    Here's an example of changing the service used:

      <IfModule mod_auth_pam.c>
        AuthPAMConfig ftpd
      </IfModule>
    


    AuthPAMOptions

    Syntax: AuthPAMOptions opt1 opt2 ... optN
    Default: None
    Context: server config, <VirtualHost>, <Global>
    Module: mod_auth_pam
    Compatibility: 1.3.2rc1 and later

    The AuthPAMOptions directive is used to configure various optional behavior of mod_auth_pam.

    Example:

      <IfModule mod_auth_pam.c>
        # Do not set the PAM_TTY token when authenticating via PAM
        AuthPAMOptions NoTTY
      </IfModule>
    

    The currently implemented options are:

    • NoTTY

      By default, mod_auth_pam will use the PAM_TTY PAM API item, and will use a value of "/dev/ftpdPID". The item can be used by PAM modules for filtering access, for example. This "NoTTY" option tells mod_auth_pam to not set the PAM_TTY item.

      Note: On Solaris platforms, the use of this PAM_TTY token is mandatory, and cannot be disabled. This is due to Solaris Bug ID 4250887.


    Installation

    The mod_auth_pam module is automatically included when proftpd is built on a system that supports PAM. To disable this automatic inclusion, use the --disable-auth-pam configure option.

    Frequently Asked Questions

    Question: I need to use PAM for enforcing the handling of aged/expired passwords on my Unix system. How do I make sure that PAM does the right thing?
    Answer: For this sort of requirement, you are probably already using ProFTPD's default authentication modules, which include mod_auth_unix and mod_auth_pam. But to make sure that the PAM rules are enforced, you need to make mod_auth_pam be "authoritative", i.e. have the final say on whether a given password is acceptable. Use the AuthOrder directive to accomplish this, using:

      # It is important that mod_auth_pam appear before mod_auth_unix, and
      # that the asterisk appear after the name, not before.
      AuthOrder mod_auth_pam.c* mod_auth_unix.c
    
    The asterisk ("*") after a module name in the AuthOrder directive is what tells proftpd to treat that module's results as authoritative.
    Last Updated: $Date: 2011/03/10 07:28:33 $

    proftpd-dfsg-1.3.5~rc3/doc/license.txt0000644000175000017500000000226011566550174017507 0ustar frankiefrankie/* * ProFTPD - FTP server daemon * Copyright (c) 1997, 1998 Public Flood Software * Copyright (c) 1999, 2000 MacGyver aka Habeeb J. Dihu * Copyright (c) 2001-2011 The ProFTPD Project team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * As a special exemption, The ProFTPD Project and other respective copyright * holders give permission to link this program with OpenSSL, and distribute * the resulting executable, without including the source code for OpenSSL in * the source distribution. */ proftpd-dfsg-1.3.5~rc3/doc/Configuration.html0000644000175000017500000205556412110266214021023 0ustar frankiefrankie Configuration Directive List
    Table of Contents
    1. List of Directives
    AccessDenyMsg -- Customise the response on failed authentication
    AccessGrantMsg -- Customise the response on successful authentication
    Allow -- Access control directive
    AllowAll -- Allow all clients
    AllowClass -- Class based allow rules
    AllowFilter -- Regular expression of command arguments to be accepted
    AllowForeignAddress -- Control the use of the PORT command
    AllowGroup -- Group based allow rules
    AllowLogSymlinks -- Permit logging to symlinked files
    AllowOverride -- Toggles handling of .ftpaccess files
    AllowOverwrite -- Enable files to be overwritten
    AllowRetrieveRestart -- Allow clients to resume downloads
    AllowStoreRestart -- Allow clients to resume uploads
    AllowUser -- User based allow rules
    AnonRatio -- Ratio directive
    AnonRejectPasswords -- Block certain anonymous user passwords
    AnonRequirePassword -- Make anonymous users supply a valid password
    Anonymous -- Define an anonymous server
    AnonymousGroup -- Treat group members as anonymous users
    AuthAliasOnly -- Allow only aliased login names
    AuthGroupFile -- Specify alternate group file
    AuthOrder -- Configure auth module checking order
    AuthPAM -- Enable/Disable PAM authentication
    AuthPAMConfig -- Select PAM service name
    AuthUserFile -- Specify alternate passwd file
    AuthUsingAlias -- Authenticate via Alias-name instead of mapped username
    Bind -- Bind the server or Virtualhost to a specific IP address [deprecated]
    ByteRatioErrMsg -- Ratio directive
    CapabilitiesEngine -- Enable/disable mod_cap
    CapabilitiesSet -- Configure the set of Linux capabilities processed
    CDPath -- Sets "search paths" for the cd command
    Class -- Define a class of client connections
    CommandBufferSize -- Limit the maximum command length
    CreateHome -- Create and populate users' home directories as needed
    CwdRatioMsg -- Ratio directive
    DebugLevel -- Set the debugging output level
    DefaultAddress -- Set the address for the server to listen on
    DefaultChdir -- Set starting directory for FTP sessions
    DefaultRoot -- Sets default chroot directory
    DefaultServer -- Set the default server
    DefaultTransferMode -- Set the default method of data transfer
    DeferWelcome -- Don't show welcome message until user has authenticated
    Define -- Initialises Defines for IfDefine
    DelayEngine -- Control the use of mod_delay
    DelayTable -- Sets the name and path of the file used as the timing table
    DeleteAbortedStores -- Enable automatic deletion of partially uploaded HiddenStores files
    Deny -- Access control directive
    DenyAll -- Deny all clients
    DenyClass -- Class based deny rules
    DenyFilter -- Regular expression of command arguments to be blocked
    DenyGroup -- Group based deny rules
    DenyUser -- User based deny rules
    Directory -- Directory-limited configuration directives
    DirFakeGroup -- Hide real file/directory group
    DirFakeMode -- Hide real file/directory permissions
    DirFakeUser -- Hide real file/directory owner
    DisplayChdir -- Set the file to display when entering a directory
    DisplayConnect -- Sets connect banner file
    DisplayFileTransfer -- FIXFIXFIX
    DisplayGoAway -- Set the file to display to a rejected connection
    DisplayLogin -- Set the file to display on login
    DisplayQuit -- Set the file to display on quit
    DisplayReadme -- Enable display of file modification times on a file pattern
    ExtendedLog -- Specify custom logfiles
    FileRatioErrMsg -- (docs incomplete)
    Global -- Set some directives to apply across the entire daemon
    Group -- Set the group the server normally runs as
    GroupOwner -- Change default group for new files and directories
    GroupPassword -- Set a group-wide password
    GroupRatio -- Ratio directive
    HiddenStores -- Enables more safe file uploads
    HideFiles -- Enable hiding of files based on regular expressions
    HideGroup -- Enable hiding of files based on group owner
    HideNoAccess -- Block the listing of directory entries to which the user has no access permissions
    HideUser -- Enable hiding of files based on user owner
    HostRatio -- Ratio directive
    IdentLookups -- Toggle ident lookups
    IfDefine -- To control the use of sections of the configuration
    IfModule -- Parse a section of config based on module name
    IgnoreHidden -- Treat 'hidden' files as if they don't exist
    Include -- Load additional configuration directives from a file
    LDAPAliasDereference -- Specify how LDAP alias dereferencing is done
    LDAPAttr -- Map LDAP Attributes to something non standard
    LDAPAuthBinds -- (docs incomplete)
    LDAPDefaultAuthScheme --  Set the authentication scheme/hash that is used when no leading {hashname} is present.
    LDAPDefaultGID --  Set the default GID to be assigned to users when no uidNumber attribute is found.
    LDAPDefaultUID --  Set the default UID to be assigned to users when no uidNumber attribute is found.
    LDAPDNInfo -- Set DN information to be used for initial bind
    LDAPDoAuth -- Enable LDAP authentication
    LDAPDoGIDLookups --  Enable LDAP lookups for user group membership and GIDs in directory listings
    LDAPDoQuotaLookups -- Enable LDAP quota limit support
    LDAPDoUIDLookups --  Enable LDAP lookups for UIDs in directory listings
    LDAPForceDefaultGID -- Force all LDAP-authenticated users to use the same GID.
    LDAPForceDefaultUID -- Force all LDAP-authenticated users to use the same UID.
    LDAPForceGeneratedHomedir --  Force all LDAP-authenticated users to use the default HomeDironDemand prefix/suffix.
    LDAPForceHomedirOnDemand --  Force all LDAP-authenticated users to use the default HomeDironDemand prefix/suffix. [deprecated]
    LDAPGenerateHomedir --  Enable the creation of user home directories on demand
    LDAPGenerateHomedirPrefix --  Enable the creation of user home directories on demand
    LDAPGenerateHomedirPrefixNoUsername -- (docs incomplete)
    LDAPGroups --  Enable LDAP lookups for user group membership and GIDs in directory listings
    LDAPHomedirOnDemand --  Enable the creation of user home directories on demand [deprecated]
    LDAPHomedirOnDemandPrefix --  Enable the creation of user home directories on demand [deprecated]
    LDAPHomedirOnDemandPrefixNoUsername -- (docs incomplete)
    LDAPHomedirOnDemandSuffix --  Specify an additional directory to be created inside a user's home directory on demand. [deprecated]
    LDAPNegativeCache -- Enable negative caching for LDAP lookups
    LDAPProtocolVersion -- Set the LDAP protocol version
    LDAPQueryTimeout -- Set a timeout for LDAP queries
    LDAPSearchScope -- Specify the search scope used in LDAP queries
    LDAPServer -- Specify the LDAP server to use for lookups
    LDAPUsers -- Enable LDAP authentication/user lookups
    LDAPUseTLS -- Enable TLS/SSL connections to the LDAP server.
    LeechRatioMsg -- Sets the 'over ratio' error message
    Limit -- Set the commands/actions to be controlled
    ListOptions -- Configure options used when listing directories
    LogFormat -- Specify a logging format
    LoginPasswordPrompt -- Configure to display the passwort prompt or not
    MasqueradeAddress -- Configure the server address presented to clients
    MaxClients -- Limits the number of users that can connect
    MaxClientsPerClass -- Limit the number of connections per class
    MaxClientsPerHost -- Limits the connections per client machine
    MaxClientsPerUser -- Limit the number of connections per userid
    MaxConnectionRate -- Maximum TCP socket connection rate
    MaxConnectionsPerHost -- Limits the unauthenticated connections per client machine
    MaxHostsPerUser -- Limit the number of connections per userid
    MaxInstances -- Sets the maximum number of child processes to be spawned
    MaxLoginAttempts -- Sets how many password attempts are allowed before disconnection
    MaxRetrieveFileSize -- Restrict size of downloaded files
    MaxStoreFileSize -- Restrict size of uploaded files
    MultilineRFC2228 -- Enable RFC2228 multiline response mode
    Order -- Configures the precedence of the Limit directives
    PassivePorts -- Specify the ftp-data port range to be used
    PathAllowFilter -- Only allow new files which match a specified pattern
    PathDenyFilter -- Disallow new files which match a specified pattern
    PersistentPasswd -- Sets handling of unix auth files
    PidFile -- Set the filepath to hold the pid of the master server
    Port -- Set the port for the control socket
    RadiusAcctServer -- Setup RADIUS accounting details
    RadiusAuthServer -- Setup RADIUS authenticator details
    RadiusEngine -- Enable RADIUS support
    RadiusLog -- Specify the logfile for reporting / debugging
    RadiusRealm -- Setup the authentication realm
    RadiusUserInfo -- Configure login information via RADIUS
    RatioFile -- Ratio directive
    Ratios -- (docs incomplete)
    RatioTempFile -- Ratio directive
    RequireValidShell -- Allow connections based on /etc/shells
    RewriteCondition -- Define a rule condition
    RewriteEngine -- Enable/disable mod_rewrite
    RewriteLock -- Set the filename for synchronization lockfile
    RewriteLog -- Specify a log file for mod_rewrite reporting
    RewriteMap -- Define a rewrite map
    RewriteRule -- Define a rewrite rule
    RLimitCPU -- Configure the maximum CPU time in seconds used by a process
    RLimitMemory -- Configure the maximum memory in bytes used by a process
    RLimitOpenFiles -- Configure the maximum number of open files used by a process
    RootLogin -- Permit root user logins
    RootRevoke -- Drop root privileges completely
    SaveRatios -- FIXME FIXME
    ScoreboardFile -- Sets the name and path of the scoreboard file
    ServerAdmin -- Set the address for the server admin
    ServerIdent -- Set the message displayed on connect
    ServerLog -- Configure logs on a per-server basis
    ServerName -- Configure the name displayed to connecting users
    ServerType -- Set the mode proftpd runs in
    SetEnv -- (docs incomplete)
    ShowSymlinks -- Toggle the display of symlinks
    SocketBindTight -- Controls how TCP/IP sockets are created
    SocketOptions -- Tune socket-level options
    SQLAuthenticate --  Specify authentication methods and what to authenticate
    Group Table Structure
    SQLAuthTypes -- Specify the allowed authentication types and their check order
    SQLBackend -- Set the SQL backend module
    SQLConnectInfo -- Specify connection information for the backend
    SQLDefaultGID -- Configure the default GID for users
    SQLDefaultHomedir -- Configure the default homedir
    SQLDefaultUID -- Configure the default UID for users
    SQLEngine -- Configure how mod_sql will operate
    SQLGroupInfo -- Configure the group table and fields that hold group information
    SQLGroupWhereClause -- Configure a WHERE clause for every group query
    SQLLog -- Log information to a database table
    SQLLogFile -- Specify a log file for mod_sql reporting and debugging
    SQLMinID -- Set SQLMinUserGID and SQLMinUserID in one place
    SQLMinUserGID -- Set a minimum GID
    SQLMinUserUID -- Set a minimum UID
    SQLNamedQuery -- Specify a query and an identifier for SQLShowInfo and SQLLog
    SQLNegativeCache -- Enable negative caching for SQL lookups
    SQLRatios -- (docs incomplete)
    SQLRatioStats -- (docs incomplete)
    SQLShowInfo -- Create a message to be sent to the user after any successful command
    SQLUserInfo -- Configure the user table and fields that hold user information
    SQLUserWhereClause -- Configure a WHERE clause for every user query<
    StoreUniquePrefix -- Set the prefix to be added to uniquely generated filenames
    SyslogFacility -- Set the facility level used for logging
    SyslogLevel -- Set the verbosity level of system logging
    SystemLog -- Redirect syslogging to a file
    TCPAccessFiles -- Sets the access files to use
    TCPAccessSyslogLevels -- Sets the logging levels for mod_wrap
    tcpBackLog -- Control the tcp backlog in standalone mode
    TCPGroupAccessFiles -- Sets the access files to use
    tcpNoDelay -- Control the use of TCP_NODELAY
    TCPServiceName -- Configures the name proftpd will use with mod_wrap
    TCPUserAccessFiles -- Sets the access files to use
    TimeoutIdle -- Sets the idle connection timeout
    TimeoutLinger -- Sets the timeout used for lingering closes
    TimeoutLogin -- Sets the login timeout
    TimeoutNoTransfer -- Sets the connection without transfer timeout
    TimeoutSession -- Sets a timeout for an entire session
    TimeoutStalled -- Sets the timeout on stalled data transfers
    TimesGMT -- Toggle time display between GMT and local
    TLSCACertificateFile -- Define a CA certificate used to verify your client certificates
    TLSCACertificatePath -- Define a path to the CAs used to verify your client certificates
    TLSCARevocationFile -- Define a file with your CA revocation certifcates
    TLSCARevocationPath -- Define a path to your CA revocation certificates
    TLSCertificateChainFile -- Define an all in one certification file
    TLSCipherSuite -- Define a cipher list
    TLSDHParamFile -- Define a file used in Diffie-Hellman key exchange
    TLSDSACertificateFile -- Point to the file containing the DSA certificate
    TLSDSACertificateKeyFile -- Point to the file containing the private DSA key
    TLSEngine -- Enable TLS/SSL connections
    TLSLog -- Specify a logfile for mod_tls's reporting on a per-server basis
    TLSOptions -- Configure optional behaviour of mod_tls
    TLSPassPhraseProvider -- FIXFIXFIX
    TLSProtocol -- Define the SSL/TLS protocol version mod_tls should use
    TLSRandomSeed -- Define a file for PRNG seeding
    TLSRenegotiate -- Configure SSL renegotiations
    TLSRequired -- Require SSL/TLS on the control and/or data channel
    TLSRSACertificateFile -- Point to the file containing the RSA certificate
    TLSRSACertificateKeyFile -- Point to the file containing the private RSA key
    TLSVerifyClient -- Configure how to candle certificates presented by clients -- 
    TLSVerifyDepth -- Define how deeply mod_tls should verify a client certificate
    TransferLog -- Specify the path to the transfer log
    TransferRate -- Configure upload, download transfer rates
    Umask -- Set the default Umask
    UnsetEnv -- (docs incomplete)
    UseFtpUsers -- Block based on /etc/ftpusers
    UseGlobbing -- Toggles use of glob() functionality
    UseIPv6 -- Disable IPv6 support
    User -- Set the user the daemon will run as
    UserAlias -- Alias a username to a system user
    UserDirRoot -- Set the chroot directory to a subdirectory of the anonymous server
    UseReverseDNS -- Toggle rDNS lookups
    UserOwner -- Set the user ownership of new files / directories
    UserPassword -- Creates a hardcoded username/password pair
    UserRatio -- Ratio directive
    UseSendfile -- Toggles use of sendfile() functionality
    UseUTF8 -- FIXFIXFIX
    VirtualHost -- Define a virtual ftp server
    WtmpLog -- Toggle logging to wtmp
    2. List of modules
    mod_auth -- Authentication module
    mod_core -- Core module
    mod_delay -- Prevent information leak through timing attacks
    mod_ldap -- LDAP authentication support
    mod_log -- Logging support
    mod_ls -- file listing functionality
    mod_radius -- RADIUS based authentication support
    mod_ratio -- FIX ME FIX ME
    mod_readme -- "README" file support
    mod_sql -- SQL support module
    mod_tls -- TLS/SSL support module
    mod_wrap -- Interface to libwrap
    mod_xfer -- FIX ME FIX ME
    3. List of configuration contexts
    server config -- server config
    Global -- Global
    VirtualHost -- VirtualHost
    Anonymous -- Anonymous
    Limit -- Limit
    .ftpaccess -- .ftpaccess

    Chapter 1. List of Directives

    AccessDenyMsg

    Name

    AccessDenyMsg -- Customise the response on failed authentication

    Synopsis

    AccessDenyMsg [ "message"]

    Default

    Dependent on login type

    Context

    server config, <VirtualHost>, <Anonymous>, <Global>

    Module

    mod_auth

    Compatibility

    1.2.2 and later

    Description

    Normally, a 530 response message is sent to an FTP client immediately after a failed authentication attempt, with a standard message indicating the the reason of failure. In the case of a wrong password, the reason is usually "Login incorrect." This message can be customized with the AccessDenyMsg directive. In the message argument, the magic cookie '%u' is replaced with the username specified by the client during login.

    See also

    Examples

    AccessDenyMsg "Guest access denied for %u."

    AccessGrantMsg

    Name

    AccessGrantMsg -- Customise the response on successful authentication

    Synopsis

    AccessGrantMsg [ "message"]

    Default

    Dependent on login type

    Context

    server config, <VirtualHost>, <Anonymous>, <Global>

    Module

    mod_auth

    Compatibility

    0.99.0pl5 and later

    Description

    Normally, a 230 response message is sent to an FTP client immediately after authentication, with a standard message indicating that the user has either logged in or that anonymous access has been granted. This message can be customized with the AccessGrantMsg directive. In the message argument, the magic cookie '%u' is replaced with the username specified by the client during login.

    See also

    Examples

    AccessGrantMsg "Guest access granted for %u."

    Allow

    Name

    Allow -- Access control directive

    Synopsis

    Allow [ ["from"] "all"|"none"|host|network[,host|network[,...]]]

    Default

    Allow from all

    Context

    <Limit>

    Module

    mod_core

    Compatibility

    0.99.0pl6 and later

    Description

    The Allow directive is used inside a <Limit> context to explicitly specify which hosts and/or networks have access to the commands or operations being limited. Allow is typically used in conjunction with Order and Deny in order to create sophisticated (or perhaps not-so-sophisticated) access control rules. Allow takes an optional first argument; the keyword from. Using from is purely cosmetic. The remaining arguments are expected to be a list of hosts and networks which will be explicitly granted access. The magic keyword all can be used to indicate that all hosts will explicitly be granted access (analogous to the AllowAll directive, except with a lower priority). Additionally, the magic keyword none can be used to indicate that no hosts or networks will be explicitly granted access (although this does not prevent them from implicitly being granted access). If all or none is used, no other hosts or networks can be supplied. Host and network addresses can be specified by name or numeric address. For security reasons, it is recommended that all address information be supplied numerically. Relying solely on named addresses causes security to depend a great deal upon DNS servers which may themselves be vulnerable to attack or spoofing. Numeric addresses which specify an entire network should end in a trailing period (i.e. 10.0.0. for the entire 10.0.0 subnet). Named addresses which specify an entire network should begin with a leading period (i.e. .proftpd.net for the entire proftpd.net domain).

    See also

    Allow Order Limit

    Examples

    <Limit LOGIN>
    Order allow,deny
    Allow from 128.44.26.,128.44.26.,myhost.mydomain.edu,.trusted-domain.org
    Deny from all
    </Limit>

    AllowAll

    Name

    AllowAll -- Allow all clients

    Synopsis

    AllowAll [ AllowAll]

    Default

    Default is to implicitly AllowAll, but not explicitly

    Context

    <Directory>, <Anonymous>, <Limit>, .ftpaccess

    Module

    mod_core

    Compatibility

    0.99.0 and later

    Description

    The AllowAll directive explicitly allows access to a <Directory>, <Anonymous> or <Limit> block. Although proftpd's default behavior is to allow access to a particular object, the default is an implicit allow. AllowAll creates an explicit allow, overriding any higher level denial directives.

    See also

    DenyAll

    Examples

    AllowClass

    Name

    AllowClass -- Class based allow rules

    Synopsis

    AllowClass [ ["AND"|"OR"|"regex"] class-expression]

    Default

    None

    Context

    <Limit>

    Module

    mod_core

    Compatibility

    1.2.10rc1 and later

    Description

    AllowClass specifies a class-expression that is specifically permitted access within the context of the <Limit> block it is applied to. class-expression has a similar syntax as that used in AllowGroup, in that it should contain a comma delimited list of classes or "not" classes (by prefixing a class name name with the `!' character) that are to be allowed access to the block.

    By default, the expression is parsed as a boolean "OR" list, meaning that ANY elements of the expression must evaluate to logically true in order to the explicit allow to apply. In order to treat the expression as a boolean "AND" list, meaning that ALL of the elements must evaluate to logically true, use the optional "AND" keyword. Similarly, to treat the expression as a regular expression, use the "regex" keyword.

    Examples

      # A regular expression AllowClass directive
      AllowClass regex ^known
    
      # An AND-evaluated ClassUser directive
      DenyClass AND bad,scanner

    AllowFilter

    Name

    AllowFilter -- Regular expression of command arguments to be accepted

    Synopsis

    AllowFilter [ regular-expression]

    Default

    None

    Context

    server config, <VirtualHost>, <Global>, <Anonymous>, <Directoryl>, .ftpaccess

    Module

    mod_core

    Compatibility

    1.2.0pre7 and later

    Description

    AllowFilter allows the configuration of a regular expression that must be matched for all command arguments sent to ProFTPD. It is extremely useful in controlling what characters may be sent in a command to ProFTPD, preventing some possible types of attacks against ProFTPD. The regular expression is applied against the arguments to the command sent by the client, so care must be taken when creating a proper regex. Commands that fail the regex match result in a "Forbidden command" error being returned to the client. If the regular-expression argument contains whitespace, it must be enclosed in quotes.

    See also

    DenyFilter

    Examples

    # Only allow commands containing alphanumeric characters and whitespace
    AllowFilter "^[a-zA-Z0-9 ,]*$"

    AllowForeignAddress

    Name

    AllowForeignAddress -- Control the use of the PORT command

    Synopsis

    AllowForeignAddress [ on|off ]

    Default

    AllowForeignAddress off

    Context

    server config, <VirtualHost>, <Anonymous>, <Global>

    Module

    mod_core

    Compatibility

    1.1.7 and later

    Description

    Normally, proftpd disallows clients from using the ftp PORT command with anything other than their own address (the source address of the ftp control connection), as well as preventing the use of PORT to specify a low-numbered (< 1024) port. In either case, the client is sent an "Invalid port" error and a message is syslog'd indicating either "address mismatch" or "bounce attack". By enabling this directive, proftpd will allow clients to transmit foreign data connection addresses that do not match the client's address. This allows such tricks as permitting a client to transfer a file between two FTP servers without involving itself in the actual data connection. Generally it's considered a bad idea, security-wise, to permit this sort of thing. AllowForeignAddress only affects data connection addresses; not tcp ports. There is no way (and no valid reason) to allow a client to use a low-numbered port in its PORT command.

    See also

    Examples

    AllowGroup

    Name

    AllowGroup -- Group based allow rules

    Synopsis

    AllowGroup [ ["AND"|"OR"|"regex"] group-expression]

    Default

    None

    Context

    <Limit>

    Module

    mod_core

    Compatibility

    1.1.1 and later

    Description

    AllowGroup specifies a group-expression that is specifically permitted within the context of the <Limit> block it is applied to. group-expression has the same format as that used in DefaultRoot, in that it should contain a comma separated list of groups or "not" groups (by prefixing a group name with the `!' character) that are to be allowed access to the block.

    By default, the expression is parsed as a boolean "AND" list, meaning that ALL elements of the expression must evaluate to logically true in order to the explicit allow to apply. In order to treat the expression as a boolean "OR" list, meaning that ANY of the elements must evaluate to logically true, use the optional "OR" keyword. Similarly, to treat the expression as a regular expression, use the "regex" keyword.

    Examples

      # An OR-evaluated AllowGroup directive
      AllowGroup OR www,doc
    
      # A regular expression DenyGroup directive
      DenyGroup regex ^sys

    AllowLogSymlinks

    Name

    AllowLogSymlinks -- Permit logging to symlinked files

    Synopsis

    AllowLogSymlinks [ "on"|"off"]

    Default

    AllowLogSymlinks off

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_log

    Compatibility

    1.2.2rc2 and later

    Description

    By default, the server will the path of any configured SystemLog, any configured TransferLogs, and any configured ExtendedLogs to see if they are symbolic links. If the paths are symbolic links, the server will refuse to log to that link unless explicitly configured to do so via this directive.

    Security note:

    Security note: this behaviour should not be allowed unless for a very good reason. By allowing the server to open symbolic links with its root privileges, you are allowing a potential symlink attack where the server could be tricked into overwriting arbitrary system files. You have been warned.

    See also

    Examples

    AllowLogSymlinks on

    AllowOverride

    Name

    AllowOverride -- Toggles handling of .ftpaccess files

    Synopsis

    AllowOverride [ on|off ["user"|"group"|"class" expression]]

    Default

    on

    Context

    server config, <Global>, <VirtualHost>, <Anonymous>

    Module

    mod_core

    Compatibility

    1.2.7rc1 and later

    Description

    Normally, the server will look for and parse any files in the encountered directories called ".ftpaccess". The files provide a functionality similar to Apache's .htaccess files -- mini-configuration files. This directive controls when those .ftpaccess files will be parsed.

    The optional parameters are used to restrict the use of .ftpaccess files only to specific users. If the "user" restriction is given, then expression is a user-expression specifying to which users the rule applies. Similarly for the "group" restriction. For the "class" restriction, the expression is simply the name of connection class for whom the rule will apply.

    See also

    AllowOverwrite

    Name

    AllowOverwrite -- Enable files to be overwritten

    Synopsis

    AllowOverwrite [ on|off]

    Default

    AllowOverwrite off

    Context

    server config, <VirtualHost>, <Anonymous>, <Directory>, <Global>, .ftpaccess

    Module

    mod_xfer

    Compatibility

    0.99.0 and later

    Description

    The AllowOverwrite directive permits newly transfered files to overwrite existing files. By default, ftp clients cannot overwrite existing files.

    See also

    Examples

    AllowRetrieveRestart

    Name

    AllowRetrieveRestart -- Allow clients to resume downloads

    Synopsis

    AllowRetrieveRestart [ on|off]

    Default

    AllowRetrieveRestart on

    Context

    server config, <VirtualHost>, <Anonymous>, <Directory>, <Global>, .ftpaccess

    Module

    mod_core

    Compatibility

    0.99.0 and later

    Description

    The AllowRetrieveRestart directive permits or denies clients from performing "restart" retrieve file transfers via the FTP REST command. By default this is enabled, so that clients may resume interrupted file transfers at a later time without losing previously collected data.

    Examples

    AllowStoreRestart

    Name

    AllowStoreRestart -- Allow clients to resume uploads

    Synopsis

    AllowStoreRestart [ on|off]

    Default

    AllowStoreRestart off

    Context

    server config, <VirtualHost>, <Anonymous>, <Directory>, <Global>, .ftpaccess

    Module

    mod_core

    Compatibility

    0.99.0 and later

    Description

    The AllowStoreRestart directive permits or denies clients from "restarting" interrupted store file transfers (those sent from client to server). By default restarting (via the REST command) is not permitted when sending files to the server. Care should be taken to disallow anonymous ftp "incoming" transfers to be restarted, as this will allow clients to corrupt or increase the size of previously stored files (even if not their own).

    The REST (Restart STOR) command is automatically blocked when HiddenStores is enabled, with the server returning a 501 error code to the client.

    Examples

    AllowUser

    Name

    AllowUser -- User based allow rules

    Synopsis

    AllowUser [ ["AND"|"OR"|"regex"] user-expression]

    Default

    None

    Context

    <Limit>

    Module

    mod_core

    Compatibility

    1.1.7 and later

    Description

    AllowUser specifies a user-expression that is specifically permitted access within the context of the <Limit> block it is applied to. user-expression has a similar syntax as that used in AllowGroup, in that it should contain a comma delimited list of users or "not" users (by prefixing a user name with the `!' character) that are to be allowed access to the block.

    By default, the expression is parsed as a boolean "OR" list, meaning that ANY elements of the expression must evaluate to logically true in order to the explicit allow to apply. In order to treat the expression as a boolean "AND" list, meaning that ALL of the elements must evaluate to logically true, use the optional "AND" keyword. Similarly, to treat the expression as a regular expression, use the "regex" keyword.

    Examples

      # A regular expression AllowUser directive
      AllowUser regex ^ftp
    
      # An AND-evaluated DenyUser directive
      DenyUser AND system,test

    AnonRatio

    Name

    AnonRatio -- Ratio directive

    Synopsis

    AnonRatio [ foo1 foo2 foo3]

    Default

    None known

    Context

    <Directory>, <Anonymous>, <Limit>,.ftpaccess

    Module

    mod_ratio

    Compatibility

    at least 1.2.0 and later

    Description

    The AnonRatio directive ....

    See also

    AnonRatio

    Examples

    AnonRejectPasswords

    Name

    AnonRejectPasswords -- Block certain anonymous user passwords

    Synopsis

    AnonRejectePasswords [ regex]

    Default

    None

    Context

    <Anonymous>

    Module

    mod_auth

    Compatibility

    1.2.9rc1 and later

    Description

    The AnonRejectPasswords directive configures a regular expression filter for passwords given for anonymous logins. If the given anonymous password matches the configured regular expression, the anonymous login is denied.

    Examples

      # Reject all <Anonymous> logins that use "evil.org" as part of the password
      AnonRejectPasswords @evil\.org$

    AnonRequirePassword

    Name

    AnonRequirePassword -- Make anonymous users supply a valid password

    Synopsis

    AnonRequirePassword [ on|off]

    Default

    AnonRequirePassword off

    Context

    <Anonymous>

    Module

    mod_auth

    Compatibility

    0.99.0 and later

    Description

    Normally, anonymous FTP logins do not require the client to authenticate themselves via the normal method of a transmitted cleartext password which is hashed and matched against an existing system user's password. Instead, anonymous logins are expected to enter their e-mail address when prompted for a password. Enabling the AnonRequirePassword directive requires anonymous logins to enter a valid password which must match the password of the user that the anonymous daemon runs as. However using AuthUsingAlias authentication can be matched against the password of the login username. This can be used to create "guest" accounts, which function exactly as normal anonymous logins do (and thus present a "chrooted" protected file system to the client), but require a valid password on the server's host system.

    Anonymous

    Name

    Anonymous -- Define an anonymous server

    Synopsis

    Anonymous [ root-directory]

    Default

    None

    Context

    server config,<VirtualHost>, <Global>

    Module

    mod_core

    Compatibility

    0.99.0 and later

    Description

    The Anonymous configuration block is used to create an anonymous FTP login, and is terminated by a matching </Anonymous> directive. The root-directory parameters specifies which directory the daemon will first chdir to, and then chroot, immediately after login. Once the chroot operation successfully completes, higher level directories are no longer accessible to the running child daemon (and thus the logged in user). By default, proftpd assumes an anonymous login if the remote client attempts to login as the currently running user; unless the current user is root, in which case anonymous logins are not allowed regardless of the presence of an <Anonymous> block. To force anonymous logins to be bound to a user other than the current user, see the User and Group directives. In addition, if a User or Group directive is present in an <Anonymous> block, the daemon permanently switches to the specified uid/gid before chroot()ing. Normally, anonymous logins are not required to authenticate with a password, but are expected to enter a valid e-mail address in place of a normal password (which is logged). If this behavior is undesirable for a given <Anonymous> configuration block, it can be overridden via the AnonRequirePassword directive.

    Note: Chroot()ed anonymous directories do not need to have supplemental system files in them, nor do they need to have any sort of specific directory structure. This is because proftpd is designed to acquire as much system information as possible before the chroot, and to leave open those files which are needed for normal operation and reside outside the new root directory.

    See also

    Examples

    Example of a typical anonymous FTP configuration:
    
    <Anonymous /home/ftp>
      # After anonymous login, daemon runs as user/group ftp.
      User ftp
      Group ftp
    
      # The client login 'anonymous' is aliased to the "real" user 'ftp'.
      UserAlias anonymous ftp
    
      # Deny write operations to all directories, except for 'incoming' where 
      # 'STOR' is allowed (but 'READ' operations are prohibited)
    
      <Directory *>
        <Limit WRITE>
          DenyAll
        </Limit>
      </Directory>
    
      <Directory incoming>
        <Limit READ >
          DenyAll
        </Limit>
        <Limit STOR>
          AllowAll
        </Limit>
      </Directory>
    
    </Anonymous>

    AnonymousGroup

    Name

    AnonymousGroup -- Treat group members as anonymous users

    Synopsis

    AnonymousGroup [ group-expression]

    Default

    None

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_core

    Compatibility

    1.1.3 and later

    Description

    The AnonymousGroup directive specifies a group-expression to which all matching users will be considered anonymous logins. The group-expression argument is a boolean logically ANDed list of groups to which the user must be a member of (or non-member if the group name is prefixed with a `!' character). For more information on group-expressions see the DefaultRoot directive. If the authenticating user is matched by an AnonymousGroup directive, no valid password is required, and a special dynamic anonymous configuration is created, with the user's home directory as the default root directory. If a DefaultRoot directive also applies to the user, this directory is used instead of the user's home dir. Great care should be taken when using AnonymousGroup, as improper configuration can open up user home directories to full read/write access to the entire world.

    Examples

    AuthAliasOnly

    Name

    AuthAliasOnly -- Allow only aliased login names

    Synopsis

    AuthAliasOnly [ on|off]

    Default

    AuthAliasOnly off

    Context

    server config, <VirtualHost>, <Anonymous>, <Global>

    Module

    mod_auth

    Compatibility

    1.1.3 and later

    Description

    AuthAliasOnly restricts authentication to "aliased" logins only; i.e. those usernames provided by clients which are "mapped" to a real userid by the UserAlias directive. Turning AuthAliasOnly `on' in a particular context will cause proftpd to completely ignore all non-aliased logins for the entire context. If no contexts are available without AuthAliasOnly set to `on', proftpd rejects the client login and sends an appropriate message to syslog.

    Examples

    AuthGroupFile

    Name

    AuthGroupFile -- Specify alternate group file

    Synopsis

    AuthGroupFile [ path]

    Default

    None

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_auth_file

    Compatibility

    1.0.3/1.1.1 and later

    Description

    AuthGroupFile specifies an alternate groups file, having the same format as the system /etc/group file, and if specified is used during authentication and group lookups for directory/access control operations. The path argument should be the full path to the specified file. AuthGroupFile can be configured on a per-VirtualHost basis, so that virtual FTP servers can each have their own authentication database (most often used in conjunction with AuthUserFile).

    Note that this file need not reside inside a chroot()ed directory structure for Anonymous or DefaultRoot logins, as it is held open for the duration of client connections.

    See also

    AuthUserFile

    Examples

    AuthOrder

    Name

    AuthOrder -- Configure auth module checking order

    Synopsis

    AuthOrder [ module-name...]

    Default

    None

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_core

    Compatibility

    1.2.8rc1 and later

    Description

    The AuthOrder directive configures the names of auth modules, and the order in which they will be checked when authenticating a user.

    At least one module name must be given; there is no maximum number of modules that can be listed. The listed module names must the full name of the source file, e.g. "mod_auth_unix.c". To see a full list of module names, use "proftpd -l". Do not use "mod_auth.c", as that module is the authentication front end module, and is necessary.

    You can make an auth module be "authoritative" by appending an asterisk (*) after the module name. Usually this is done for the "mod_auth_pam.c" module, to ensure that the login fails if the PAM check fails.

    Examples

      # Use only AuthUserFiles when authenticating, and not the system's /etc/passwd
      AuthOrder mod_auth_file.c
      # If the user's information is not in LDAP, they're not a user to use
      # this server.
      AuthOrder mod_ldap.c
      # Use SQL tables first, then LDAP, for authentication
      AuthOrder mod_sql.c mod_ldap.c
      # Use the normal system /etc/passwd and PAM, but make sure that PAM is
      # authoritative about accepting or rejecting the login
      AuthOrder mod_auth_pam.c* mod_auth_unix.c

    AuthPAM

    Name

    AuthPAM -- Enable/Disable PAM authentication

    Synopsis

    AuthPAM [ on|off]

    Default

    on

    Context

    server config,<VirtualHost>, <Global>

    Module

    mod_auth_pam

    Compatibility

    1.2.0rc1 and later

    Description

    This directive determines whether PAM is used as an authentication method by ProFTPD. Enabled by default to fit in with the design policy of using PAM as the primary authentication mechanism.

    See also

    Examples

    AuthPAMConfig

    Name

    AuthPAMConfig -- Select PAM service name

    Synopsis

    AuthPAMConfig [ service]

    Default

    ftp

    Context

    server config,<VirtualHost>, <Global>

    Module

    mod_auth_pam

    Compatibility

    1.2.0rc1 and later

    Description

    This directive allows you to specify the PAM service name used in authentication. PAM allows you to specify a service name to use when authenticating. This allows you to configure different PAM service names to be used for different virtual hosts. The directive was renamed from PAMConfig post 1.2.0 pre10.

    See also

    Examples

    # Virtual host foobar authenticates differently than the rest
    
    AuthPAMConfig foobar
    
    # This assumes, that you have a PAM service named foobar
    # configured in your /etc/pam.conf file or /etc/pam.d directory. 

    AuthUserFile

    Name

    AuthUserFile -- Specify alternate passwd file

    Synopsis

    AuthUserFile [ path]

    Default

    None

    Context

    server config,<VirtualHost>, <Global>

    Module

    mod_auth_file

    Compatibility

    1.0.3/1.1.1 and later

    Description

    AuthUserFile specifies an alternate passwd file, having the same format as the system /etc/passwd file, and if specified is used during authentication and user lookups for directory/access control operations. The path argument should be the full path to the specified file. AuthUserFile can be configured on a per-VirtualHost basis, so that virtual FTP servers can each have their own authentication database (most often used in conjunction with AuthGroupFile).

    Note that this file need not reside inside a chroot()ed directory structure for Anonymous or DefaultRoot logins, as it is held open for the duration of client connections.

    Examples

    AuthUsingAlias

    Name

    AuthUsingAlias -- Authenticate via Alias-name instead of mapped username

    Synopsis

    AuthUsingAlias [ on|off]

    Default

    AuthUsingAlias off

    Context

    <Anonymous>

    Module

    mod_auth

    Compatibility

    1.2.0pre9 and later

    Description

    AuthUsingAlias disables the resolving of mapped usernames for authentication purposes. For example, if you have mapped the username anonymous to the "real" user ftp, the password gets checked against the user "anonymous". When AuthUsingAlias is disabled, the checked username would be "ftp".

    Examples

    An example of an Anonymous configuration using
    AuthUsingAlias
    # Basic Read-Only Anonymous Configuration.
    <Anonymous /home/ftp>
    UserAlias             anonymous  nobody
    UserAlias             ftp        nobody
    AuthAliasOnly         on
    <Limit WRITE>
    DenyAll
    </Limit>
    </Anonymous>
    # Give Full Read-Write Anonymous Access to certain users
    <Anonymous /home/ftp>
    AnonRequirePassword   on
    AuthAliasOnly         on
    AuthUsingAlias        on
    # The list of authorized users.
    # user/pass lookup is for each user, not password entry
    # of server uid ('nobody' in this example).
    UserAlias             fred       nobody
    UserAlias             joe        nobody
    <Limit ALL>
    AllowAll
    </Limit>
    </Anonymous>

    Bind

    Name

    Bind -- Bind the server or Virtualhost to a specific IP address [deprecated]

    Synopsis

    Bind [ IP address]

    Default

    None

    Context

    server config, <VirtualHost>

    Module

    mod_core

    Compatibility

    1.1.6 - 1.3.0rc1

    Description

    Cause of too much confusion this directive has been deprecated with ProFTPD 1.3.0rc1. Please take a look at the VirtualHost and DefaultAddress directive. The Bind directive allows additional IP addresses to be bound to a main or VirtualHost configuration. Multiple Bind directives can be used to bind multiple addresses. The address argument should be either a fully qualified domain name or a numeric dotted-quad IP address. Incoming connections destined to an additional address added by Bind are serviced by the context containing the directive. Additionally, if SocketBindTight is set to on, a specific listen connection is created for each additional address.

    Examples

    ByteRatioErrMsg

    Name

    ByteRatioErrMsg -- Ratio directive

    Synopsis

    ByteRatioErrMsg [ foo1 foo2 foo3]

    Default

    None known

    Context

    <Directory>, <Anonymous>, <Limit>,.ftpaccess

    Module

    mod_ratio

    Compatibility

    at least 1.2.0 and later

    Description

    The ByteRatioErrMsg directive .... Example: ByteRatioErrMsg

    See also

    Examples

    CapabilitiesEngine

    Name

    CapabilitiesEngine -- Enable/disable mod_cap

    Synopsis

    CapabilitiesEngine [ on off]

    Default

    CapabilitiesEngine On, if running on a Linux hosts that supports capabilities

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_cap

    Compatibility

    1.2.8rc1 and later

    Description

    The CapabilitiesEngine directive enables or disables the module's runtime capabilities engine. If set to off, this module does no runtime capabilities processing at all. Use this directive to disable the module.

    CapabilitiesSet

    Name

    CapabilitiesSet -- Configure the set of Linux capabilities processed

    Synopsis

    CapabilitiesSet [ [+/-]capability...]

    Default

    CapabilitiesSet +CAP_CHOWN

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_cap

    Compatibility

    1.2.8rc1 and later

    Description

    By default, mod_cap removes all but two capabilities from the session-handling process: CAP_NET_BIND_SERVICE, for binding to ports lower than 1024 (required for active data transfers), and CAP_CHOWN, for allowing a process to change a file's ownership to a different user. The latter capability is only strictly necessary if the UserOwner configuration directive is in use; if not being used, the CAP_CHOWN capability is best removed. The CapabilitiesSet directive is used to manipulate the set of capabilities that mod_cap grants.

    To remove a capability, prefix the name with a '-'; to enable a capability, use '+'. At present, this directive only supports one capability: CAP_CHOWN.

    Example

    <IfModule mod_cap.c> CapabilitiesEngine on CapabilitiesSet -CAP_CHOWN </IfModule>

    CDPath

    Name

    CDPath -- Sets "search paths" for the cd command

    Synopsis

    CDPath [ directory]

    Default

    None

    Context

    server config, <VirtualHost>, <Anonymous>, <Global>

    Module

    mod_core

    Compatibility

    1.2.0pre2 and later

    Description

    Adds an entry to a search path that is used when changing directories. For example: CDPath /home/public CDPath /var/devel This allows a user to cd into any directory directly under /home/public or /var/devel, provided they have the appropriate rights. So, if /home/public/proftpd exists, cd proftpd will bring the user to that directory, regardless of where they currently are in the directory tree.

    See also

    Examples

    Class

    Name

    Class -- Define a class of client connections

    Synopsis

    VirtualHost [ <Class name>]

    Default

    None

    Context

    server config

    Module

    mod_core

    Compatibility

    1.2.10rc1 and later

    Description

    When configuring proftpd, it is sometimes nice, or even necessary, to tag or label a client as belonging to some group, based on that client's IP address or DNS hostname. A "class" is the name for such connection-based groupings in ProFTPD terms. A class is defined to have a name, and as having certain criteria such as IP addresses, IP subnets/masks, and DNS hostnames. A client that connects to the daemon that has matching characteristics is then labeled as belonging to that class.

    Within a <Class> section, the From directive is used to list the IP addresses, IP subnet/masks, and DNS names that make up the class.

    See also

    From

    Examples

       From 192.168.0.0/16

    This defines a class named "internal"; any client connecting from 192.168.0.0/16 will belong to this class. And if you wanted to define a class for all clients not connecting from 192.168.0.0/16 address space:

       From !192.168.0.0/16

    A more complicated class might include matching DNS names as well:

       From 1.2.3.4 From proxy.*.com From my.example.com From 5.6.7.8

    CommandBufferSize

    Name

    CommandBufferSize -- Limit the maximum command length

    Synopsis

    CommandBufferSize [ size]

    Default

    512

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_core

    Compatibility

    1.2.0pre7 and later

    Description

    The CommandBufferSize directive controls the maximum command length permitted to be sent to the server. This allows you to effectively control what the longest command the server may accept it, and can help protect the server from various Denial of Service or resource-consumption attacks.

    See also

    Examples

    CreateHome

    Name

    CreateHome -- Create and populate users' home directories as needed

    Synopsis

    CreateHome [ off|on [<mode>] [skel <path>] [dirmode <mode>] [uid <uid>] [gid <gid>]]

    Default

    None

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_auth

    Compatibility

    1.2.8rc2 and later

    1.3.1rc1 and later for uid, gid arguments

    Description

    The CreateHome directive configures the server to automatically create a user's home directory, if that directory does not exist, during the login process.

    The mode parameter is used to configure the absolute mode of the home directory created. If not specified, the module will default to 700.

    The optional skel path parameter can be used to configure an /etc/skel-like directory containing account initialization files and directories. The parameter must be the full path to the directory. The directory must not be world-writeable. Files copied from this directory into the new home directory will have the UID and GID of the logging-in user. Note that sockets and FIFOs in the skeleton directory will not be copied; any setuid or setgid bits on files will be removed from the copied files in the target home directory.

    The optional dirmode, uid, and gid parameters can be used to specify the mode, owner, and group for intermediate directories that may need to be created in order to create the target home directory. By default, the mode for such intermediate directories will be 711. NOTE: using a mode that does not allow for the execute bit to be enabled can cause havoc. You have been warned.

    Examples

    # Use the CreateHome default settings CreateHome on

    # Specify a skeleton directory CreateHome on skel /etc/ftpd/skel

    # No skeleton, but make sure that intermediate directories have 755 # permissions. CreateHome on dirmode 755

    # Skeleton directory, with 700 intermediate directories CreateHome on skel /etc/ftpd/skel dirmode 700

    CwdRatioMsg

    Name

    CwdRatioMsg -- Ratio directive

    Synopsis

    CwdRatioMsg [ foo1 foo2 foo3]

    Default

    None known

    Context

    <Directory>, <Anonymous>, <Limit>,.ftpaccess

    Module

    mod_ratio

    Compatibility

    at least 1.2.0 and later

    Description

    The CwdRatioMsg directive .... Example: CwdRatioMsg

    See also

    Examples

    DebugLevel

    Name

    DebugLevel -- Set the debugging output level

    Synopsis

    DebugLevel [ level]

    Default

    DebugLevel 0

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_core

    Compatibility

    1.2.8rc1 and later

    Description

    The DebugLevel directive configures the debugging level the server will use when logging. The level parameter must be between 0 (lowest) and 10 (highest). This configuration directive will take precedence over any command-line debugging options used.

    DefaultAddress

    Name

    DefaultAddress -- Set the address for the server to listen on

    Synopsis

    DefaultAddress [ dns-names|ip-addresses seperated with spaces]

    Default

    none

    Context

    server config

    Module

    mod_core

    Compatibility

    1.2.7rc1 and later

    Description

    This directive sets the the address the main server instance will bind to, the default behaviour is to select whatever IP the system reports as being the primary IP.

    Starting with ProFTPD 1.3.0rc1 it's possible to use more than one FQDN or IP Address. With this change the old Bind directive has been deprecated.

    See also

    VirtualHost

    Examples

    ServerName "Default FTP Server"
    Port 21

    # We want the main server instance to listen on a specific IP
    DefaultAddress 192.168.10.30

    ## Since 1.3.0rc1 it's also possible to use the following:
    # DefaultAddress 192.168.10.30 my.domain.tld

    DefaultChdir

    Name

    DefaultChdir -- Set starting directory for FTP sessions

    Synopsis

    DefaultChdir [ directory [group-expression]]

    Default

    ~

    Context

    server config, <VirtualHost>, <Anonymous>, <Global>

    Module

    mod_auth

    Compatibility

    1.2.0pre2 and later

    Description

    Determines the directory a user is placed in after logging in. By default, the user is put in their home directory. The specified directory can be relative to the user's home directory. NOTE: If the specified directory is not available then DefaultChdir is treated as if it wasn't there in the first place. In particular, in this case the directory a user is placed in after logging in is determined by the other settings in proftpd.conf.

    See also

    DefaultRoot

    Examples

    DefaultRoot

    Name

    DefaultRoot -- Sets default chroot directory

    Synopsis

    DefaultRoot [ directory [group-expression]]

    Default

    DefaultRoot /

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_auth

    Compatibility

    0.99.0pl7 and later

    Description

    The DefaultRoot directive controls the default root directory assigned to a user upon login. If DefaultRoot is set to a directory other than "/", a chroot operation is performed immediately after a client authenticates. This can be used to effectively isolate the client from a portion of the host system filespace. The specified root directory must begin with a / or can be the magic character '~'; meaning that the client is chroot jailed into their home directory.

    When the specified chroot directory is a symlink this will be resolved to it's parent first before setting up the chroot. This can have unwanted side effects. For example if a user has write access to the symlink he could modify it so that it points to '/'. Thus the chroot would be the root directory of the server, resulting in insufficient or no restrictions.

    If the DefaultRoot directive specifies a directory which disallows access to the logged-in user's home directory, the user's current working directory after login is set to the DefaultRoot instead of their normal home directory. DefaultRoot cannot be used in <Anonymous> configuration blocks, as the <Anonymous> directive explicitly contains a root directory used for Anonymous logins. The special character '~' is replaced with the authenticating user's home directory immediately after login. Note that the default root may be a subdirectory of the home directory, such as "~/anon-ftp".

    The optional group-expression argument can be used to restrict the DefaultRoot directive to a unix group, groups or subset of groups. The expression takes the format: [!]group-name1[,[!]group-name2[,...]]. The expression is parsed in a logical boolean AND fashion, such that each member of the expression must evaluate to logically TRUE in order for the DefaultRoot directive to apply. The special character '!' is used to negate group membership.

    Care should be taken when using DefaultRoot. Chroot "jails" should not be used as methods for implementing general system security as there are potentially ways that a user can "escape" the jail.

    See also

    Examples

    Example of a DefaultRoot configuration:
    
    ServerName "A test ProFTPD Server"
    ServerType inetd
    User ftp
    Group ftp
    #
    # This causes proftpd to perform a chroot into the authenticating user's directory 
    # immediately after login.
    # Once this happens, the user is unable to "see" higher level directories.
    # Because a group-expression is included, only users who are a member of
    # the group 'users' and NOT a member of 'staff' will have their default
    # root directory set to '~'.
    DefaultRoot ~ users,!staff
    ... 

    DefaultServer

    Name

    DefaultServer -- Set the default server

    Synopsis

    DefaultServer [ on|off]

    Default

    DefaultServer off

    Context

    server config,<VirtualHost>

    Module

    mod_core

    Compatibility

    0.99.0pl6 and later

    Description

    The DefaultServer directive controls which server configuration is used as the default when an incoming connection is destined for an IP address which is neither the host's primary IP address or one of the addresses specified in a <VirtualHost> configuration block. Normally such "unknown" connections are issued a "no server available to service your request" message and disconnected. When DefaultServer is turned on for either the primary server configuration or a virtual server, all unknown destination connections are serviced by the default server. Only a single server configuration can be set to default.

    See also

    Examples

    DefaultTransferMode

    Name

    DefaultTransferMode -- Set the default method of data transfer

    Synopsis

    DefaultTransferMode [ ascii|binary]

    Default

    DefaultTransferMode ascii

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_core

    Compatibility

    1.2.0pre9 and later

    Description

    DefaultTransferMode sets the default transfer mode of the server. By default, carriage-return/linefeed translation will be performed (ASCII mode).

    See also

    Examples

    DeferWelcome

    Name

    DeferWelcome -- Don't show welcome message until user has authenticated

    Synopsis

    DeferWelcome [ DeferWelcome on|off]

    Default

    DeferWelcome off

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_core

    Compatibility

    0.99.0 and later

    Description

    The DeferWelcome directive configures a master or virtual server to delay transmitting the ServerName and address to new connections, until a client has successfully authenticated. If enabled, the initial welcome message will be exceedingly generic and will not give away any type of information about the host that the daemon is actively running on. This can be used by security-conscious administrators to limit the amount of "probing" possible from non-trusted networks/hosts.

    Examples

    Define

    Name

    Define -- Initialises Defines for IfDefine

    Synopsis

    Define [ parameter-name]

    Default

    none

    Context

    any context

    Module

    mod_core

    Compatibility

    1.2.6rc1 and later

    Description

    This directive is used to initialise defines for use in conjunction with the IfDefine directive

    Examples

    IfDefine LoadLimiting
    IfDefine HighPerformanceSetup

    DelayEngine

    Name

    DelayEngine -- Control the use of mod_delay

    Synopsis

    DelayEngine [ on|off ]

    Default

    DelayEngine on

    Context

    server config

    Module

    mod_delay

    Compatibility

    1.3.0rc1 and later

    Description

    The DelayEngine directive enables or disables the module's runtime delaying calculations. If it is set to off this module does no delaying. Use this directive to disable the module.

    See also

    DelayTable

    Examples

      <IfModule mod_delay.c>
        DelayEngine off
      </IfModule>

    DelayTable

    Name

    DelayTable -- Sets the name and path of the file used as the timing table

    Synopsis

    DelayTable [ path ]

    Default

    DelayTable var/proftpd/proftpd.delay

    Context

    server config

    Module

    mod_delay

    Compatibility

    1.3.0rc1 and later

    Description

    The DelayTable directive configures a path to a file that mod_delay uses for storing its timing data. The given path must be an absolute path. It is recommended that this file not be on an NFS mounted partition.

    Note that timing data is kept across daemon stop/starts. When new <VirtualHost>s are added to the configuration, though, mod_delay will detect that it does not have a suitable DelayTable for the new configuration, and will clear all stored data.

    See also

    DelayEngine

    Examples

    DeleteAbortedStores

    Name

    DeleteAbortedStores -- Enable automatic deletion of partially uploaded HiddenStores files

    Synopsis

    DeleteAbortedStores [ DeleteAbortedStores on|off]

    Default

    off

    Context

    server, <VirtualHost>, <Directory>, <Anonymous>, <Global>, .ftpaccess

    Module

    mod_xfer

    Compatibility

    1.2.0rc2 and later

    Description

    The DeleteAbortedStores directive controls whether ProFTPD deletes partially uploaded HiddenStores files if the transfer is stopped via the ABOR command rather than a connection failure.

    See also

    HiddenStores

    Examples

    Deny

    Name

    Deny -- Access control directive

    Synopsis

    Deny [ Deny ["from"] "all"|"none"|host|network[,host|network[,...]]]

    Default

    None

    Context

    <Limit>

    Module

    mod_core

    Compatibility

    0.99.0pl6 and later

    Description

    The Deny directive is used to create a list of hosts and/or networks which will explicitly be denied access to a given <Limit> context block. The magic keywords "ALL" and "NONE" can be used to indicate that all hosts are denied access, or that no hosts are explicitly denied (respectively). For more information on the syntax and usage of Deny see: Allow and Order.

    See also

    Allow Order Limit

    Examples

    DenyAll

    Name

    DenyAll -- Deny all clients

    Synopsis

    DenyAll [ DenyAll]

    Default

    None

    Context

    <Directory>, <Anonymous>, <Limit>, .ftpaccess

    Module

    mod_core

    Compatibility

    0.99.0 and later

    Description

    The DenyAll directive is analogous to a combination of "order deny,allow <cr> deny from all", with the exception that it has a higher precedence when parsed. It is provided as a convenient method of completely denying access to a directory, anonymous ftp or limit block. Because of its precedence, it should not be intermixed with normal Order/Deny directives. The DenyAll directive can be overridden at a lower level directory by using AllowAll. DenyAll and AllowAll are mutually exclusive.

    See also

    AllowAll

    Examples

    DenyClass

    Name

    DenyClass -- Class based deny rules

    Synopsis

    DenyClass [ ["AND"|"OR"|"regex"] class-expression]

    Default

    None

    Context

    <Limit>

    Module

    mod_core

    Compatibility

    1.2.10rc1 and later

    Description

    DenyClass specifies a class-expression that is specifically denied access within the context of the <Limit> block it is applied to. class-expression has a similar syntax as that used in AllowGroup, in that it should contain a comma delimited list of classes or "not" classes (by prefixing a class name name with the `!' character) that are to be denied access to the block.

    By default, the expression is parsed as a boolean "OR" list, meaning that ANY elements of the expression must evaluate to logically true in order to the explicit deny to apply. In order to treat the expression as a boolean "AND" list, meaning that ALL of the elements must evaluate to logically true, use the optional "AND" keyword. Similarly, to treat the expression as a regular expression, use the "regex" keyword.

    Examples

      # A regular expression AllowClass directive
      AllowClass regex ^known
    
      # An AND-evaluated ClassUser directive
      DenyClass AND bad,scanner

    DenyFilter

    Name

    DenyFilter -- Regular expression of command arguments to be blocked

    Synopsis

    DenyFilter [ DenyFilter regular-expression]

    Default

    None

    Context

    server config, <VirtualHost>, <Global>, <Anonymous>, <Directory>, .ftpaccess

    Module

    mod_core

    Compatibility

    1.2.0pre7 and later

    Description

    Similar to AllowFilter, DenyFilter specifies a regular expression which must not match any of the command arguments. If the regex does match, a "Forbidden command" error is returned to the client. This can be especially useful for forbidding certain command argument combinations from ever reaching ProFTPD.

    Notes: The 'PASV' command cannot be blocked using this directive.

    See also

    AllowFilter

    Examples

    # We don't want to allow any commands with % being sent to the server
    DenyFilter "%"

    DenyGroup

    Name

    DenyGroup -- Group based deny rules

    Synopsis

    DenyGroup [ ["AND"|"OR"|"regex"] group-expression]

    Default

    None

    Context

    <Limit>

    Module

    mod_core

    Compatibility

    1.1.1 and later

    Description

    DenyGroup specifies a group-expression that is specifically denied within the context of the <Limit> block it is applied to. group-expression has the same format as that used in DefaultRoot, in that it should contain a comma separated list of groups or "not" groups (by prefixing a group name with the `!' character) that are to be denied access to the block.

    By default, the expression is parsed as a boolean "AND" list, meaning that ALL elements of the expression must evaluate to logically true in order to the explicit deny to apply. In order to treat the expression as a boolean "OR" list, meaning that ANY of the elements must evaluate to logically true, use the optional "OR" keyword. Similarly, to treat the expression as a regular expression, use the "regex" keyword.

    Examples

      # An OR-evaluated AllowGroup directive
      AllowGroup OR www,doc
    
      # A regular expression DenyGroup directive
      DenyGroup regex ^sys

    DenyUser

    Name

    DenyUser -- User based deny rules

    Synopsis

    DenyUser [ ["AND"|"OR"|"regex"] user-expression]

    Default

    None

    Context

    <Limit>

    Module

    mod_core

    Compatibility

    1.1.7 and later

    Description

    DenyUser specifies a user-expression that is specifically denied within the context of the <Limit> block it is applied to. user-expression is a comma delimited list of users or "not" users (by prefixing a user name with the `!' character).

    By default, the expression is parsed as a boolean "OR" list, meaning that ANY elements of the expression must evaluate to logically true in order to the explicit deny to apply. In order to treat the expression as a boolean "AND" list, meaning that ALL of the elements must evaluate to logically true, use the optional "AND" keyword. Similarly, to treat the expression as a regular expression, use the "regex" keyword.

    Examples

      # A regular expression AllowUser directive
      AllowUser regex ^ftp
    
      # An AND-evaluated DenyUser directive
      DenyUser AND system,test

    Directory

    Name

    Directory -- Directory-limited configuration directives

    Synopsis

    Directory [ <Directory pathname>]

    Default

    None

    Context

    server config, <VirtualHost>, <Anonymous>, <Global>

    Module

    mod_core

    Compatibility

    0.99.0 and later

    Description

    This directive creates a block of configuration directives which applies only to the specified directory and its sub-directories. The block is ended with </Directory>. Per-directory configuration is enabled during run-time with a "closest" match algorithm, meaning that the <Directory> directive with the closest matching path to the actual pathname of the file or directory in question is used. Per-directory configuration is inherited by all sub-directories until a closer matching <Directory> is encountered, at which time the original per-directory configuration is replaced with the closer match. Note that this does not apply to <Limit> </Limit> blocks, which are inherited by all sub-directories until a <Limit> block is reached in a closer match.

    A trailing slash and wildcard ("/*") can be appended to the directory, specifying that the configuration block applies only to the contents (and sub-contents), not to the actual directory itself. Such wildcard matches always take precedence over non-wildcard <Directory> configuration blocks. <Directory> blocks cannot be nested (they are automatically nested at run-time based on their pathnames). Pathnames must always be absolute (except inside <Anonymous>), and should not reference symbolic links. Pathnames inside an <Anonymous> block can be relative, indicating that they are based on the anonymous root directory.

    [Notes for ProFTPD 1.1.3 and later only] Pathnames that begin with the special character '~' and do not specify a username immediately after ~ are put into a special deferred mode. When in deferred mode, the directory context is not hashed and sorted into the configuration tree at boot time, but rather this hashing is deferred until a user authenticates, at which time the '~' character is replaced with the user's home directory. This allows a global <Directory> block which applies to all user's home directories, or sub-directories thereof. This feature is not supported within an <Anonymous> block.

    See also

    Limit

    Examples

    #Default usage of the directory directive
    <Directory /users/robroy/private>
      HideNoAccess on
    </Directory>
    
    #Example with username-expanding
    <Directory ~/anon-ftp>
      <Limit WRITE>
        DenyAll
      </Limit>
    </Directory>

    DirFakeGroup

    Name

    DirFakeGroup -- Hide real file/directory group

    Synopsis

    DirFakeGroup [ DirFakeGroup On|Off [groupname]]

    Default

    DirFakeGroup Off

    Context

    server config, <VirtualHost>, <Global>, <Anonymous>, <Directory>, .ftpaccess

    Module

    mod_ls

    Compatibility

    1.1.5

    Description

    DirFakeGroup can be used to hide the true group of files (including directories, fifos, etc.) in a directory listing. If simply turned On, DirFakeGroup will display all files as being owned by group 'ftp'. Optionally, the groupname argument can be used to specify a specific group other than 'ftp'. "~" can be used as the argument in order to display the primary group name of the current user.

    Both DirFakeGroup and DirFakeUser are completely cosmetic; the groupname or username specified don't need to exist on the system, and neither directive affects permissions, real ownership or access control in any way.

    Examples

    DirFakeMode

    Name

    DirFakeMode -- Hide real file/directory permissions

    Synopsis

    DirFakeMode [ DirFakeMode octal-mode]

    Default

    None

    Context

    server config, <VirtualHost>, <Global>, <Anonymous>, <Directory>

    Module

    mod_ls

    Compatibility

    1.1.6

    Description

    The DirFakeMode directive configures a mode (or permissions) which will be displayed for ALL files and directories in directory listings. For each subset of permissions (user, group, other), the "execute" permission for directories is added in listings if the "read" permission is specified by this directive. As with DirFakeUser, and DirFakeGroup, the "fake" permissions shown in directory listings are cosmetic only, they do not affect real permissions or access control in any way on the server. Note that DirFakeMode can affect the real permissions, for example, for FTP mirroring tools. Such tools tend to create a mirror from what the tool sees (e.g. DirFakeMode permissions) on the source FTP server.

    Examples

      DirFakeMode 0640
    
    Will result in:
    
      -rw-r----- ... arbitrary.file
      drwxr-x--- ... arbitrary.directory

    DirFakeUser

    Name

    DirFakeUser -- Hide real file/directory owner

    Synopsis

    DirFakeUser [ DirFakeUser On|Off [username]]

    Default

    DirFakeUser Off

    Context

    server config, <VirtualHost>, <Global>, <Anonymous>, <Directory>, .ftpaccess

    Module

    mod_ls

    Compatibility

    1.1.5

    Description

    DirFakeUser can be used to hide the true user owners of files (including directories, fifos, etc.) in a directory listing. If simply turned On, DirFakeUser will display all files as being owned by user 'ftp'. Optionally, the username argument can be used to specify a specific user other than 'ftp'. "~" can be used as the argument in order to display the current user's username.

    Both DirFakeGroup and DirFakeUser are completely cosmetic; the groupname or username specified don't need to exist on the system, and neither directive affects permissions, real ownership or access control in any way.

    Examples

    DisplayChdir

    Name

    DisplayChdir -- Set the file to display when entering a directory

    Synopsis

    DisplayChdir [ DisplayChdir filename [ true ]]

    Default

    None

    Context

    server config, <Global>, <VirtualHost>, <Anonymous>, <Directory>

    Module

    mod_core

    Compatibility

    1.3.1rc1 and later

    Description

    The DisplayChdir directive configures an ASCII text filename which will be displayed to the user everytime he changes into a directory. If you would like to have the old behaviour of DisplayFirstChdir back you've to use the option "true". Then the file will only be displayed on the first time the user changes into the directory or if proftpd detects that its last modification time has changed since the previous CWD into a given directory. If the filename is relative, it is looked for in the new directory that the user has changed into. Note that for anonymous ftp logins (see <Anonymous>), the file must reside inside the chroot()ed file system space. If the file cannot be found or accessed, no error occurs and nothing is logged or displayed to the client.

    DisplayChdir, DisplayConnect, DisplayLogin and DisplayQuit support the following "magic cookies" (only in 0.99.0pl10 and later), which are replaced with their respective strings before being displayed to the user.

    %C	Current working directory
    
    %E	Server admin's e-mail address
    
    %F	Available space on file system, in bytes
    
    %f      Available space on file system, with units
    
    %i      The number of files uploaded (input) in this session
    
    %K	Total number of bytes transferred
    
    %k	Total number of bytes transferred, in units
    
    %L	Local host name
    
    %M	Max number of authenticated clients
    
    %N	Current number of authenticated clients
    
    %o      The number of files downloaded (output) in this session
    
    %R	Remote host name
    
    %T	Current Time
    
    %t      The number of files transfered (uploaded and downloaded) in this session
    
    %U	Username originally used in login
    
    %u	Username reported by ident protocol
    
    %V	Name of virtual host (if any)
    
    %x	The name of the user's class
    
    %y	Current number of connections from the user's class
    
    %z	Max number of connections from the user's class
    
    %{total_bytes_in} The number of bytes uploaded (input) in this session
    
    %{total_bytes_out} The number of bytes downloaded (output) in this session
    
    %{total_bytes_xfer} The number of bytes transferred (uploaded and downloaded) in this session
    
    %(total_files_in} The number of files uploaded (input) in this session
    
    %(total_files_out} The number of files downloaded (output) in this session
    
    %(total_files_xfer} The number of files transferred (uploaded and downloaded) in this session

    NOTE: not all of these may have a rational value, depending on the context in which they're used (e.g., %u if ident lookups are off).

    Examples

    #Old way in the spirit of DisplayFirstChdir
    DisplayChdir /home/ftp/filetodisplay true

    DisplayConnect

    Name

    DisplayConnect -- Sets connect banner file

    Synopsis

    DisplayConnect [ DisplayConnect filename]

    Default

    None

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_core

    Compatibility

    1.2.0pre2 and later

    Description

    The DisplayConnect directive configures an ASCII text filename which will be displayed to the user when they initially connect but before they login. The filename can be either relative or absolute. In the case of a relative filename, the file is searched for starting in the home directory of the user the server is running as. As this can lead confusion, absolute pathnames are suggested. If the file cannot be found or accessed, no error occurs and nothing is logged or displayed to the client.

    See also

    DisplayFirstChdir

    Examples

    DisplayFileTransfer

    Name

    DisplayFileTransfer -- FIXFIXFIX

    Synopsis

    DisplayFileTransfer [ "name" limit|regex|ip value]

    Default

    FIXFIXFIX

    Context

    server config, <Global>, <VirtualHost>, <Anonymous>, <Limit>, .ftpaccess

    Module

    mod_xfer

    Compatibility

    1.3.1rc1 and later

    Description

    FIX FIX FIX

    See also

    Examples

    FIXFIXFIX

    FIXFIX

    DisplayGoAway

    Name

    DisplayGoAway -- Set the file to display to a rejected connection

    Synopsis

    DisplayGoAway [ DisplayGoAway filename]

    Default

    None

    Context

    server config, <VirtualHost>, <Anonymous>, <Global>

    Module

    mod_core

    Compatibility

    1.2.0pre8 and later

    Description

    The DisplayGoAway directive specifies an ASCII text filename which will be displayed to the user if the class they're a member of has too many users logged in and their login request has been denied. DisplayGoAway supports the same "magic cookies" as DisplayFirstChdir.

    See also

    DisplayFirstChdir

    Examples

    DisplayLogin

    Name

    DisplayLogin -- Set the file to display on login

    Synopsis

    DisplayLogin [ DisplayLogin filename]

    Default

    None

    Context

    server config, <VirtualHost>, <Anonymous>, <Global>

    Module

    mod_core

    Compatibility

    0.99.0 and later

    Description

    The DisplayLogin directive configures an ASCII text filename which will be displayed to the user when they initially login. The filename can be either relative or absolute. In the case of a relative filename, the file is searched for in the initial directory a user is placed in immediately after login (home directory for unix user logins, anonymous-root directory for anonymous logins). Note: that for jailed logins, the file must reside inside the chroot()ed file system space. If the file cannot be found or accessed, no error occurs and nothing is logged or displayed to the client. DisplayLogin supports the same "magic cookies" as DisplayFirstChdir.

    See also

    DisplayFirstChdir

    Examples

    DisplayQuit

    Name

    DisplayQuit -- Set the file to display on quit

    Synopsis

    DisplayQuit [ DisplayQuit filename]

    Default

    None

    Context

    server config, <VirtualHost>, <Anonymous>, <Global>

    Module

    mod_core

    Compatibility

    1.2.0pre8 and later

    Description

    DisplayQuit configures an ASCII text filename which will be displayed to the user when they quit. The filename can be either relative or absolute. In the case of a relative filename, the file is searched for in current directory a user is in when they logout -- for this reason, a absolute filename is usually preferable. NOTE: for jailed logins, the file must reside inside the chroot()ed file system space. If the file cannot be found or accessed, no error occurs and nothing is logged or displayed to the client. DisplayQuit supports the "magic cookies" listed under DisplayFirstChdir.

    See also

    DisplayFirstChdir

    Examples

    DisplayReadme

    Name

    DisplayReadme -- Enable display of file modification times on a file pattern

    Synopsis

    DisplayReadme [ DisplayReadme filename or pattern]

    Default

    None

    Context

    server config, <VirtualHost>, <Anonymous>, <Global>

    Module

    mod_readme

    Compatibility

    1.2.0pre8 and later

    Description

    Module: mod_readme The DisplayReadme directive notifies the user of the last change date of the specified file or pattern. Only a single DisplayReadme directive is allowed per configuration scope. DisplayReadme README Will result in: Please read the file README it was last modified on Sun Oct 17 10:36:14 1999 - 0 days ago Being displayed to the user on a cwd. DisplayReadmePattern README* Will result in: Please read the file README it was last modified on Tue Jan 25 04:47:48 2000 - 0 days ago Please read the file README.first it was last modified on Tue Jan 25 04:48:04 2000 - 0 days ago Being displayed to the user on a cwd.

    See also

    Examples

    ExtendedLog

    Name

    ExtendedLog -- Specify custom logfiles

    Synopsis

    ExtendedLog [ filename [[command-classes] format-nickname]]

    Default

    None

    Context

    server config, <VirtualHost>, <Anonymous> <Global>

    Module

    mod_log

    Compatibility

    1.1.6pl1 and later

    Description

    The ExtendedLog directive allows customizable logfiles to be generated, either globally or per VirtualHost. The filename argument must contain an absolute pathname to a logfile which will be appended to when proftpd starts; the pathname should not be to a file in a nonexistent directory, to a world-writeable directory, or be a symbolic link (unless AllowLogSymlinks is set to on). Multiple logfiles (potentially with different command classes and formats) can be created. Optionally, the command-classes argument can be used to control which types of commands are logged. If not command classes are specified, proftpd logs all commands by default (passwords are hidden). command-classes is a comma delimited (no whitespace!) list of which commands to log.

    The following are valid classes: NONE No commands AUTH Authentication commands (ACCT, PASS, REIN, USER) INFO Informational commands (FEAT, HELP, MDTM, QUIT, PWD, STAT, SIZE, SYST, XPWD) DIRS Directory commands (CDUP, CWD, LIST, MKD, NLST, RMD, XCWD, XCUP, XMKD, XRMD) READ File reading (RETR) WRITE File/directory writing or creation (APPE, MKD, RMD, RNFR, RNTO, STOR, STOU, XMKD, XRMD) MISC Miscellaneous commands (ABOR, ALLO, EPRT, EPSV, MODE, NOOP, OPTS, PASV, PORT, REST, RNFR, RNTO, SITE, SMNT, STRU, TYPE) SEC RFC2228-related security FTP commands ALL All commands (default)

    If a format-nickname argument is supplied, ExtendedLog will use the predefined logformat (created by LogFormat). Otherwise, the default format of "%h %l %u %t \"%r\" %s %b" is used.

    Examples

    For example, to log all read and write operations to /var/log/ftp.log (using the default format), you could:

    ExtendedLog /var/log/ftp.log read,write

    FileRatioErrMsg

    Name

    FileRatioErrMsg -- (docs incomplete)

    Synopsis

    FileRatioErrMsg [ FileRatioErrMsg foo1 foo2 foo3]

    Default

    None known

    Context

    <Directory>, <Anonymous>, <Limit>,.ftpaccess

    Module

    mod_ratio

    Compatibility

    at least 1.2.0 and later

    Description

    The FileRatioErrMsg directive .... Example: FileRatioErrMsg

    See also

    Examples

    Global

    Name

    Global -- Set some directives to apply across the entire daemon

    Synopsis

    Global [ <Global>]

    Default

    None

    Context

    server config, <VirtualHost>

    Module

    mod_core

    Compatibility

    1.1.6 and later

    Description

    The Global configuration block is used to create a set of configuration directives which is applied universally to both the main server configuration and all VirtualHost configurations. Most, but not all other directives can be used inside a Global block.

    In addition, multiple <Global> blocks can be created. At runtime, all Global blocks are merged together and finally into each server's configuration. Global blocks are terminated by a matching </Global> directive.

    See also

    Examples

    Group

    Name

    Group -- Set the group the server normally runs as

    Synopsis

    Group [ Group groupid]

    Default

    None

    Context

    server config, <VirtualHost>, <Anonymous>, <Global>

    Module

    mod_core

    Compatibility

    0.99.0 and later

    Description

    The Group directive configures which group the server daemon will normally run at. See User for more details.

    See also

    Examples

    GroupOwner

    Name

    GroupOwner -- Change default group for new files and directories

    Synopsis

    GroupOwner [ GroupOwner groupname]

    Default

    None

    Context

    <Anonymous>, <Directory>, .ftpaccess

    Module

    mod_core

    Compatibility

    0.99.0 and later

    Description

    The GroupOwner directive configures which group all newly created directories and files will be owned by, within the context that GroupOwner is applied to. The group ID of groupname cannot be 0. Note that GroupOwner cannot be used to override the host OS/file system user/group paradigm. If the current user is not a member of the specified group, new files and directories will not be able to be chown()ed to the GroupOwner group. If this happens, file STOR (send file from client to server) and MKD/XMKD (mkdir) operations will succeed normally, however the new directory entries will be owned by the current user's default group (a warning message is also logged) instead of by the desired group. If you also use UserOwner in the same context, this restriction is lifted.

    See also

    UserOwner

    Examples

    GroupPassword

    Name

    GroupPassword -- Set a group-wide password

    Synopsis

    GroupPassword [ GroupPassword groupid hashed-password]

    Default

    None

    Context

    server config, <VirtualHost>, <Anonymous>, <Global>

    Module

    mod_auth

    Compatibility

    0.99.0pl5 and later

    Description

    The GroupPassword directive creates a special "group" password which allows all users in the specified group to authenticate using a single password. The group/password supplied is only effective inside the context to which GroupPassword is applied. The hashed-password argument is a standard cleartext password which has been passed through the standard unix crypt() library function. Extreme care should be taken when using GroupPassword, as serious security problems may arise if group membership is not carefully controlled.

    See also

    UserPassword

    Examples

    GroupRatio

    Name

    GroupRatio -- Ratio directive

    Synopsis

    GroupRatio [ GroupRatio foo1 foo2 foo3]

    Default

    None known

    Context

    <Directory>, <Anonymous>, <Limit>,.ftpaccess

    Module

    mod_ratio

    Compatibility

    at least 1.2.0 and later

    Description

    The GroupRatio directive .... Example: GroupRatio

    See also

    Examples

    HiddenStores

    Name

    HiddenStores -- Enables more safe file uploads

    Synopsis

    HiddenStores [ HiddenStores on|off]

    Default

    HiddenStores off

    Context

    server config, <Global>, <VirtualHost>, <Anonymous>, >

    Module

    mod_xfer

    Compatibility

    1.2.7rc1 and later

    Description

    The HiddenStores directive enables two-step file uploads: files are uploaded as ".in.filename." and once the upload is complete, renamed to just "filename". This provides a degree of atomicity and helps prevent 1) incomplete uploads and 2) files being used while they're still in the progress of being uploaded.

    Note: if the temporary file name is already in use (e.g., a server crash during upload), it will prevent the file from being uploaded

    The REST (Restart STOR) command is automatically blocked when HiddenStores is enabled, with the server returning a 501 error code to the client.

    HideFiles

    Name

    HideFiles -- Enable hiding of files based on regular expressions

    Synopsis

    HideFiles [ [!]regexp|"none" ["user"|"group"|"class" expression]]

    Default

    None

    Context

    <Directory>, .ftpaccess

    Module

    mod_core

    Compatibility

    1.2.7rc1 and later

    Description

    The HideFiles directive configures a <Directory> section to hide all directory entries, e.g. its files and sub-directories, that match the given regular expression. These files can still be operated on by other FTP commands (DELE, RETR, etc), as constrained by any applicable <Limit>s, but this can be modified using the IgnoreHidden directive. Note that this directive manipulates a file's "hidden-ness", but doesn't do any hiding by itself. A <Limit> section, with IgnoreHidden enabled, does the actual hiding of the files from the <Limit>ed commands.

    As <Directory> configurations are inherited by sub-directories, the "none" parameter can be used to disable any inherited file hiding within a sub-directory, usually through the use of a .ftpaccess file.

    The optional parameters are used to restrict the rule for hiding files only to specific users. If "user" restriction is given, then expression is a user-expression specifying to which users the rule applies. Similarly for the "group" restriction. For the "class" restriction, the expression is simply the name of connection class for whom the rule will apply.

    Examples:

      # Hide configuration and passwd files from view
      HideFiles "(\\.conf|passwd)$"
    
      # ...or the same regex, without the quotes
      HideFiles (\.conf|passwd)$
    
      # Hide those same files from everyone _except_ a special user
      HideFiles (\.conf|passwd)$ user !tj
    
      # Using the ! prefix to "invert" the regular expression matching,
      # allow only .txt and .html files to be seen
      HideFiles !(\.txt|\.html)$
    
      # Only let users of the webmaster group see HTML files, but nothing else
      HideFiles !(\.htm|\.html)$ group webmaster

    See Also: HideGroup, HideUser, HideNoAccess

    HideGroup

    Name

    HideGroup -- Enable hiding of files based on group owner

    Synopsis

    HideGroup [ HideGroup groupid]

    Default

    None

    Context

    <Directory>, <Anonymous>

    Module

    mod_core

    Compatibility

    0.99.0 and later

    Description

    The HideGroup directive configures a <Directory> or < Anonymous> block to hide all directory entries owned by the specified group, unless the group is the primary group of the currently logged-in, authenticated user . Normally, hidden directories and files cannot be seen via LIST or NLST commands but can be operated on via other FTP commands (CWD, DELE, RETR, etc). This behavior can be modified via the IgnoreHidden directive.

    See also

    See Also: HideUser, HideNoAccess, IgnoreHidden

    Examples

    HideNoAccess

    Name

    HideNoAccess -- Block the listing of directory entries to which the user has no access permissions

    Synopsis

    HideNoAccess [ HideNoAccess on|off]

    Default

    None

    Context

    <Directory>,<Anonymous>

    Module

    mod_core

    Compatibility

    0.99.0 and later

    Description

    The HideNoAccess directive configures a <Directory> or <Anonymous> block to hide all directory entries in a directory listing (via the LIST or NLST FTP commands) to which the current logged-in, authenticated user has no access. Normal Unix-style permissions always apply, so that although a user may not be able to see a directory entry that has HideNoAccess applied, they will receive a normal "Permission denied" error message when attempting to blindly manipulate the file system object. The directory or file can be made completely invisible to all FTP commands by applying IgnoreHidden in conjunction with HideNoAccess.

    See also

    See Also: HideUser, HideGroup, IgnoreHidden

    Examples

    HideUser

    Name

    HideUser -- Enable hiding of files based on user owner

    Synopsis

    HideUser [ HideUser userid]

    Default

    None

    Context

    <Directory>, <Anonymous>

    Module

    mod_core

    Compatibility

    0.99.0 and later

    Description

    The HideUser directive configures a <Directory> or <Anonymous> block to hide all directory entries owned by the specified user, unless the owning user is the currently logged-in, authenticated user. Normally, hidden directories and files cannot be seen via LIST or NLST commands but can be operated on via other FTP commands (CWD, DELE, RETR, etc). This behavior can be modified via the IgnoreHidden directive.

    See also

    HideGroup, HideNoAccess, IgnoreHidden

    Examples

    HostRatio

    Name

    HostRatio -- Ratio directive

    Synopsis

    HostRatio [ HostRatio foo1 foo2 foo3]

    Default

    None known

    Context

    <Directory>, <Anonymous>, <Limit>,.ftpaccess

    Module

    mod_ratio

    Compatibility

    at least 1.2.0 and later

    Description

    The HostRatio directive .... Example: HostRatio

    See also

    Examples

    IdentLookups

    Name

    IdentLookups -- Toggle ident lookups

    Synopsis

    IdentLookups [ IdentLookups on|off]

    Default

    IdentLookups on

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_core

    Compatibility

    1.1.5 and later

    Description

    Normally, when a client initially connects to proftpd, the ident protocol (RFC1413) is used to attempt to identify the remote username. This can be controlled via the IdentLookups directive.

    See also

    Examples

    IfDefine

    Name

    IfDefine -- To control the use of sections of the configuration

    Synopsis

    IfDefine [ [!]define-label]

    Default

    none

    Context

    any

    Module

    mod_core

    Compatibility

    1.2.6rc1 and later

    Description

    The <IfDefine test>...</IfDefine> section is used to mark directives that are conditional. The directives within an IfDefine section are only processed if the test is true. If the test is false, everything between the start and end markers is ignored.

    The test in the <IfDefine> section directive can be one of two forms: 'parameter-name' or '!parameter-name'

    In the former case, the directives between the start and end markers are only processed if the parameter named parameter-name is defined. The second format reverses the test, and only processes the directives if parameter-name is not defined.

    The parameter-name argument is a define as given on the command line via -Dparameter-name, at the time the server was started.

    <IfDefine> sections are nest-able, which can be used to implement simple multiple-parameter tests.

    See also

    Define, IfModule

    Examples

    $ proftpd -DDoSomething

    --[ proftpd.conf ]--
    <IfDefine DoSomething>
    # do something here
    </IfDefine>
    --[ end ]--

    IfModule

    Name

    IfModule -- Parse a section of config based on module name

    Synopsis

    IfModule [ [!]module-name]

    Default

    none

    Context

    any

    Module

    mod_core

    Compatibility

    1.2.6rc1 and later

    Description

    The <IfModule test>...</IfModule> section is used to mark directives that are conditional. The directives within an IfModule section are only processed if the test is true. If the test is false, everything between the start and end markers is ignored.

    The test in the <IfModule> section directive can be one of two forms: "module name" or "!module name"

    In the former case, the directives between the start and end markers are only processed if the module named module name is compiled in to ProFTPD. The second format reverses the test, and only processes the directives if module name is not compiled in.

    The module name argument is a module name as given as the file name of the module, at the time it was compiled. For example, mod_sql.c.

    <IfModule> sections are nest-able, which can be used to implement simple multiple-module tests.

    See also

    Define, IfDefine

    Examples

    <IfModule mod_load.c>
    MaxLoad                 10 "Access denied, server load too high"
    </IfModule>

    IgnoreHidden

    Name

    IgnoreHidden -- Treat 'hidden' files as if they don't exist

    Synopsis

    IgnoreHidden [ IgnoreHidden on|off]

    Default

    IgnoreHidden off

    Context

    <Limit>

    Module

    mod_core

    Compatibility

    0.99.0 and later

    Description

    Normally, files hidden via HideNoAccess, HideUser or HideGroup can be operated on by all FTP commands (assuming Unix file permissions allow access), even though they do not appear in directory listings. Additionally, even when normal file system permissions disallow access, proftpd returns a "Permission denied" error to the client, indicating that the requested object does exist, even if it cannot be acted upon. IgnoreHidden configures a <Limit> block to completely ignore any hidden directory entries for the set of limited FTP commands. This has the effect of returning an error similar to "No such file or directory" when the client attempts to use the limited command upon a hidden directory or file.

    See also

    Examples

    Include

    Name

    Include -- Load additional configuration directives from a file

    Synopsis

    Include [ Include file]

    Default

    None

    Context

    server config, <Directory>, <Anonymous>, <VirtualHost>, <Global>

    Module

    mod_core

    Compatibility

    1.2.0 and later

    Description

    This directive allows you to include another configuration file within your current configuration file. The given file argument must be the full path to the file to be included.

    See also

    Examples

    LDAPAliasDereference

    Name

    LDAPAliasDereference -- Specify how LDAP alias dereferencing is done

    Synopsis

    LDAPAliasDereference [ never find search always ]

    Default

    LDAPAliasDereference never

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_ldap

    Compatibility

    2.8.16 and later

    Description

    Should be one of never, always, search, or find to specify that aliases are never dereferenced, always dereferenced, dereferenced when searching, or dereferenced only when locating the base object for the search.

    Examples

    LDAPAliasDereference always

    LDAPAttr

    Name

    LDAPAttr -- Map LDAP Attributes to something non standard

    Synopsis

    LDAPAttr [ uid uidNumber gidNumber homeDirectory userPassword loginShell cn memberUid ftpQuota] [ "NewAttribute"]

    Default

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_ldap

    Compatibility

    2.8.13 and later

    Description

    FIXMEFIXMEFIXME

    This dicrective has to be set before any of the LDAPDo* directives.

    See also

    Examples

    FIXFIXFIX

    FIXFIX

    LDAPAuthBinds

    Name

    LDAPAuthBinds -- (docs incomplete)

    Synopsis

    Syntax: LDAPAuthBinds [ on off ]

    (docs incomplete)

    Default

    LDAPAuthBinds off in mod_ldap <= 2.7.6, LDAPAuthBinds on in mod_ldap >= 2.8

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_ldap

    Compatibility

    mod_ldap v2.5 and later

    Description

    By default, the DN specified by LDAPDNInfo will be used to bind to the LDAP server to obtain user information, including the userPassword attribute. If LDAPAuthBinds is set to on, the DN specified by LDAPDNInfo will be used to fetch all user information except the userPassword attribute. Then, mod_ldap will bind to the LDAP server as the user who is logging in via FTP with the user-supplied password. If this bind succeeds, the user is considered authenticated and is allowed to log in. This method of LDAP authentication has the added benefit of supporting any password encryption scheme that your LDAP server supports.

    See also

    Examples

    LDAPDefaultAuthScheme

    Name

    LDAPDefaultAuthScheme --  Set the authentication scheme/hash that is used when no leading {hashname} is present.

    Synopsis

    LDAPDefaultAuthScheme [ crypt clear ]

    Default

    LDAPDefaultAuthScheme "crypt"

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_ldap

    Compatibility

    mod_ldap v2.0 and later

    Description

    Specifies the authentication scheme used for passwords with no {prefix} in the LDAP database. For example, if you are using something like userPassword: mypass in your LDAP database, you would want to set LDAPDefaultAuthScheme to clear.

    See also

    Examples

    LDAPDefaultGID

    Name

    LDAPDefaultGID --  Set the default GID to be assigned to users when no uidNumber attribute is found.

    Synopsis

    LDAPDefaultGID [ default-gid ]

    Default

    None

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_ldap

    Compatibility

    mod_ldap v2.0 and later

    Description

    This directive is useful primarily in virtual-user environments common in large-scale ISPs and hosting organizations. If a user does not have a LDAP gidNumber attribute, the LDAPDefaultGID is used. This allows one to have a large number of users in an LDAP database without gidNumber attributes; setting this configuration directive will automatically assign those users a single GID.

    See also

    Examples

    LDAPDefaultUID

    Name

    LDAPDefaultUID --  Set the default UID to be assigned to users when no uidNumber attribute is found.

    Synopsis

    LDAPDefaultUID [ default-uid ]

    Default

    None

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_ldap

    Compatibility

    mod_ldap v2.0 and later

    Description

    This directive is useful primarily in virtual-user environments common in large-scale ISPs and hosting organizations. If a user does not have a LDAP uidNumber attribute, the LDAPDefaultUID is used. This allows one to have a large number of users in an LDAP database without uidNumber attributes; setting this configuration directive will automatically assign those users a single UID.

    See also

    Examples

    LDAPDNInfo

    Name

    LDAPDNInfo -- Set DN information to be used for initial bind

    Synopsis

    LDAPDNInfo [ LDAPDNInfo "ldap-dn" "dn-password" ]

    Default

    LDAPDNInfo "" "" (anonymous bind)

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_ldap

    Compatibility

    mod_ldap v2.0 and later

    Description

    This directive specifies the LDAP DN and password to use when binding to the LDAP server. If this configuration directive is not specified, anonymous binds are used.

    See also

    Examples

    LDAPDoAuth

    Name

    LDAPDoAuth -- Enable LDAP authentication

    Synopsis

    LDAPDoAuth [ on off ] [ "auth-base-dn" ] [ "search-filter-template" ]

    Default

    LDAPDoAuth off

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_ldap

    Compatibility

    mod_ldap <= v2.9.0, replaced by LDAPUsers

    Description

    This configuration directive activates LDAP authentication. The second argument to this directive is the LDAP base DN to use for authentication. The third argument is a template to be used for the search filter; %v will be replaced with the username that is being authenticated. By default, the search filter template "(&(uid=%v)(objectclass=posixAccount))" is used. The uid for the the search filter is taken from the LDAPAttr directive. Search filter templates are only supported in mod_ldap v2.7 and later.

    See also

    LDAPAttr

    Examples

    LDAPDoGIDLookups

    Name

    LDAPDoGIDLookups --  Enable LDAP lookups for user group membership and GIDs in directory listings

    Synopsis

    LDAPDoGIDLookups [ on off ] [ "gid-base-dn" ] [ "cn-filter-template" ] [ "gid-number-filter-template" ] [ "member-uid-filter-template" ]

    Default

    LDAPDoGIDLookups off

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_ldap

    Compatibility

    mod_ldap <= v2.9.0, replaced by LDAPGroups

    Description

    This configuration directive activates LDAP GID-to-name lookups in directory listings. The second argument to this directive is the LDAP base DN to use for GID-to-name lookups. The third through fifth arguments are templates to be used for the search filter; %v will be replaced with the GID that is being looked up.

    By default, the search filter templates look like this:

    cn_filter: "(cn=%v)(objectclass=posixGroup))", gidnumber_filter: "(gidNumber=%v)(objectclass=posixGroup))", memberuid_filter: "(memberUid=%v)(objectclass=posixGroup))".

    The attribute names used in the default search filters are taken from the LDAPAttr directive.

    Filter templates are only supported in mod_ldap v2.8.3 and later.

    See also

    LDAPAttr

    Examples

    LDAPDoQuotaLookups

    Name

    LDAPDoQuotaLookups -- Enable LDAP quota limit support

    Synopsis

    LDAPDoQuotaLookups [ on off ] [ "base-dn" ] [ "quota-filter-template" ] [ "default-quota" ]

    Default

    LDAPDoQuotaLookups off

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_ldap

    Compatibility

    mod_ldap <= v2.9.0, replaced by LDAPUsers and LDAPDefaultQuota

    Description

    Activates LDAP quota lookups. The second argument is the LDAP base DN to use for quota limit searches. The third argument is the search filter template. The default search filter template is "(&(LDAPAttr_uid=%u)(objectclass=posixAccount))". The attribute name used in the default search filter template is taken from the LDAPAttr directive, so if you re-map an attribute, the default search filter reflects that re-mapping.

    In mod_ldap v2.7 or later, %u in the search filter template will be replaced with the username, group, or class that is being looked up. mod_ldap v2.9.3 or later will also expand %u in the base DN.

    The optional default-quota argument specifies the quota limits to use if an entry does not have a ftpQuota attribute, and has the same format as the ftpQuota LDAP attribute. For example, "false,hard,100,100,100,100,100,100". This argument is deprecated as of ProFTPD 1.3.4b; use the >LDAPAttr

    Examples

    LDAPDoUIDLookups

    Name

    LDAPDoUIDLookups --  Enable LDAP lookups for UIDs in directory listings

    Synopsis

    LDAPDoUIDLookups [ on off ] [ "uid-base-dn" ] [ "uid-filter-template" ]

    Default

    LDAPDoUIDLookups off

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_ldap <= v2.9.0, replaced by LDAPUsers

    Compatibility

    mod_ldap v2.0 and later

    Description

    This configuration directive activates LDAP UID-to-name lookups in directory listings. The second argument to this directive is the LDAP base DN to use for UID-to-name lookups. The third argument is a template to be used for the search filter; %v will be replaced with the UID that is being looked up. By default, the search filter template "(&(LDAPAttr_uidNumber=%v)(objectclass=posixAccount))" is used. The uid for the the search filter is taken from the LDAPAttr directive Search filter templates are only supported in mod_ldap v2.7 and later.

    See also

    LDAPAttr

    Examples

    LDAPForceDefaultGID

    Name

    LDAPForceDefaultGID -- Force all LDAP-authenticated users to use the same GID.

    Synopsis

    Syntax: LDAPForceDefaultGID [ on off ]

    Default

    LDAPForceDefaultGID off

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_ldap

    Compatibility

    mod_ldap v2.8 and later

    Description

    Even when a LDAPDefaultGID is configured, mod_ldap will allow individual users to have gidNumber attributes that will override this default GID. With LDAPForceDefaultGID enabled, all LDAP-authenticated users are given the default GID; GIDs may not be overridden by gidNumber attributes.

    See also

    Examples

    LDAPForceDefaultUID

    Name

    LDAPForceDefaultUID -- Force all LDAP-authenticated users to use the same UID.

    Synopsis

    Syntax: LDAPForceDefaultUID [ on off ]

    Default

    LDAPForceDefaultUID off

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_ldap

    Compatibility

    mod_ldap v2.8 and later

    Description

    Even when a LDAPDefaultUID is configured, mod_ldap will allow individual users to have uidNumber attributes that will override this default UID. With LDAPForceDefaultUID enabled, all LDAP-authenticated users are given the default UID; UIDs may not be overridden by uidNumber attributes.

    See also

    Examples

    LDAPForceGeneratedHomedir

    Name

    LDAPForceGeneratedHomedir --  Force all LDAP-authenticated users to use the default HomeDironDemand prefix/suffix.

    Synopsis

    LDAPForceGeneratedHomedir [ on off ] [ directory-mode ]

    Default

    LDAPForceGeneratedHomedir off

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_ldap

    Compatibility

    mod_ldap v2.8.13 and later

    Description

    Even when a LDAPGenerateHomedirPrefix is configured, mod_ldap will allow individual users to have homeDirectory attributes that will override the default. With LDAPForceHomeDironDemand enabled, all LDAP-authenticated users are given the default prefix and/or suffix; homedirs may not be overridden by LDAP homeDirectory attributes.

    Examples

    LDAPForceHomedirOnDemand

    Name

    LDAPForceHomedirOnDemand --  Force all LDAP-authenticated users to use the default HomeDironDemand prefix/suffix. [deprecated]

    Synopsis

    LDAPForceHomedirOnDemand [ on off ] [ directory-mode ]

    Default

    LDAPForceHomedirOnDemand off

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_ldap

    Compatibility

    mod_ldap v2.8.11 and later

    Description

    This directive has been deprecated with mod_ldap v2.8.13. Please take a look at LDAPForceGeneratedHomedir

    Even when a LDAPHomeDironDemandPrefix is configured, mod_ldap will allow individual users to have homeDirectory attributes that will override the default. With LDAPForceHomeDironDemand enabled, all LDAP-authenticated users are given the default prefix and/or suffix; homedirs may not be overridden by LDAP homeDirectory attributes.

    Examples

    LDAPGenerateHomedir

    Name

    LDAPGenerateHomedir --  Enable the creation of user home directories on demand

    Synopsis

    LDAPGenerateHomedir [ on off ] [ directory-mode ]

    Default

    LDAPGenerateHomedir off

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_ldap

    Compatibility

    mod_ldap v2.8.13 and later

    Description

    LDAPGenerateHomedir activates on-demand home directory creation. If a user logs in and does not yet have a home directory, a home directory is created automatically.

    In mod_ldap <= 2.7.6, the home directory will be owned by the same user and group that ProFTPD runs as (see the User and Group configuration directives). mod_ldap >= 2.8 can create home directories for users with any UID/GID, not just those with the same UID/GID as the main ProFTPD server.

    The second argument allows you to specify the mode (default permissions) to use when creating home directories on demand, subject to ProFTPD's umask (see the Umask directive). If no directory mode is specified, the default of 0755 is used. Directory mode setting is only supported in mod_ldap v2.7 or later.

    Examples

    %

    LDAPGenerateHomedirPrefix

    Name

    LDAPGenerateHomedirPrefix --  Enable the creation of user home directories on demand

    Synopsis

    LDAPGenerateHomedirPrefix [ leading-path ]

    Default

    LDAPGenerateHomedirPrefix off

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_ldap

    Compatibility

    mod_ldap v2.8.13 and later

    Description

    LDAPGenerateHomedirPrefix enables a prefix to be specified for on-demand home directory creation. This is most useful if mod_ldap is being used to authenticate against an LDAP directory that does not return a homeDirectory attribute, either because it cannot (Microsoft Active Directory, for example) or because you do not wish to extend your existing directory schema.

    For example, setting this directive to "/home" and logging in as the user "joe" would result in his home directory being created as "/home/joe". The directory will be created with the mode specified in LDAPGenerateHomedir. To use this directive, LDAPGenerateHomedir must be enabled.

    Examples

    LDAPGenerateHomedirPrefixNoUsername

    Name

    LDAPGenerateHomedirPrefixNoUsername -- (docs incomplete)

    Synopsis

    LDAPGenerateHomedirPrefixNoUsername [ on off]

    Default

    (docs incomplete)

    Context

    server config, <Global>, <VirtualHost>, <Anonymous>, <Limit>, .ftpaccess

    Module

    mod_ldap

    Compatibility

    mod_ldap 2.8.13 and later

    Description

    (docs incomplete)

    LDAPGroups

    Name

    LDAPGroups --  Enable LDAP lookups for user group membership and GIDs in directory listings

    Synopsis

    LDAPGroups [ "group-base-dn" ] [ "group-name-filter-template" ] [ "gid-number-filter-template" ] [ "member-user-filter-template" ]

    Default

    disabled

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_ldap

    Compatibility

    mod_ldap v2.9.0 and later

    Description

    Activates LDAP group membership lookups and GID to name mappings in directory listings.

    The first argument is the LDAP base DN to use for group lookups. The second through fourth arguments are search filter templates; %u will be replaced with the group name, GID number, or group member username that is being looked up, respectively.

    The default search filter templates are:

    group-name-filter-template: "(cn=%u)(objectclass=posixGroup))", gid-number-filter-template: "(gidNumber=%u)(objectclass=posixGroup))", member-user-filter-template: "(memberUid=%u)(objectclass=posixGroup))".

    The attribute names used in the default search filters are taken from the LDAPAttr directive, so if you re-map an attribute, the default search filter reflects that re-mapping.

    See also

    LDAPAttr

    Examples

    LDAPHomedirOnDemand

    Name

    LDAPHomedirOnDemand --  Enable the creation of user home directories on demand [deprecated]

    Synopsis

    LDAPHomedirOnDemand [ on off ] [ directory-mode ]

    Default

    LDAPHomedirOnDemand off

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_ldap

    Compatibility

    mod_ldap v2.0 - 2.8.12

    Description

    LDAPHomedirOnDemand activates on-demand home directory creation. If a user logs in and does not yet have a home directory, a home directory is created automatically.

    In mod_ldap <= 2.7.6, the home directory will be owned by the same user and group that ProFTPD runs as (see the User and Group configuration directives). mod_ldap >= 2.8 can create home directories for users with any UID/GID, not just those with the same UID/GID as the main ProFTPD server.

    The second argument allows you to specify the mode (default permissions) to use when creating home directories on demand, subject to ProFTPD's umask (see the Umask directive). If no directory mode is specified, the default of 0755 is used. Directory mode setting is only supported in mod_ldap v2.7 or later.

    Examples

    LDAPHomedirOnDemandPrefix

    Name

    LDAPHomedirOnDemandPrefix --  Enable the creation of user home directories on demand [deprecated]

    Synopsis

    LDAPHomedirOnDemandPrefix [ leading-path ]

    Default

    LDAPHomedirOnDemandPrefix off

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_ldap

    Compatibility

    mod_ldap v2.8 - 2.8.12

    Description

    LDAPHomedirOnDemandPrefix enables a prefix to be specified for on-demand home directory creation. This is most useful if mod_ldap is being used to authenticate against an LDAP directory that does not return a homeDirectory attribute, either because it cannot (Microsoft Active Directory, for example) or because you do not wish to extend your existing directory schema.

    For example, setting this directive to "/home" and logging in as the user "joe" would result in his home directory being created as "/home/joe". The directory will be created with the mode specified in LDAPHomedirOnDemand. To use this directive, LDAPHomedirOnDemand must be enabled.

    Examples

    LDAPHomedirOnDemandPrefixNoUsername

    Name

    LDAPHomedirOnDemandPrefixNoUsername -- (docs incomplete)

    Synopsis

    LDAPHomedirOnDemandPrefixNoUsername [ "name" limit|regex|ip value]

    Default

    (docs incomplete)

    Context

    server config, <Global>, <VirtualHost>, <Anonymous>, <Limit>, .ftpaccess

    Module

    mod_ldap

    Compatibility

    mod_ldap v2.8.1 - 2.8.12

    Description

    (docs incomplete)

    LDAPHomedirOnDemandSuffix

    Name

    LDAPHomedirOnDemandSuffix --  Specify an additional directory to be created inside a user's home directory on demand. [deprecated]

    Synopsis

    LDAPHomedirOnDemandSuffix [ additional-directory1 additional-directory2 additional-directory3 ]

    Default

    LDAPHomedirOnDemandSuffix ""

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_ldap

    Compatibility

    mod_ldap v2.6 - 2.8.12

    Description

    to be created within a user's home directory when it is created on demand. For example, if a user's home directory is "/home/user", setting this configuration directive to "public_html" will also create "/home/user/public_html" on demand. In mod_ldap v2.7.6 and earlier, you must also activate LDAPHomedirOnDemand in your configuration.

    mod_ldap >= 2.8 supports multiple suffix arguments and does not require LDAPHomedirOnDemand to be enabled.

    mod_ldap >= 2.8.11 supports additional mode information; you can add ":octal-mode" to a directory argument to have it created with that mode. For example, LDAPHomedirOnDemandSuffix foo:700 will create the suffix directory foo with the mode 700.

    See also

    Examples

    LDAPNegativeCache

    Name

    LDAPNegativeCache -- Enable negative caching for LDAP lookups

    Synopsis

    LDAPNegativeCache [ on off ]

    Default

    LDAPNegativeCache off

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_ldap

    Compatibility

    mod_ldap v1.1 - 2.8.23

    Description

    LDAPNegativeCache specifies whether or not to cache negative responses from the LDAP server when using LDAP for UID/GID lookups. This option is useful if you also use/are in transition from another authentication system; if there are many users in your old authentication system that aren't in the LDAP database, there can be a significant delay when a directory listing is performed as the UIDs not in the LDAP database are repeatedly looked up in an attempt to present usernames instead of UIDs in directory listings. With LDAPNegativeCache set to on, negative ("not found") responses from the LDAP server will be cached and speed will improve on directory listings that contain many users not present in the LDAP database.

    See also

    Examples

    LDAPProtocolVersion

    Name

    LDAPProtocolVersion -- Set the LDAP protocol version

    Synopsis

    LDAPProtocolVersion [ 2 | 3]

    Default

    3

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_ldap

    Compatibility

    2.8.13 and later

    Description

    FIX FIX FIX

    See also

    Examples

    FIXFIXFIX

    FIXFIX

    LDAPQueryTimeout

    Name

    LDAPQueryTimeout -- Set a timeout for LDAP queries

    Synopsis

    LDAPQueryTimeout [ timeout-seconds ]

    Default

    LDAPQueryTimeout default-api-timeout

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_ldap

    Compatibility

    mod_ldap v2.0 and later

    Description

    Sets the timeout used for LDAP directory queries. The default is the default timeout used by your LDAP API.

    See also

    Examples

    LDAPSearchScope

    Name

    LDAPSearchScope -- Specify the search scope used in LDAP queries

    Synopsis

    LDAPSearchScope [ onelevel subtree ]

    Default

    LDAPSearchScope subtree

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_ldap

    Compatibility

    mod_ldap v2.6 and later

    Description

    Set the scope used for LDAP searches. The default setting, subtree, searches for all entries in the tree from the current level down. Setting this directive to onelevel searches only one level deep in the LDAP tree.

    See also

    Examples

    LDAPServer

    Name

    LDAPServer -- Specify the LDAP server to use for lookups

    Synopsis

    LDAPServer [ "hostname1:port1 hostname2:port2" ]

    Default

    LDAPServer "localhost"

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_ldap

    Compatibility

    mod_ldap v1.0 and later

    Description

    LDAPServer allows you to to specify the hostname(s) and port(s) of the LDAP server(s) to use for LDAP authentication. If no LDAPServer configuration directive is present, the default LDAP servers specified by your LDAP API will be used.

    Note that the default search scope for LDAP URLs is 'base' if a scope is not explicitly specified in the URL. This behavior differs from the LDAPSearchScope directive, which defaults to 'subtree'.

    See also

    Examples

    LDAPUsers

    Name

    LDAPUsers -- Enable LDAP authentication/user lookups

    Synopsis

    LDAPUsers [ "user-base-dn" ] [ "username-filter-template" ] [ "uid-number-filter-template" ]

    Default

    disabled

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_ldap

    Compatibility

    mod_ldap v2.9.0 and later

    Description

    Activates LDAP authentication and UID to name mappings in directory listings.

    The first argument is the LDAP base DN to use for user lookups. During authentication, %u will be replaced with the username that is being authenticated. When looking up users by UID number, %u will not be replaced. Usually, %u in the base DN is only useful in "virtual user" environments, since mod_ldap won't be able to look up other users.

    The second argument is the search filter template for looking up users by username; %u will be replaced with the username that is being authenticated.

    The third argument is the search filter template for looking up users by UID number; %u will be replaced with the UID number that is being looked up.

    The default search filter templates are:

    username-filter-template: "(uid=%u)(objectclass=posixAccount))", uid-number-filter-template: "(uidNumber=%u)(objectclass=posixAccount))",

    The attribute names used in the default search filters are taken from the LDAPAttr directive, so if you re-map an attribute, the default search filter reflects that re-mapping.

    See also

    LDAPAttr

    Examples

    LDAPUseTLS

    Name

    LDAPUseTLS -- Enable TLS/SSL connections to the LDAP server.

    Synopsis

    Syntax: LDAPUseTLS [ on off ]

    Default

    LDAPUseTLS off

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_ldap

    Compatibility

    mod_ldap v2.8 and later

    Description

    By default, mod_ldap connects to the LDAP server via a non-encrypted connection. Enabling this option causes mod_ldap to use an encrypted (TLS/SSL) connection to the LDAP server. If a secure connection to the LDAP server fails, mod_ldap will not authenticate users (mod_ldap will *not* fall back to an unsecure connection).

    See also

    Examples

    LeechRatioMsg

    Name

    LeechRatioMsg -- Sets the 'over ratio' error message

    Synopsis

    LeechRatioMsg [ LeechRatioMsg foo1 foo2 foo3]

    Default

    None known

    Context

    <Directory>, <Anonymous>, <Limit>,.ftpaccess

    Module

    mod_ratio

    Compatibility

    at least 1.2.0 and later

    Description

    The LeechRatioMsg directive defines the response message sent back to the client upon breaking their quota limits.

    See also

    Examples

    LeechRatioMsg "please upload as well as download"

    Limit

    Name

    Limit -- Set the commands/actions to be controlled

    Synopsis

    Limit [ <Limit command|command-group [command2 ..]>]

    Default

    None

    Context

    server config, <VirtualHost>, <Directory>, <Anonymous>, <Global>, .ftpaccess

    Module

    mod_core

    Compatibility

    0.99.0 and later

    Description

    The Limit configuration block is used to place access restrictions on one or more FTP commands, within a given context. Limits flow downward, so that a Limit configuration in the server config context applies to all <Directory> and <Anonymous> blocks that also reside in the configuration; until it is overridden by a "lower" <Limit> block. Any number of command parameters can be specified, against which the contents of the <Limit> block will be applied. command can be any valid FTP command, but is generally one of the following: CWD (Change Working Directory) Sent by client when changing directories. MKD / XMKD (MaKe Directory) Sent by client to create a new directory. RNFR (ReName FRom), RNTO (ReName TO) Sent as a pair by client to rename a directory entry. DELE (DELEte) Sent by client to delete a file. RMD / XRMD (ReMove Directory) Sent by client to remove a directory. RETR (RETRieve) Transfer a file from the server to the client. STOR (STORe) Transfer a file from the client to the server. In addition, the following command-groups are accepted. They have a lower precedence than real commands, meaning that a real command limit will always be applied instead of the command-group. READ All FTP commands which deal with file reading (directory listing not included): RETR, SITE, SIZE, STAT WRITE All FTP commands which deal with file or directory write/creation/deletion: APPE, DELE, MKD, RMD, RNTO, STOR, XMKD, XRMD DIRS All FTP commands which deal with directory listing: CDUP, CWD, LIST, MDTM, NLST, PWD, RNFR, XCUP, XCWD, XPWD ALL ALL FTP commands (identical to READ WRITE DIRS). Note this group has the lowest precedence of all; it will not override a limit imposed by another command-group (e.g. DIRS). Finally, a special command is allowed which can be used to control login access: LOGIN Connection or login to the server. Applying a <Limit> to this pseudo-command can be used to allow or deny initial connection or login to the context. It has no effect, and is ignored, when used in a context other than server config, <VirtualHost> or <Anonymous> (i.e. using it in a <Directory> context is meaningless). <Limit> command restrictions should not be confused with file/directory access permission. While limits can be used to restrict a command on a certain directory, they cannot be used to override the file permissions inherent to the base operating/file system. The following FTP commands cannot be restricted via <Limit>: ABOR HELP MODE (not implemented, always S) NOOP PASS (use <Limit LOGIN>) PASV PORT QUIT REST (use AllowRetrieveRestart, AllowStoreRestart) STRU (not implemented, always F) SYST TYPE USER (use <Limit LOGIN>)

    See also

    See Also: IgnoreHidden

    Examples

    ListOptions

    Name

    ListOptions -- Configure options used when listing directories

    Synopsis

    ListOptions [ "options string"] [ ["strict"]]

    Default

    None

    Context

    server config, <VirtualHost>, <Anonymous>, <Global>, <Directory>, .ftpaccess

    Module

    mod_ls

    Compatibility

    1.2.8rc1 and later

    Description

    Normally, FTP commands involving directory listings (NLST, LIST and STAT) use the arguments (options) passed by the client to determine what files are displayed and the format they are displayed in. The ListOptions directive can alter the behaviour of such listings by making it such that a certain option (or options) is always in effect, or is always disabled.

    In addition to the normal dash-prefixed options that the builtin ls takes, the directive allows for plus-prefixed options. The plus-prefixed options allow for their dash-prefixed equivalents, potentially given by a user, to be disabled, while still allowing other options to function normally.

          -1 List one file per line
    
          -A List all files except "." and ".."
        
          -a List all files including those whose names start with "."
        
          -C List entries by columns
        
          -d List directory entries instead of directory contents
        
          -F Append file type indicator (one of "*", "/", "=", "@" or "|") to names
        
          -h Print file sizes in human-readable format (e.g. 1K, 234M, 2G)
        
          -L List files pointed to by symlinks
        
          -l Use a long listing format
        
          -n List numeric UIDs/GIDs instead of user/group names
        
          -R List subdirectories recursively
        
          -r Sort filenames in reverse order
        
          -S Sort by file size
        
          -t Sort by modification time 

    If the optional "strict" keyword is used, then the configured options will override any options given by the user (i.e. the user's options will be ignored). In addition to "strict" the following keywords are supported:

          maxfiles Sets a maximum limit on the number of files listed in one directory listing
    
          maxdirs Sets a maximum limit on the number of directories listed in one directory listing
    
          maxdepth Sets a maximum recursion depth, if the -R option is allowed 

    See also

    Examples

    # Force directory listings to always show dotfiles ListOptions "-a"

    # To prevent anyone from doing recursive listings, but still allowing # other user options, use +R to disable any -R option given by users ListOptions "+R"

    # To allow only the basic listing, no options, always ListOptions "" strict

    #limit maximum files given back to 2000 and recurse in to a max #depth of 3 directories ListOptions -a maxfiles 2000 maxdepth 3

    LogFormat

    Name

    LogFormat -- Specify a logging format

    Synopsis

    LogFormat [ LogFormat nickname "format-string"]

    Default

    LogFormat default "%h %l %u %t \"%r\" %s %b"

    Context

    server config

    Module

    mod_log

    Compatibility

    1.1.6pl1 and later

    Description

    The LogFormat directive can be used to create a custom logging format for use with the ExtendedLog directive. Once created, the format can be referenced by the specified nickname. The format-string argument can consist of any combination of letters, numbers and symbols. The special character % is used to start a meta-sequence (see below). To insert a literal % character, use %%.

    The following meta sequences are available and are replaced as indicated when logging.

    %a		Remote client IP address
    %A		Anonymous username (password given), or UNKNOWN if non-anonymous
    %b		Bytes sent for request
    %d		Directory name (not full path) for CDUP, CWD, MKD, RMD, XCWD, XCUP, XMKD, XRMD
    %D		Directory name (full path) for CDUP, CWD, MKD, RMD, XCWD, XCUP, XMKD, XRMD
    %{FOOBAR}e	  Contents of environment variable FOOBAR.  Note that the server does not set any environment variables itself.
    %f		  Filename stored or retrieved, absolute path (not chrooted)
    %F		  Filename stored or retrieved, as the client sees it
    %h		  Remote client DNS name
    %J		  Command arguments received from client, e.g. file.txt
    %l		  Remote username (from ident), or UNKNOWN if ident lookup failed
    %L		  Local server IP address
    %m		  Command (method) name received from client, e.g. RETR
    %p		  Local server port number
    %P		  Local server process id (pid)
    %r		  Full command line received from client
    %s		  Numeric FTP response code (status)
    %S		  Response message send from the client (available since v1.3.1rc1)
    %t		  Current local time
    %{format}t	  Current local time formatted (strftime(3) format)
    %T		  Time taken to transmit/receive file, in seconds 
    %u		  Local authenticated userid
    %U		  USER name originally sent by the client
    %v		  ServerName of server handling session
    %V		  DNS name of server handling session
    %{version}	  Print ProFTPD Version
    %{protocol}       Protocol used

    Examples

    LoginPasswordPrompt

    Name

    LoginPasswordPrompt -- Configure to display the passwort prompt or not

    Synopsis

    LoginPasswordPrompt [ LoginPasswordPrompt on|off]

    Default

    LoginPasswordPrompt on

    Context

    server config, <VirtualHost>, <Anonymous>, <Global>

    Module

    mod_auth

    Compatibility

    1.2.0pre1 and later

    Description

    If set to off, ProFTPd will skip the password request if the login will be denied regardless of password, e.g., if a <Limit LOGIN> directive forbids the connection.

    See also

    Examples

    MasqueradeAddress

    Name

    MasqueradeAddress -- Configure the server address presented to clients

    Synopsis

    MasqueradeAddress [ MasqueradeAddress ip-address|dns-hostname]

    Default

    none

    Context

    server config, <VirtualHost>

    Module

    mod_core

    Compatibility

    1.2.2 and later

    Description

    MasqueradeAddress causes the server to display the network information for the specified IP address or DNS hostname to the client, on the assumption that that IP address or DNS host is acting as a NAT gateway or port forwarder for the server.

    See also

    Examples

        MasqueradeAddress nat-gw.mydomain.com

    MaxClients

    Name

    MaxClients -- Limits the number of users that can connect

    Synopsis

    MaxClients [ MaxClients number|none [message]]

    Default

    MaxClients none

    Context

    server config, <Anonymous>, <VirtualHost>, <Global>

    Module

    mod_auth

    Compatibility

    0.99.0 and later

    Description

    The MaxClients directive configures the maximum number of authenticated clients which may be logged into a server or anonymous account. Once this limit is reached, additional clients attempting to authenticate will be disconnected. The special value none may be supplied which removes all maximum connection limits from the applicable configuration context. Additionally, an optional message argument may be used which will be displayed to a client attempting to exceed the maximum value; immediately before disconnection. The message argument is parsed for the magic string "%m", which is replaced with the configured maximum value. If message is not supplied, a system-wide default message is used. Example: MaxClients 5 "Sorry, the maximum number of allowed users are already connected (%m)" Results in: 530 Sorry, the maximum number of allowed users are already connected (5)

    See also

    Examples

    MaxClientsPerClass

    Name

    MaxClientsPerClass -- Limit the number of connections per class

    Synopsis

    MaxClientsPerClass [ MaxClientsPerClass name number|"none" [message]]

    Default

    None

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_auth

    Compatibility

    1.2.10rc1 and later

    Description

    The MaxClientsPerClass directive configures the maximum number of clients that may be connected at any given time from the same Class. The optional argument message may be used which will be displayed to a client attempting to exceed the maximum value. If message is not supplied, a default message of "Sorry, the maximum number of clients (%m) from your class are already connected."

    Examples

    MaxClientsPerClass foo 1 "Only one such client at a time."
    Results in: 530 Only one such client at a time.

    MaxClientsPerHost

    Name

    MaxClientsPerHost -- Limits the connections per client machine

    Synopsis

    MaxClientsPerHost [ MaxClientsPerHost number|none [message]]

    Default

    MaxClientsPerHost none

    Context

    server config, <Anonymous>, <VirtualHost>, <Global>

    Module

    mod_auth

    Compatibility

    1.1.7 and later

    Description

    The MaxClientsPerHost directive configures the maximum number of clients allowed to connect per host. The optional argument message may be used which will be displayed to a client attempting to exceed the maximum value. If message is not supplied, a default message of "Sorry, the maximum number clients (%m) from your host are already connected." is used.

    See also

    MaxClients, MaxHostsPerUser

    Examples

    MaxClientsPerHost 1 "Sorry, you may not connect more than one time."
    Results in: 530 Sorry, you may not connect more than one time.

    MaxClientsPerUser

    Name

    MaxClientsPerUser -- Limit the number of connections per userid

    Synopsis

    MaxClientsPerUser [ MaxClientsPerUser number|none [message]]

    Default

    MaxClientsPerUser none

    Context

    server config, <VirtualHost>, <Global>, <Anonymous>

    Module

    mod_auth

    Compatibility

    1.2.7rc1 and later

    Description

    The MaxClientsPerUser directive configures the maximum number of clients that may be connected at any given time using the same user name. The optional argument message may be used which will be displayed to a client attempting to exceed the maximum value. If message is not supplied, a default message of "Sorry, the maximum number of clients (%m) for this user already connected."

    Examples

    MaxClientsPerUser 1 "Only one such user at a time."
    Results in: 530 Only one such user at a time.

    MaxConnectionRate

    Name

    MaxConnectionRate -- Maximum TCP socket connection rate

    Synopsis

    MaxConnectionRate [ connections per second]

    Default

    none

    Context

    server config

    Module

    mod_core

    Compatibility

    1.2.7rc1 and later

    Description

    Set the maxiumum rate at which new TCP connections are accepted, this applies to the entire server, therefore too low a value on a high traffic server can result in all VirtualHosts being made unavailable due to normal traffic levels.

    The value is the number of connections in a given second at which the block comes into effect, thus a value of "1" will result in all connections being blocked.

    See also

    Examples

    MaxConnectionRate 4

    MaxConnectionsPerHost

    Name

    MaxConnectionsPerHost -- Limits the unauthenticated connections per client machine

    Synopsis

    MaxConnectionsPerHost [ MaxConnectionsPerHost number|none [message]]

    Default

    MaxConnectionsPerHost none

    Context

    server config, <Anonymous>, <VirtualHost>, <Global>

    Module

    mod_auth

    Compatibility

    1.2.11rc1 and later

    Description

    The MaxConnectionsPerHost directive configures the maximum number of unauthenticated clients allowed to connect per host. The optional argument message may be used which will be displayed to a client attempting to exceed the maximum value. If message is not supplied, a default message of "Sorry, the maximum number of connections (%m) from your host are already connected." is used.

    See also

    MaxClients, MaxClientsPerHost, MaxHostsPerUser

    Examples

    MaxConnectionsPerHost 1 "Sorry, you may not connect more than one time."
    Results in: 530 Sorry, you may not connect more than one time.

    MaxHostsPerUser

    Name

    MaxHostsPerUser -- Limit the number of connections per userid

    Synopsis

    MaxHostsPerUser [ MaxHostsPerUser number|none [message]]

    Default

    MaxHostsPerUser none

    Context

    server config, <Anonymous>, <VirtualHost>, <Global>

    Module

    mod_auth

    Compatibility

    1.2.4 and later

    Description

    The MaxHostsPerUser directive configures the maximum number of times different hosts, using a given login, can connect at any given time. The optional argument message may be used which will be displayed to a client attempting to exceed the maximum value. If message is not supplied, a default message of "Sorry, the maximum number of hosts (%m) for this user already connected."

    Examples

    MaxHostsPerUser 1 "Sorry, you may not connect more than one time."
    Results in: 530 Sorry, you may not connect more than one time.

    MaxInstances

    Name

    MaxInstances -- Sets the maximum number of child processes to be spawned

    Synopsis

    MaxInstances [ MaxInstances number]

    Default

    MaxInstances none

    Context

    server config

    Module

    mod_core

    Compatibility

    1.1.6pl1

    Description

    The MaxInstances directive configures the maximum number of child processes that may be spawned by a parent proftpd process in standalone mode. The directive has no effect when used on a server running in inetd mode. Because each child proftpd process represents a single client connection, this directive also controls the maximum number of simultaneous connections allowed. Additional connections beyond the configured limit are syslog'd and silently disconnected. The MaxInstances directive can be used to prevent undesirable denial-of-service attacks (repeatedly connecting to the ftp port, causing proftpd to fork-bomb). By default, no limit is placed on the number of child processes that may run at one time.

    See also

    Examples

    MaxLoginAttempts

    Name

    MaxLoginAttempts -- Sets how many password attempts are allowed before disconnection

    Synopsis

    MaxLoginAttempts [ MaxLoginAttempts number]

    Default

    MaxLoginAttempts 3

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_auth

    Compatibility

    0.99.0 and later

    Description

    The MaxLoginAttempts directive configures the maximum number of times a client may attempt to authenticate to the server during a given connection. After the number of attempts exceeds this value, the user is disconnected and an appropriate message is logged via the syslog mechanism.

    See also

    Examples

    MaxRetrieveFileSize

    Name

    MaxRetrieveFileSize -- Restrict size of downloaded files

    Synopsis

    MaxRetrieveFileSize [ number|"*" units ["user"|"group"|"class" expression]]

    Default

    None

    Context

    server config, <Global>, <VirtualHost>, <Anonymous>, <Directory>, .ftpaccess

    Module

    mod_xfer

    Compatibility

    1.2.7rc1 and later

    Description

    When downloading files to clients (eg serving a RETR request), the server will check for any configured limit against the size of the file being requested, and abort any transfers if the requested file's size exceeds the configured limit.

    A single "*" argument configures unlimited file sizes, and is used primarily to override any inherited restrictions from higher contexts. The given number is the number of bytes for the limit, and is followed by a units specifier of (case-insensitive) "Gb" (Gigabytes), "Mb" (Megabytes), "Kb" (Kilobytes), or "B" (bytes). The given number of bytes is multiplied by the appropriate factor.

    The optional parameters are used to restrict the file size limits only to specific users. If the "user" restriction is given, then expression is a user-expression specifying to which users the rule applies. Similarly for the "group" restriction. For the "class" restriction, the expression is simply the name of connection class for whom the rule will apply. If no matching user, group, or class expression is found for the current user (in that order), then a limit with no expression (i.e. no "user", "group", or "class" identifier) is applied.

    See Also: MaxStoreFileSize

    See also

    Examples

      # Restrict downloads to only 1 gigabyte
      MaxRetrieveFileSize 1 Gb

      # Restrict downloads for user fred, but allow unlimited download size for
      # everyone else
      MaxStoreFileSize 50 Kb user fred
      MaxStoreFileSize *

    MaxStoreFileSize

    Name

    MaxStoreFileSize -- Restrict size of uploaded files

    Synopsis

    MaxStoreFileSize [ number|"*" units ["user"|"group"|"class" expression]]

    Default

    None

    Context

    server config, <Global>, <VirtualHost>, <Anonymous>, <Directory>, .ftpaccess

    Module

    mod_xfer

    Compatibility

    1.2.7rc1 and later

    Description

    When uploading files from a client (eg serving a STOR request), the server will check for any configured limit against the size of the file being sent, and abort any transfers if/when the given file's size exceeds the configured limit.

    A single "*" argument configures unlimited file sizes, and is used primarily to override any inherited restrictions from higher contexts. The given number is the number of bytes for the limit, and is followed by a units specifier of (case-insensitive) "Gb" (Gigabytes), "Mb" (Megabytes), "Kb" (Kilobytes), or "B" (bytes). The given number of bytes is multiplied by the appropriate factor.

    The optional parameters are used to restrict the file size limits only to specific users. If the "user" restriction is given, then expression is a user-expression specifying to which users the rule applies. Similarly for the "group" restriction. For the "class" restriction, the expression is simply the name of connection class for whom the rule will apply. If no matching user, group, or class expression is found for the current user (in that order), then a limit with no expression (ie no "user", "group", or "class" identifier) is applied.

    See Also: MaxRetrieveFileSize

    See also

    Examples

      # Restrict upload to only 3 megabytes
      MaxStoreFileSize 3 Mb

      # Restrict anonymous uploads to 50k, but allow unlimited upload size for
      # everyone else
      MaxStoreFileSize 50 Kb user anonymous
      MaxStoreFileSize *

    MultilineRFC2228

    Name

    MultilineRFC2228 -- Enable RFC2228 multiline response mode

    Synopsis

    MultilineRFC2228 [ MultilineRFC2228 on|off]

    Default

    MultilineRFC2228 off

    Context

    server config

    Module

    mod_core

    Compatibility

    1.2.0pre3 and later

    Description

    By default, proftpd sends multiline responses as per RFC 959, i.e.: 200-First line More lines... 200 Last line RFC 2228 specifies that "6xy" response codes will be sent as follows: 600-First line 600-More lines... 600 Last line Note that 2228 ONLY specifies this for response codes starting with '6'. Enabling this directive causes ALL responses to be sent in this format, which may be more compatible with certain web browsers and clients. Also note that this is NOT the same as wu-ftpd's multiline responses, which do not comply with any RFC. Using this method of multilines is more likely to be compatible with all clients, although it isn't strictly RFC, and is thus not enabled by default.

    See also

    Examples

    Order

    Name

    Order -- Configures the precedence of the Limit directives

    Synopsis

    Order [ Order allow,deny|deny,allow]

    Default

    Order allow,deny

    Context

    <Limit>

    Module

    mod_core

    Compatibility

    0.99.0pl6 and later

    Description

    The Order directive configures the order in which Allow and Deny directives are checked inside of a <Limit> block. Because Allow directives are permissive, and Deny directives restrictive, the order in which they are examined can significantly alter the way security functions. If the default setting of allow,deny is used, "allowed" access permissions are checked first. If an Allow directive explicitly allows access to the <Limit> context, access is granted and any Deny directives are never checked. If Allow did not explicitly permit access, Deny directives are checked. If any Deny directive applies, access is explicitly denied. Otherwise, access is granted. When deny,allow is used, "deny" access restrictions are checked first. If any restriction applies, access is denied immediately. If nothing is denied, Allow permissions are checked. If an Allow explicitly permits access, access to the entire context is permitted; otherwise access is implicitly denied. For clarification, the following illustrates the steps used when checking Allow/Deny access: Order allow,deny Check Allow directives. If one or more apply, exit with result: ALLOW Check Deny directives. If one or more apply, exit with result: DENY Exit with default implicit ALLOW Order deny,allow Check Deny directives. If one or more apply, exit with result: DENY Check Allow directives. If one or more apply, exit with result: ALLOW Exit with default implicit: DENY

    See also

    Examples

    PassivePorts

    Name

    PassivePorts -- Specify the ftp-data port range to be used

    Synopsis

    PassivePorts [ PassivePorts min-pasv-port max-pasv-port]

    Default

    None

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_core

    Compatibility

    1.2.0rc2 and later

    Description

    PassivePorts restricts the range of ports from which the server will select when sent the PASV command from a client. The server will randomly choose a number from within the specified range until an open port is found. Should no open ports be found within the given range, the server will default to a normal kernel-assigned port, and a message logged.

    The port range selected must be in the non-privileged range (eg. greater than or equal to 1024); it is STRONGLY RECOMMENDED that the chosen range be large enough to handle many simultaneous passive connections (for example, 49152-65534, the IANA-registered ephemeral port range).

    See also

    Examples

    # Use the IANA registered ephemeral port range
    PassivePorts 49152 65534

    PathAllowFilter

    Name

    PathAllowFilter -- Only allow new files which match a specified pattern

    Synopsis

    PathAllowFilter [ PathAllowFilter regular-expression]

    Default

    None

    Context

    server config, <VirtualHost>, <Anonymous>, <Global>, <Directory>, .ftpaccess

    Module

    mod_core

    Compatibility

    1.1.7 and later

    Description

    PathAllowFilter allows the configuration of a regular expression that must be matched for all newly uploaded (stored) files. The regular expression is applied against the entire pathname specified by the client, so care must be taken when creating a proper regex. Paths that fail the regex match result in a "Forbidden filename" error being returned to the client. If the regular-expression argument contains whitespace, it must be enclosed in quotes.

    Examples

    # Only allow a-z 0-9 . - _ in file names,
    PathAllowFilter ^[a-z0-9._-]+$
    
    # as above but with upper case characters as well
    PathAllowFilter ^[A-Za-z0-9._-]+$

    PathDenyFilter

    Name

    PathDenyFilter -- Disallow new files which match a specified pattern

    Synopsis

    PathDenyFilter [ PathDenyFilter regular-expression]

    Default

    None

    Context

    server config, <VirtualHost>, <Anonymous>, <Global>, <Directory>, .ftpaccess

    Module

    mod_core

    Compatibility

    1.1.7 and later

    Description

    Similar to PathAllowFilter, PathDenyFilter specifies a regular expression which must not match any uploaded pathnames. If the regex does match, a "Forbidden filename" error is returned to the client. This can be especially useful for forbidding .ftpaccess or .htaccess files.

    Examples

    # We don't want .ftpaccess or .htaccess files to be uploaded
    PathDenyFilter "(\\.ftpaccess|\\.htaccess)$"

    PersistentPasswd

    Name

    PersistentPasswd -- Sets handling of unix auth files

    Synopsis

    PersistentPasswd [ PersistentPasswd on|off]

    Default

    Platform dependent

    Context

    server config

    Module

    mod_auth_unix

    Compatibility

    1.1.5 and later

    Description

    The PersistentPasswd directive controls how proftpd handles authentication, user/group lookups, and user/group to name mapping. If set to "on", proftpd will attempt to open the system-wide /etc/passwd, /etc/group (and /etc/shadow, potentially) files itself, holding them open even during a chroot()ed login. Note that /etc/shadow is never held open, for security reasons). On some platforms, you must turn this option on, as the libc functions are incapable of accessing these databases from inside of a chroot(). At configure-time, the configuration script will attempt to detect whether or not you need this support, and make it the default. However, such "guessing" may fail, and you will have to manually enable or disable the feature. If you cannot see user or group names when performing a directory listing inside an anonymous chrooted login, this indicates you must enable the directive. Use of the AuthUserFile or AuthGroupFile directives will force partial support for persistent user or group database files, regardless of PersistentPasswd's setting.

    Note: NIS/NIS+ and NSS users will most likely want to disable this feature, regardless of proftpd's detected configuration defaults. Failure to disable this will make your NIS/NIS+ maps and NSS lookups not work! On certain systems, you may also need to compile ProFTPD with the --enable-autoshadow option in order to authenticate both users from NIS maps or NSS lookups, and local users.

    See also

    Examples

    PidFile

    Name

    PidFile -- Set the filepath to hold the pid of the master server

    Synopsis

    PidFile [ PidFile filename]

    Default

    none

    Context

    server config, <Global>

    Module

    mod_core

    Compatibility

    1.2.0rc2 and later

    Description

    The PidFile directive sets the file to which the server records the process id of the daemon. The filename should be relative to the system root, ie /var/run/proftpd/pidfile. The PidFile is only used in standalone mode. It is often useful to be able to send the server a signal, so that it closes and then reopens its ErrorLog and TransferLog, and re-reads its configuration files. This is done by sending a SIGHUP (kill -1) signal to the process id of the master daemon listed in the PidFile.

    See also

    Examples

    Port

    Name

    Port -- Set the port for the control socket

    Synopsis

    Port [ Port port-number]

    Default

    Port 21

    Context

    server config, <VirtualHost>

    Module

    mod_core

    Compatibility

    0.99.0 and later

    Description

    The Port directive configures the TCP port which proftpd will listen on while running in standalone mode. It has no effect when used upon a server running in inetd mode (see ServerType). The directive can be used in conjunction with <VirtualHost> in order to run a virtual server on the same IP address as the master server, but listening on a different port.

    For any server, either <VirtualHost> or server config, setting Port 0 effectively turns off that server.

    See also

    Examples

    RadiusAcctServer

    Name

    RadiusAcctServer -- Setup RADIUS accounting details

    Synopsis

    RadiusAcctServer [ server[:port] shared-secret [timeout]]

    Default

    none

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_radius

    Compatibility

    1.2.7rc1 and later

    Description

    The RadiusAcctServer is used to specify a RADIUS server to be used for accounting. The server parameter may be either an IP address or a DNS hostname. If not specified, the port used will be the IANA-registered 1813. The optional timeout parameter is used to tell mod_radius how long to wait for a response from the server; it defaults to 30 seconds.

    Multiple RadiusAcctServers may be configured; each will be tried, in order of appearance in the configuration file, until that server times out or mod_radius receives a response.

    If no RadiusAcctServers are configured, mod_radius will not use RADIUS for accounting.

    RadiusAuthServer

    Name

    RadiusAuthServer -- Setup RADIUS authenticator details

    Synopsis

    RadiusAuthServer [ server[:port] shared-secret [timeout]]

    Default

    none

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_radius

    Compatibility

    1.2.7rc1 and later

    Description

    The RadiusAcctServer is used to specify a RADIUS server to be used for accounting. The server parameter may be either an IP address or a DNS hostname. If not specified, the port used will be the IANA-registered 1813. The optional timeout parameter is used to tell mod_radius how long to wait for a response from the server; it defaults to 30 seconds.

    Multiple RadiusAcctServers may be configured; each will be tried, in order of appearance in the configuration file, until that server times out or mod_radius receives a response.

    If no RadiusAcctServers are configured, mod_radius will not use RADIUS for accounting.

    RadiusEngine

    Name

    RadiusEngine -- Enable RADIUS support

    Synopsis

    RadiusEngine [ on|off]

    Default

    off

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_radius

    Compatibility

    1.2.7rc1 and later

    Description

    The RadiusEngine directive enables or disables the module's runtime RADIUS engine. If it is set to off this module does no RADIUS authentication or accounting at all. Use this directive to disable the module instead of commenting out all mod_radius directives.

    See also

    RadiusLog

    Name

    RadiusLog -- Specify the logfile for reporting / debugging

    Synopsis

    RadiusLog [ "file"|none]

    Default

    none

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_radius

    Compatibility

    1.2.7rc1 and later

    Description

    The RadiusLog directive is used to a specify a log file for mod_radius reporting and debugging, and can be done a per-server basis. The file parameter must be the full path to the file to use for logging. Note that this path must not be to a world-writeable directory and, unless AllowLogSymlinks is explicitly set to on (generally a bad idea), the path must not be a symbolic link.

    If file is "none", no logging will be done at all; this setting can be used to override a RadiusLog setting inherited from a <Global> context.

    See also

    RadiusRealm

    Name

    RadiusRealm -- Setup the authentication realm

    Synopsis

    RadiusRealm [ realm]

    Default

    none

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_radius

    Compatibility

    1.2.7rc1 and later

    Description

    The RadiusRealm directive configures a realm string that will be added to the username in the constructed RADIUS packets.

    See also

    Examples

      RadiusRealm .castaglia.org

    RadiusUserInfo

    Name

    RadiusUserInfo -- Configure login information via RADIUS

    Synopsis

    RadiusUserInfo [ uid gid home shell [suppl-group-names suppl-group-ids]]

    Default

    none

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_radius

    Compatibility

    1.2.7rc1 and later

    Description

    The RadiusUserInfo directive is used to configure login information used for every user authenticated via RADIUS. The optional suppl-group-names and suppl-group-ids parameters are used to specify supplemental group membership for each user; the number of names and IDs must match if these parameters are used.

    In order to support RADIUS servers that may use custom attributes in their Access-Accept response packets to supply user information back to the RADIUS client (mod_radius in this case), this directive allows the following syntax for some of its parameters:

      $(attribute-id:default-value)

    where the enclosing $() signals that the parameter is to be supplied by the RADIUS server, attribute-id is the custom attribute ID for which to search in the response packet, and default-value is the value to use in case the requested attribute is not present in the response packet. This syntax is not supported for the suppl-group-names or suppl-group-ids parameters.

    If RadiusUserInfo is not used, mod_radius will perform pure "yes/no" authentication only, in the style of PAM. The information that would have been configured via this directive will be pulled from other sources (e.g. /etc/passwd, AuthUserFiles, MySQL tables, etc).

    See also

    RatioFile

    Name

    RatioFile -- Ratio directive

    Synopsis

    RatioFile [ RatioFile foo1 foo2 foo3]

    Default

    None known

    Context

    <Directory>, <Anonymous>, <Limit>,.ftpaccess

    Module

    mod_ratio

    Compatibility

    at least 1.2.0 and later

    Description

    The RatioFile directive .... Example: RatioFile

    See also

    Examples

    Ratios

    Name

    Ratios -- (docs incomplete)

    Synopsis

    Ratios [ Ratios foo1 foo2 foo3]

    Default

    None known

    Context

    <Directory>, <Anonymous>, <Limit>,.ftpaccess

    Module

    mod_ratio

    Compatibility

    at least 1.2.0 and later

    Description

    The Ratios directive .... Example: Ratios

    See also

    Examples

    RatioTempFile

    Name

    RatioTempFile -- Ratio directive

    Synopsis

    RatioTempFile [ RatioTempFile foo1 foo2 foo3]

    Default

    None known

    Context

    <Directory>, <Anonymous>, <Limit>,.ftpaccess

    Module

    mod_ratio

    Compatibility

    at least 1.2.0 and later

    Description

    The RatioTempFile directive .... Example: RatioTempFile

    See also

    Examples

    RequireValidShell

    Name

    RequireValidShell -- Allow connections based on /etc/shells

    Synopsis

    RequireValidShell [ RequireValidShell on|off]

    Default

    RequireValidShell on

    Context

    server config, <VirtualHost>, <Anonymous>, <Global>

    Module

    mod_auth

    Compatibility

    0.99.0 and later

    Description

    The RequireValidShell directive configures the server, virtual host or anonymous login to allow or deny logins which do not have a shell binary listed in /etc/shells. By default, proftpd disallows logins if the user's default shell is not listed in /etc/shells. If /etc/shells cannot be found, all default shells are assumed to be valid.

    See also

    Examples

    RewriteCondition

    Name

    RewriteCondition -- Define a rule condition

    Synopsis

    RewriteCondition [ condition pattern]

    Default

    None

    Context

    server config, <Global>, <VirtualHost>, <Anonymous>, <Directory>

    Module

    mod_rewrite

    Compatibility

    1.2.6rc1 and later

    Description

    The RewriteCondition directive defines a rule condition. Precede a RewriteRule directive with one or more RewriteCondition directives. The following rewriting rule is only used if its pattern matches the current state of the FTP command and if these additional conditions apply too.

    Condition is a string which can contain the following expanded constructs in addition to plain text:

    • RewriteRule backreferences

      These are backreferences of the form:

      $N

      (0 <= N <= 9) which provide access to the grouped parts (parentheses!) of the pattern from the corresponding RewriteRule directive (the one following the current bunch of RewriteCondition directives). Note that $0 will refer back to the entire original string being matched.

    • RewriteCondition backreferences

      These are backreferences of the form:

      %N

      (0 <= N <= 9) which provide access to the grouped parts (parentheses!) of the pattern from the previous RewriteCondition attached to this RewriteRule.

    • RewriteMap expansions:

      These are expansions of the form:

      ${map-name:lookup-key|default-value}

      See the documentation for RewriteMap for more details.

    • Variable substitutions:

      These are substitutions of the form:

      • %a client IP address

      • %c name of Class for current session

      • %f filename

      • %F transfer path, as seen by the client (only useful for upload/download commands)

      • %g primary group of authenticated user

      • %G supplemental groups of authenticated user

      • %h client DNS name

      • %m FTP command

      • %p port of server handling the session

      • %u name of authenticated user

      • %U name of user sent by client via USER

      • %v ServerName of server handling the session

    Pattern is the condition pattern, i.e., a regular expression which is applied to the current instance of the condition, i.e., condition is evaluated and then matched against pattern. You can prefix the pattern string with a '!' character (exclamation mark) to specify a non-matching pattern.

    Examples

    RewriteEngine

    Name

    RewriteEngine -- Enable/disable mod_rewrite

    Synopsis

    RewriteEngine [ on|off]

    Default

    off

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_rewrite

    Compatibility

    1.2.6rc1 and later

    Description

    The RewriteEngine directive enables or disables the module's runtime rewriting engine. If it is set to off this module does no parsing or rewriting at all. Use this directive to disable the module instead of commenting out all mod_rewrite directives.

    See also

    RewriteLock

    Name

    RewriteLock -- Set the filename for synchronization lockfile

    Synopsis

    RewriteLock [ filename]

    Default

    None

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_rewrite

    Compatibility

    1.2.6rc1 and later

    Description

    The RewriteLock directive sets the filename for a synchronization lockfile which mod_rewrite needs to communicate with RewriteMaps of type fifo. Set file to a local absolute path (not on a NFS-mounted device) when you want to use a rewriting FIFO. It is not required for other types of rewriting maps.

    See also

    RewriteLog

    Name

    RewriteLog -- Specify a log file for mod_rewrite reporting

    Synopsis

    RewriteLog [ file|"none"]

    Default

    None

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_rewrite

    Compatibility

    1.2.6rc1 and later

    Description

    The RewriteLog directive is used to a specify a log file for mod_rewrite reporting and debugging, and can be done a per-server basis. The file parameter must be the full path to the file to use for logging. Note that this path must not be to a world-writeable directory and, unless AllowLogSymlinks is explicitly set to on (generally a bad idea), the path must not be a symbolic link. In general, this directive should only be used for debugging your mod_rewrite configuration, and should be removed once debugging is completed; do not use this directive in a production configuration.

    If file is "none", no logging will be done at all; this setting can be used to override a RewriteLog setting inherited from a <Global> context.

    See also

    RewriteMap

    Name

    RewriteMap -- Define a rewrite map

    Synopsis

    RewriteMap [ map-name map-type:map-soure]

    Default

    None

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_rewrite

    Compatibility

    1.2.6rc1 and later

    Description

    The RewriteMap directive defines a rewriting map which can be used inside rule substitution strings by the mapping-functions to insert/substitute fields through a key lookup. The source of this lookup can be of various types.

    The map-name is the name of the map and will be used to specify a mapping-function for the substitution strings of a rewriting rule via one of the following constructs:

    ${ map-name : lookup-key }

    ${ map-name : lookup-key | default-value

    When such a construct occurs the map map-name is consulted and the key lookup-key is resolved. If the key is found, the map-function construct is substituted by subst-value. If the key is not found then it is substituted by default-value or by the empty string if no default-value was specified.

    The following combinations for map-type and map-src can be used:

    • Standard Plain Text

      map-type: txt, map-src: Unix filesystem path to valid regular file.

      This is the standard rewriting map feature where the map-src is a plain ASCII file containing either blank lines, comment lines (starting with a '#' character) or pairs like the following - one per line.

      matching-key subst-value

      Example 1-1. Example Usermap

      		    # --------------------------------------------
          		    # usermap.txt -- map for rewriting user names
          		    # --------------------------------------------
      
          		    Dave.Admin      dave       # The Uber-admin
          		    root            anonymous  # no one should be logging in as root anyway
      		

      And, to configure this map to be used:

      			RewriteMap real-to-user txt:/path/to/file/usermap.txt
      		
    • FIFO/Named Pipe

      map-type: fifo, map-src: Unix filesystem path to valid FIFO.

      For this rewriting map, map-src is a FIFO (a.k.a. named pipe). To create it, you can use the mkfifo(1) command. An external program that opens the FIFO for reading and writing must be started before proftpd is started. This program can communicate with the rewriting engine via the FIFO. For each mapping lookup, it can read the key to lookup as a newline-terminated string from the FIFO. It then has to write back to the FIFO the looked-up value as a newline-terminated string, or just simply newline character (denoting an empty string) if there is no corresponding value for the given key).

      An example program which will implement a 1:1 mapping (i.e., key == value) could be:

      Example 1-2. Example FIFO/Named Pipe 1:1 mapping

      #!/usr/bin/perl
          use strict;
      
          use File::Basename qw(basename);
          use Getopt::Long;
          use IO::Handle;
          use IO::Select;
      
          my $default_delay = 0.5;
          my $program = basename($0);
          my %opts = ();
      
          GetOptions(\%opts, 'delay=f', 'fifo=s', 'help', 'verbose');
      
          usage() if $opts{'help'};
      
          my $delay = $opts{'delay'} ? $opts{'delay'} : $default_delay;
      
          die "$program: missing required --fifo parameter\n" unless $opts{'fifo'};
          my $fifo = $opts{'fifo'};
      
          my $verbose = $opts{'verbose'} ? 1 : 0;
      
          open(my $fifo_fh, "+> $fifo") or die "$program: unable to open $fifo: $!\n";
      
          # Instantiate a Select object for knowing when to read from and write to
          # the FIFO.
          my $sel = IO::Select->new();
      
          while (1) {
      
            # Blocking select() for reading.
            $sel->add($fifo_fh);
      
            print STDERR "$program: selecting for reading\n" if $verbose;
            my ($rfh) = $sel->can_read();
      
            my $key = <$rfh>;
            print STDERR "$program: read '$key'\n" if $verbose;
      
            # Lookup a value for the given key.
            my $value = lookup_value($key);
      
            # Clear the Select object's filehandles.
            $sel->remove();
      
            print $fifo_fh "$value\n" if $verbose;
            $fifo_fh->flush();
      
            print STDERR "$program: wrote '$value'\n" if $verbose;
      
            # Wait for the buffer's byte to be cleared before reading again.
            wait_fifo($fifo_fh);
          }
      
          close($fifo_fh);
          print STDOUT "$program: done\n" if $verbose;
      
          exit 0;
      
          # --------------------------------------------------------------------------
          sub lookup_value {
            my ($key) = @_;
      
            # NOTE: do something to obtain a value for the given key here.
            chomp(my $value = $key);
      
            return $value;
          }
      
          # --------------------------------------------------------------------------
          sub usage {
            print STDOUT <<END_OF_USAGE;
      
          usage: $program [options]
      
            --delay         Configure the buffer check delay.
                            The default is $default_delay seconds.
      
            --fifo          Configure the path to the FIFO.  Required.
      
            --help          Displays this message.
      
            --verbose       Enables verbose output while $program runs.
      
          END_OF_USAGE
      
            exit 0;
          }
      
          # --------------------------------------------------------------------------
          sub wait_fifo {
            my ($fh) = @_;
      
            # Now we get tricky.  Use ioctl(2) to poll the number of bytes to
            # be read from the FIFO filehandle.  When the number drops to zero,
            # it means that the data we just wrote has been read from the buffer
            # by some other process, so we can go back to the top of this loop.
            # Otherwise, if this program loops faster than the reader/writer on
            # the other end of the FIFO, we'd end up reading the data we just
            # wrote.  Quite annoying, actually.
            #
            # Note: this value must be manually extracted from the system header files
            # using the following program:
            #
            # -------- fionread.c -------------------
            #  #include <sys/ioctl.h>
            #
            #  int main(int argc, char *argv[]) {
            #   printf("%#08x\n", FIONREAD);
            #   return 0;
            # }
            # ---------------------------------------
            #
            # > cc -o fionread fionread.c
            # > ./fionread
      
            my $FIONREAD = 0x00541b;
      
            my $size = pack('L', 0);
            ioctl($fh, $FIONREAD, $size) or die "$program: unable to use ioctl: $!\n";
            $size = unpack('L', $size);
      
            while ($size != 0) {
              print STDERR "$program: waiting for buffer to be read\n" if $verbose;
              select(undef, undef, undef, $delay);
      
              $size = pack('L', 0);
              ioctl($fh, $FIONREAD, $size) or die "$program: unable to use ioctl: $!\n";
              $size = unpack('L', $size);
            }
          }
      
      		

      To make use of this example script, simply implement your lookup code in the lookup_value() subroutine. Be very careful with such scripts, though:

      1. "Keep it simple, stupid" (KISS), because if this program hangs it will hang proftpd when the rule occurs. Well, keep it as simple as possible...

      2. Avoid one common mistake: avoid buffered I/O if possible. This can cause a deadloop. If necessary, be sure to flush the filehandle before reading, and after writing.

      3. Use the RewriteLock directive to define a lockfile mod_rewrite can use to synchronize the communication to the FIFO program. By default no such synchronization takes place.

    • Internal Function

      map-type: int, map-src: Internal mod_rewrite function.

      Here the map-src is a mod_rewrite built-in function. Currently you cannot create your own, but the following functions already exist:

      • toupper

        Converts the looked up key to all upper case.

      • tolower

        Converts the looked up key to all lower case.

      • unescape

        Translates hex-encodings in the looked up key back to special characters.

      • utf8trans

        Translates UTF-8 encodings in the lookup up key into Latin-1 characters.

    The RewriteMap directive can occur more than once. For each mapping-function use one RewriteMap directive to declare its rewriting map name.

    Note: For plain text files the looked-up keys are cached in-core until the mtime of the text map file changes or the server does a restart. This way you can have map-functions in rules which are used for every request. This is no problem, because the parsing of the text files only happens once!

    RewriteRule

    Name

    RewriteRule -- Define a rewrite rule

    Synopsis

    RewriteRule [ pattern substitution]

    Default

    None

    Context

    server config, <Global>, <VirtualHost>, <Anonymous>, <Directory>

    Module

    mod_rewrite

    Compatibility

    1.2.6rc1 and later

    Description

    The RewriteRule directive is the real rewriting workhorse. The configuration directive can occur more than once. Each directive defines a single rewriting rule. The order of definition of these rules is important, because this order is used when applying the rules at run-time.

    Pattern can be POSIX regular expression which gets applied to the current FTP command argument(s).

    Some hints about the syntax of regular expressions:

    • Text:

      	        .           Any single character
        		[chars]     Character class: one of chars
      		[^chars]    Character class: none of chars
        		text1|text2 Alternative: text1 or text2
      	      
    • Quantifiers:

      	        ?           0 or 1 of the preceding text
        		*           0 or N of the preceding text (N > 0)
        		+           1 or N of the preceding text (N > 1)
      	      
    • Grouping:

       	      (text)       Grouping of text
                    		   (either to set the borders of an alternative or
                    		   for making backreferences where the Nth group can 
                    		   be used on the RHS of a RewriteRule with $N)
      	      
    • Anchors:

      	        ^           Start of line anchor
        		$           End of line anchor
      	      
    • Escaping:

      		\char       Escape that particular char
                    		    (for instance to specify the chars ".[]()" etc.)
      	      

    For more information about regular expressions have a look at your local regex(3) manpage. If you are interested in more detailed information about regular expressions and their variants (POSIX regex, Perl regex, etc.) have a look at the following dedicated book on this topic:

    Mastering Regular Expressions Jeffrey E.F. Friedl Nutshell Handbook Series O'Reilly & Associates, Inc. 1997 ISBN 1-56592-257-3

    Additionally in mod_rewrite the NOT character ('!') is a possible pattern prefix. This gives you the ability to negate a pattern; to say, for instance: "if the current argument(s) does NOT match this pattern". This can be used for exceptional cases, where it is easier to match the negative pattern, or as a last default rule.

    Notice: When using the NOT character to negate a pattern you cannot have grouped wildcard parts in the pattern. This is impossible because when the pattern does NOT match, there are no contents for the groups. In consequence, if negated patterns are used, you cannot use $N in the substitution string.

    Substitution of a rewriting rule is the string which is substituted for (or replaces) the original argument(s) for which pattern matched. Beside plain text you can use:

    1. $N backreferences to the RewriteRule pattern

    2. %N backreferences to the last matched RewriteCondition pattern

    3. variables as in RewriteCondition test strings

    4. map function calls (${map-name:lookup-key|default-value})

    Backreferences are $N (N=0..9) identifiers which will be replaced by the contents of the Nth group of the matched pattern. The variables are the same as for the condition of a RewriteCondition directive, with two additions:

    • %P process ID

    • %t Unix time since the epoch, in seconds

    The map functions come from the RewriteMap directive and are explained there. These four types of variables are expanded in the order of the above list.

    All of the rewriting rules are applied to substitution. The command argument(s) is completely replaced by the substitution.

    Examples

    RLimitCPU

    Name

    RLimitCPU -- Configure the maximum CPU time in seconds used by a process

    Synopsis

    RLimitCPU [ RLimitCPU ["daemon"|"session"|"none"] soft-limit|"max" [hard-limit|"max"]]

    Default

    System defaults

    Context

    server config

    Module

    mod_core

    Compatibility

    1.2.1rc1 and later

    Description

    RLimitCPU takes from one to three parameters. The first parameter may be one of "daemon" (applies the limit only to the daemon process), "session" (applies the limit only to child processes handling each FTP session), or "none" (disables any possibly inherited limits). Note that if "daemon" is used, the directive may then only occur in the "server config" context. If none of these keywords are used, the limit is assumed to apply to both daemon and session processes. After any potential keyword, the resource limit must be set. The next parameter is also optional, and sets the maximum resource limit. Either limit parameter can be a number, or "max" to indicate to the server that the limit should be set to the maximum allowed by the operating system.

    CPU resource limits are expressed in seconds per process.

    Examples

    RLimitMemory

    Name

    RLimitMemory -- Configure the maximum memory in bytes used by a process

    Synopsis

    RLimitMemory [ RLimitMemory ["daemon"|"session"|"none"] soft-limit[units]|"max" [hard-limit[units]|"max"]]

    Default

    None

    Context

    server config

    Module

    mod_core

    Compatibility

    1.2.1rc1 and later

    Description

    RLimitMemory takes from one to three parameters. The first parameter may be one of "daemon" (applies the limit only to the daemon process), "session" (applies the limit only to child processes handling each FTP session), or "none" (disables any possibly inherited limits). Note that if "daemon" is used, the directive may then only occur in the "server config" context. If none of these keywords are used, the limit is assumed to apply to both daemon and session processes. After any potential keyword, the resource limit must be set. The next parameter is also optional, and sets the maximum resource limit. Either limit parameter can be a number, or "max" to indicate to the server that the limit should be set to the maximum allowed by the operating system.

    Memory resource limits are expressed in bytes per process. An optional case-insensitive units specifier may follow the number of bytes given: G (Gigabytes), M (Megabytes), K (Kilobytes), or B (bytes). If the units specifier is used, the given number of bytes is multiplied by the appropriate factor.

    See Also

    RLimitCPU, RLimitOpenFiles

    RLimitOpenFiles

    Name

    RLimitOpenFiles -- Configure the maximum number of open files used by a process

    Synopsis

    RLimitOpenFiles [ RLimitOpenFiles ["daemon"|"session"|"none"] soft-limit|"max" [hard-limit|"max"]]

    Default

    None

    Context

    server config

    Module

    mod_core

    Compatibility

    1.2.1rc1 and later

    Description

    RLimitOpenFiles takes from one to three parameters. The first parameter may be one of "daemon" (applies the limit only to the daemon process), "session" (applies the limit only to child processes handling each FTP session), or "none" (disables any possibly inherited limits). Note that if "daemon" is used, the directive may then only occur in the "server config" context. If none of these keywords are used, the limit is assumed to apply to both daemon and session processes. After any potential keyword, the resource limit must be set. The next parameter is also optional, and sets the maximum resource limit. Either limit parameter can be a number, or "max" to indicate to the server that the limit should be set to the maximum allowed by the operating system.

    File resource limits are expressed in number of files per process.

    See Also:

    RLimitCPU, RLimitMemory

    RootLogin

    Name

    RootLogin -- Permit root user logins

    Synopsis

    RootLogin [ RootLogin on|off]

    Default

    RootLogin off

    Context

    server config, <VirtualHost>, <Anonymous>, <Global>

    Module

    mod_auth

    Compatibility

    1.1.5 and later

    Description

    Normally, proftpd disallows root logins under any circumstance. If a client attempts to login as root, using the correct password, a special security message is sent to syslog. When the RootLogin directive is turned On, the root user may authenticate just as any other user could (assuming no other access control measures deny access); however the root login security message is still sysloged. Obviously, extreme care should be taken when using this directive.

    The use of RootLogin in the Anonymous context is only valid when the User / Group defined in the Anonymous block is set to 'root'

    See also

    Examples

    RootRevoke

    Name

    RootRevoke -- Drop root privileges completely

    Synopsis

    RootRevoke [ RootRevoke on|off]

    Default

    RootRevoke off

    Context

    server config, <VirtualHost>, <Global>, <Anonymous>

    Module

    mod_auth

    Compatibility

    1.2.9rc1 and later

    Description

    The RootRevoke directive causes all root privileges to be dropped once a user is authenticated. This will also cause active transfers to be disabled, if the server is listening on a port less than 1025. Note that this only affects active transfers; passive transfers will not be blocked.

    See also

    Examples

    SaveRatios

    Name

    SaveRatios -- FIXME FIXME

    Synopsis

    SaveRatios [ SaveRatios foo1 foo2 foo3]

    Default

    None known

    Context

    <Directory>, <Anonymous>, <Limit>,.ftpaccess

    Module

    mod_ratio

    Compatibility

    at least 1.2.0 and later

    Description

    The SaveRatios directive .... Example: SaveRatios

    See also

    Examples

    ScoreboardFile

    Name

    ScoreboardFile -- Sets the name and path of the scoreboard file

    Synopsis

    ScoreboardFile [ path]

    Default

    ScoreboardFile /usr/local/var/proftpd.scoreboard

    Context

    server config

    Module

    mod_core

    Compatibility

    1.2.7rc1 and later

    Description

    The ScoreboardFile directive sets the path to the file where the daemon will store its run-time "scoreboard" session information. This file is necessary for MaxClients to work properly, as well as other utilities (such as ftpwho and ftpcount). Note that the directory containing the scoreboard cannot be world-writable.

    This directive deprecates ScoreboardPath.

    See also

    Examples

    ScoreboardFile /var/run/proftpd.scoreboard

    ServerAdmin

    Name

    ServerAdmin -- Set the address for the server admin

    Synopsis

    ServerAdmin [ ServerAdmin "admin-email-address"]

    Default

    ServerAdmin root@[ServerName]

    Context

    server config, <VirtualHost>

    Module

    mod_core

    Compatibility

    0.99.0pl10 and later

    Description

    The ServerAdmin directive sets the email address of the administrator for the server or virtualhost. This address is displayed in magic cookie replacements (see DisplayLogin and DisplayFirstChdir).

    See also

    Examples

    ServerIdent

    Name

    ServerIdent -- Set the message displayed on connect

    Synopsis

    ServerIdent [ ServerIdent off|on [identification string]]

    Default

    ServerIdent on "ProFTPD [version] Server (server name) [hostname]"

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_core

    Compatibility

    1.2.0pre2 and later

    Description

    The ServerIdent directive sets the default message displayed when a new client connects. Setting this to off displays "[hostname] FTP server ready." If set to on, the directive can take an optional string argument, which will be displayed instead of the default text. Sites desiring to give out minimal information will probably want a setting like ServerIdent on "FTP Server ready.", which won't even reveal the hostname.

    See also

    Examples

    ServerIdent on "Welcome to ftp.linux.co.uk"

    ServerLog

    Name

    ServerLog -- Configure logs on a per-server basis

    Synopsis

    ServerLog [ path]

    Default

    None

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_log

    Compatibility

    1.2.8rc1 and later

    Description

    The ServerLog directive disables the daemon's use of the syslog mechanism and instead redirects all logging output for the server to the specified filename. The filename argument must contain an absolute path. Use of this directive overrides any facility set by the SyslogFacility directive, as well as overriding any configured SystemLog.

    ServerName

    Name

    ServerName -- Configure the name displayed to connecting users

    Synopsis

    ServerName [ ServerName "name"]

    Default

    ServerName "ProFTPD Server [version]"

    Context

    server config, <VirtualHost>

    Module

    mod_core

    Compatibility

    0.99.0 and later

    Description

    The ServerName directive configures the string that will be displayed to a user connecting to the server (or virtual server if the directive is located in a <VirtualHost> block). See Also: <VirtualHost>

    See also

    Examples

    ServerType

    Name

    ServerType -- Set the mode proftpd runs in

    Synopsis

    ServerType [ ServerType type-identifier]

    Default

    ServerType standalone

    Context

    server config

    Module

    mod_core

    Compatibility

    0.99.0 and later

    Description

    The ServerType directive configures the server daemon's operating mode. The type-identifier can be one of two values: inetd The daemon will expect to be run from the inetd "super server." New connections are passed from inetd to proftpd and serviced immediately. standalone The daemon starts and begins listening to the configured port for incoming connections. New connections result in spawned child processes dedicated to servicing all requests from the newly connected client.

    See also

    Examples

    SetEnv

    Name

    SetEnv -- (docs incomplete)

    Synopsis

    SetEnv [ key value]

    Default

    None

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_core

    Compatibility

    1.2.10rc1 and later

    Description

    (docs incomplete)

    See also

    Examples

    (docs incomplete)

    ShowSymlinks

    Name

    ShowSymlinks -- Toggle the display of symlinks

    Synopsis

    ShowSymlinks [ ShowSymlinks on|off]

    Default

    (versions 1.1.5 and beyond) ShowSymlinks On

    Context

    server config, <VirtualHost>, <Anonymous>, <Global>

    Module

    mod_ls

    Compatibility

    Description

    Compatibility: 0.99.0pl6 and later Symbolic links (if supported on the host OS and filesystem) can be either shown in directory listings (including the target of the link) or can be "hidden" (proftpd dereferences symlinks and reports the target's permissions and ownership). The default behavior is to show all symbolic links when normal users are logged in, and hide them for anonymous sessions. If a symbolic link cannot be dereferenced for any reason (permissions, target does not exist, etc) and ShowSymlinks is off, proftpd displays the link as a directory entry of type 'l' (link) with the ownership and permissions of the actual link. Under ProFTPD versions 1.1.5 and higher, the default behavior in regard to ShowSymlinks has been changed so that symbolic links are always displayed as such (in all cases), unless ShowSymlinks off is explicitly set.

    See also

    Examples

    SocketBindTight

    Name

    SocketBindTight -- Controls how TCP/IP sockets are created

    Synopsis

    SocketBindTight [ SocketBindTight on|off]

    Default

    SocketBindTight off

    Context

    server config

    Module

    mod_core

    Compatibility

    0.99.0pl6 and later

    Description

    The SocketBindTight directive controls how proftpd creates and binds its initial tcp listen sockets in standalone mode (see ServerType). The directive has no effect upon servers running in inetd mode, because listen sockets are not needed or created. When SocketBindTight is set to off (the default), a single listening socket is created for each port that the server must listen on, regardless of the number of IP addresses being used by <VirtualHost> configurations. This has the benefit of typically requiring a relatively small number of file descriptors for the master daemon process, even if a large number of virtual servers are configured. If SocketBindTight is set to on, a listen socket is created and bound to a specific IP address for the master server and all configured virtual servers. This allows for situations where an administrator may wish to have a particular port be used by both proftpd (on one IP address) and another daemon (on a different IP address). The drawback is that considerably more file descriptors will be required if a large number of virtual servers must be supported. Example: Two servers have been configured (one master and one virtual), with the IP addresses 10.0.0.1 and 10.0.0.2, respectively. The 10.0.0.1 server runs on port 21, while 10.0.0.2 runs on port 2001. SocketBindTight off #default # proftpd creates two sockets, both bound to ALL available addresses. # one socket listens on port 21, the other on 2001. Because each socket is # bound to all available addresses, no other daemon or user process will be # allowed to bind to ports 21 or 2001. ... SocketBindTight on # proftpd creates two sockets again, however one is bound to 10.0.0.1, port 21 # and the other to 10.0.0.2, port 2001. Because these sockets are "tightly" # bound to IP addresses, port 21 can be reused on any address OTHER than # 10.0.0.1, and visa-versa with 10.0.0.2, port 2001. One side-effect of setting SocketBindTight to on is that connections to non-bound addresses will result in a "connection refused" message rather than the typical "500 Sorry, no server available to handle request on xxx.xxx.xxx.xxx.", due to the fact that no listen socket has been bound to the particular address/port pair. This may or may not be aesthetically desirable, depending on your circumstances.

    See also

    Examples

    SocketOptions

    Name

    SocketOptions -- Tune socket-level options

    Synopsis

    SocketOptions [ [maxseg <size>] [rcvbuf <size>] [sndbuf <size>]]

    Default

    None

    Context

    "server config", <VirtualHost>

    Module

    mod_core

    Compatibility

    1.2.9rc1 and later

    Description

    The rcvbuf and sndbuf parameters are used for setting the TCP send/receive window sizes. The maxseg parameter is used for setting a MSS (Maximum Segment Size) via setsockopt(2)'s TCP_MAXSEG option. If the MSS is larger than the interface's MTU, it is ignored and has no effect.

    If the send/receive window size is increased, it is helpful for performance to increase the internal buffer size. See the --enable-buffer-size argument to ./configure.

    SQLAuthenticate

    Name

    SQLAuthenticate --  Specify authentication methods and what to authenticate

    Synopsis

    SQLAuthenticate {on | off}

      or

    SQLAuthenticate [ users ] [ groups ] [ userset [fast] ] [ groupset [fast] ]

    Default

    SQLAuthenticate on

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_sql

    Compatibility

    1.2.5rc1 and later

    Description

    The SQLAuthenticate directive configures mod_sql's authentication behavior, controlling whether to provide user and/or group information during authentication, and how that provisioning is performed. The parameters may appear in any order.

    The available parameter values are:

    • on

      Shorthand for SQLAuthenticate users groups userset groupset.

    • off

      Disables all mod_sql authentication functions.

    • users

      If present, mod_sql will do user lookups. If not present, mod_sql will do no user lookups at all, including the {set|get|end}pwent() calls (see below).

    • groups

      If present, mod_sql will do group lookups. If not present, mod_sql will do no group lookups at all, including the {set|get|end}grent() calls (see below).

    • userset[fast]

      If present, mod_sql will process the potentially expensive {set|get|end}pwent() calls. If not present, mod_sql will not process these calls. Adding the suffix "fast" tells mod_sql to process the users as a single large query, rather than making a query per user. This may significantly reduce the number of queries against the database at the expense of increased memory use. This parameter will have no effect if "users" is not specified.

    • groupset[fast]

      If present, mod_sql will process the potentially expensive {set|get|end}grent() calls. If not present, mod_sql will not process these calls. Adding the suffix "fast" tells mod_sql to process the groups as a single large query, rather than making a query per group. This may significantly reduce the number of queries against the database at the expense of increased memory use. This parameter will have no effect if "groups" is not specified.

    The SQLLog and SQLShowInfo directives will always be processed by mod_sql. The SQLAuthenticate directive only affects the user and group lookup/authentication portions of the module.

    Turning off (i.e. by not including) the userset or groupset parameters affects the functionality of mod_sql. Not allowing these lookups may remove the ability to control access or control functionality by group membership, depending on your other authentication handlers and the data available to them. At the same time, choosing not to do these lookups may dramatically speed login for many large sites.

    The "fast" suffix is not appropriate for every site. Normally, mod_sql will retrieve a list of users and groups, and get information from the database on a per-user or per-group basis. This is query intensive: it requires (nn + 1) queries, where n is the number of users or groups to lookup. By choosing "fast" lookups, mod_sql will make a single SELECT query to get information from the database.

    In exchange for the radical reduction in the number of queries, the single query will increase the memory consumption of the process; all group or user information will be read at once rather than in discrete chunks.

    Group Table Structure

    Normally mod_sql allows multiple group members per row, and multiple rows per group. If you use the "fast" option for groupset, you must use only one row per group. For example, normally mod_sql treats the following three tables in exactly the same way:

    |--------------------------------------------------|
    |  GROUPNAME  |  GID  |  MEMBERS                   |
    |--------------------------------------------------|
    | group1      | 1000  | naomi                      |
    | group1      | 1000  | priscilla                  |
    | group1      | 1000  | gertrude                   |
    |--------------------------------------------------|

    |--------------------------------------------------|
    |  GROUPNAME  |  GID  |  MEMBERS                   |
    |--------------------------------------------------|
    | group1      | 1000  | naomi, priscilla           |
    | group1      | 1000  | gertrude                   |
    |--------------------------------------------------|

    |--------------------------------------------------|
    |  GROUPNAME  |  GID  |  MEMBERS                   |
    |--------------------------------------------------|
    | group1      | 1000  | naomi, priscilla, gertrude |
    |--------------------------------------------------|

    If you use the "fast" option, mod_sql assumes that all entries are structured like the last example.

    Examples

    SQLAuthTypes

    Name

    SQLAuthTypes -- Specify the allowed authentication types and their check order

    Synopsis

    SQLAuthTypes [ [OpenSSL]] [ [Crypt]] [ [Backend]] [ [Plaintext]] [ [Empty]]

    Default

    none

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_sql

    Compatibility

    1.2.0 and later

    Description

    This directive deprecates 'SQLEmptyPasswords', 'SQLScrambledPasswords', 'SQLSSLHashedPasswords', 'SQLPlaintextPasswords', and 'SQLEncryptedPasswords'.

    The SQLAuthTypes directive specifies which authentication method are to be allowed, and their order of use. You must specify at least one authentication method.

    The current supported authentication methods are:

    • Backend

      Allows database-specific backend passwords. Not all backend databases support this option. For example, MySQL datatabases use this option to authenticate MySQL 'PASSWORD()' encrypted passwords. The Postgres backend, however, does nothing.Caveat : if your MySQL activity log is world-readable, the user password will be visible . You have been warned.

    • Crypt

      Allows passwords in the database to be of Unix crypt(3) form.

    • Empty

      Allows empty passwords in the database, which match against any password the user may give. The database field must be a truly empty string; NULL values are not acceptable as empty passwords. Be very careful if using this authentication method.

    • OpenSSL

      Allows passwords in the database to be of the form '{digest-name}hashed-value', where hashed-value is the base64-encoded digest of the passsword. Only available if you define HAVE_OPENSSL when you compile proftpd and you link with OpenSSL's libcrypto library.

    • Plaintext

      Allows passwords in the database to be in plaintext.

    See also

    Examples

    SQLAuthTypes Crypt Empty

    configures mod_sql to first attempt to verify the password using the Unix crypt(3) function, then, if that fails, determine if the password in the database is empty (thus matching any given password). If all of the configured authentication methods fail, mod_sql will fail to authenticate the user.

    SQLBackend

    Name

    SQLBackend -- Set the SQL backend module

    Synopsis

    SQLBackend [ backend]

    Default

    Depends

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_sql

    Compatibility

    1.3.0rc1 and later

    Description

    In 1.3.0rc1, the mod_sql module gained the ability to be compiled with multiple backend modules supported, e.g. to have both mod_sql_mysql and mod_sql_postgres usable in the same proftpd daemon. The SQLBackend directive configures which of these different database backends should be used.

    If there is only one backend module compiled in, the SQLBackend directive is not needed. If there are multiple backend modules compiled and no SQLBackend directive is specified, then mod_sql will default to using the first backend module listed. For instance, if you configured proftpd using a configure command such as: ./configure --with-modules=mod_sql:mod_sql_postgres:mod_sql_mysql ... then mod_sql would default to using mod_sql_postgres as the backend module to use.

    You might have multiple <VirtualHost> sections which use different SQL backends. Use "mysql" for the mod_sql_mysql module, and "postgres" for the mod_sql_postgres module.

    See also

    Examples

      <VirtualHost 1.2.3.4>
        SQLBackend mysql
        ...
      </VirtualHost>

      <VirtualHost 5.6.7.8>
        SQLBackend postgres
        ...
      </VirtualHost>

    SQLConnectInfo

    Name

    SQLConnectInfo -- Specify connection information for the backend

    Synopsis

    SQLConnectInfo [ connection-info] [ [username]] [ [password]] [ [policy]]

    Default

    None

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_sql

    Compatibility

    1.2.0 and later

    Description

    This directive deprecates 'MySQLInfo', 'PostgresInfo', and 'PostgresPort'.

    The SQLConnectInfo directive configures the information necessary to connect to the backend database. The connection-info parameter specifies the database, host, port, and other backend-specific information. The optional username and password parameters specify a username and password to use when connecting to the database. Both default to NULL, which the backend will treat in some backend-specific manner. If you specify a password, you must specify a username. If no SQLConnectInfo directive is specified, mod_sql will disable itself.

    Any given database backend has the opportunity, though not necessarily the responsibility, to check for syntax errors in the connection-info field at server startup, but you should not expect semantic errors (i.e., cannot connect to the database) to be caught until mod_sql attempts to connect for a given host.

    A given database connection is governed by a connection policy that specifies when a connection should be opened and when it should be closed. There are three options:

    • PERSESSION

      Open a database connection at the start of the session and close the database connection at the end of the session.

    • number (TIMED)

      Timed database connections that close themselves after number seconds of inactivity.

    If a connection policy is not specified, if the policy is not a number or is a number less than 1, or if the policy is the string "PERSESSION", the PERSESSION policy will be used.

    If the connection policy is any number greater than 0, it specifies the number of seconds that a connection will be held open without activity. After that many seconds of database inactivity, the connection to the database will be closed. As soon as database activity starts again, the connection will be opened and the timer will restart.

    The MySQL and Postgres backends' connection-info is expected to be of the form:

    database[@hostname][:port]

    hostname will default to a backend-specific hostname (which happens to be 'localhost' for both the MySQL and Postgres backends), and port will default to a backend-specific default port (3306 for the MySQL backend, 5432 for the Postgres backend).

    From the MySQL documentation:

    the value of host may be either a hostname or an IP address. If host is NULL or the string "localhost", a connection to the local host is assumed. If the OS supports sockets (Unix) or named pipes (Windows), they are used instead of TCP/IP to connect to the server.

    From the PostgreSQL documentation:

    If [the hostname] begins with a slash, it specifies Unix-domain communication rather than TCP/IP communication; the value is the name of the directory in which the socket file is stored. The default is to connect to a Unix-domain socket in /tmp.

    If you plan to use the TIMED connection policy, consider the effect of directives such as DefaultRoot on local socket communication: once a user has been chroot()ed, the local socket file will probably not be available within the chroot directory tree, and attempts to reopen communication will fail. One way around this may be to use hardlinks within the user's directory tree. PERSESSION connections are not affected by this because the database will be opened prior to the chroot() call, and held open for the life of the session. Network communications are not affected by this problem. For example, while localhost would not work for MySQL since the MySQL client library will try to use socket communications for that host, 127.0.0.1 will work (as long as your database is setup to accept these connections).

    See also

    Examples

      # Connect to the database 'ftpusers' via the default port at host
      # 'foo.com'.  Use a NULL username and NULL password when connecting.
      # A connection policy of PERSESSION is used.
      SQLConnectInfo ftpusers@foo.com

      # Connect to the database 'ftpusers' via port 3000 at host 'localhost'.
      # Use the username 'admin' and a NULL password when connecting.
      # A connection policy of PERSESSION is used.
      SQLConnectInfo ftpusers:3000 admin

      # Connect to the database 'ftpusers' via port 3000 at host 'foo.com'.
      # Use the username 'admin' and password 'mypassword' when connecting.
      # A connection policy of PERSESSION is used.
      SQLConnectInfo ftpusers@foo.com:3000 admin mypassword

      # Connect to the database 'ftpusers' via port 3000 at host 'foo.com'.
      # Use a username of 'admin' and a password of 'mypassword' when
      # connecting.  A 30 second timer of connection inactivity is activated.
      SQLConnectInfo ftpusers@foo.com:3000 admin mypassword 30

    Backends may require different information in the connection-info field; check your backend module for more detailed information.

    SQLDefaultGID

    Name

    SQLDefaultGID -- Configure the default GID for users

    Synopsis

    SQLDefaultGID [ defaultgid]

    Default

    65533

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_sql

    Compatibility

    1.2.0 and later

    Description

    Sets the default GID for users. Must be greater than SQLMinID.

    SQLDefaultHomedir

    Name

    SQLDefaultHomedir -- Configure the default homedir

    Synopsis

    SQLDefaultHomedir [ path]

    Default

    None

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_sql

    Compatibility

    1.2.5rc1 and later

    Description

    The SQLDefaultHomedir directive configures a default home directory for all users authenticated with this module, overriding any (deprecated) SQLHomedirField directive. If no home directory is set with either directive, authentication fails. This directive does not change the data retrieved from the database: if you specify a home directory field to SQLUserInfo, that field's data will be returned as the user's home directory, whether that data is a legal directory, or an empty string, or NULL.

    See also

    SQLUserInfo

    Examples

    SQLDefaultUID

    Name

    SQLDefaultUID -- Configure the default UID for users

    Synopsis

    SQLDefaultUID [ defaultuid]

    Default

    65533

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_sql

    Compatibility

    1.2.0 and later

    Description

    Sets the default UID for users. Must be greater than SQLMinID.

    SQLEngine

    Name

    SQLEngine -- Configure how mod_sql will operate

    Synopsis

    SQLEngine [ on|off|auth|log]

    Default

    SQLEngine on

    Context

    server config, <Global>, <VirtualHost>, <Anonymous>

    Module

    mod_sql

    Compatibility

    1.3.0rc1 and later

    Description

    The SQLEngine directive is used to specify how mod_sql will operate. By default, SQLEngine is on, and mod_sql will operate as normal. Setting SQLEngine to off will effectively disable the module.

    In addition to on and off, SQLEngine accepts two other values: auth and log. If you wish to use mod_sql for authentication and not for logging (via SQLLog), use auth. Conversely, to do only SQLLog-type logging, and no authentication, use log.

    This directive can be used to have <Anonymous> sections that do not use mod_sql (see the example below).

    See also

    Examples

      <Anonymous ~ftp>
        ...
        SQLEngine off
        ...
      </Anonymous>

    SQLGroupInfo

    Name

    SQLGroupInfo -- Configure the group table and fields that hold group information

    Synopsis

    SQLGroupInfo [ group-table group-name gid members]

    Default

    "groups groupname gid members"

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_sql

    Compatibility

    1.2.5rc1 and later

    Description

    The SQLGroupInfo directive configures the group table and fields that hold group information. The parameters for this directive are described below:

    • grouptable

      Specifies the name of the table that holds group information.

    • groupname

      Specifies the field in the group table that holds the group name.

    • gid

      Specifies the field in the group table that holds the group's GID.

    • members

      Specifies the field in the group table that holds the group members.

    If you need to change any of these field names from the default, you need to specify all of them.

    See also

    Examples

    SQLGroupWhereClause

    Name

    SQLGroupWhereClause -- Configure a WHERE clause for every group query

    Synopsis

    SQLGroupWhereClause [ where-clause]

    Default

    off

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_sql

    Compatibility

    1.2.5rc1 and later

    Description

    The directive is used to configure a WHERE clause that is added to every group query. The WHERE clause must contain all relevant punctuation, and must not contain a leading "and".

    Starting with ProFTPD 1.3.1rc1 the SQLGroupWhereClause also supports the variables supported by SQLNamedQuery except for the "%{n}" variable

    Examples

    As an example of a possible use for this directive, imagine if your group table included a "LoginAllowed" field:

      SQLGroupWhereClause "LoginAllowed = 'true'"

    would be appended to every group-related query as the string:

      " WHERE (LoginAllowed = 'true')"

    SQLLog

    Name

    SQLLog -- Log information to a database table

    Synopsis

    SQLLog [ cmd-set query-name ["IGNORE_ERRORS"]

    Default

    None

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_sql

    Compatibility

    1.2.5rc1 and later

    Description

    This directive is used to log information to a database table. Multiple SQLLog directives can be in effect for any command; for example, a user changing directories can trigger multiple logging statements.

    The first parameter to SQLLog, the cmd-set, is a comma-separated (no spaces) list of FTP commands for which this log command will trigger. The list of commands is too long to list in entirety; commands include CWD, DELE, HELP, LIST, MKD, MODE, NLST, PASS, PASV, PORT and many more. For the complete list check the FTP RFCs. Normally mod_sql will log events after they have completed successfully; in the case of the QUIT command, mod_sql logs prior to the server's processing of the command. (Note, however, that the client may not issue a QUIT before logging out; in this case, use a command of EXIT rather than QUIT. EXIT is not a real FTP command, but it is used here to provide a means for having SQLLog work whenever a session ends.)

    FTP commands in the command set will only be logged if they complete successfully. Prefixing any command with "ERR_" will cause logging to occur only if there was an error in the command's processing. To log both errors and successful completion of a given command X, therefore, you'll need both "X" and "ERR_X" in your cmd-set.

    The special command "*" matches all FTP commands, while "ERR_*" matches all errors.

    The second parameter is the name of a query defined by a SQLNamedQuery directive. The query must be an UPDATE, INSERT, or FREEFORM type query; explicit SELECT queries will not be processed.

    The third parameter is optional. If you add "IGNORE_ERRORS" as the third parameter, SQLLog will not check for errors in the processing of the named query. Any value for this parameter other than the string "IGNORE_ERRORS" (case-insensitive) will not cause errors to be ignored.

    Normally, SQLLog directives are considered important enough that errors in their processing will cause mod_sql to abort the client session. References to non-existent named queries will not abort the client session, but may result in database corruption (in the sense that the expected database UPDATE or INSERT will not occur). Check your directives carefully.

    See also

    Examples

      SQLLog PASS updatecount
      SQLNamedQuery updatecount UPDATE "count=count+1 WHERE userid='%u'" users

    together, these replicate the deprecated "SQLLoginCountField count" directive; if the current user was "joe", this would translate into the query "UPDATE users SET count=count+1 WHERE userid='joe'". This query would run whenever a user was first authenticated.

      SQLLog CWD updatedir
      SQLNamedQuery updatedir UPDATE "cwd='%d' where userid='%u'" users

    together these replicate the logging side of the deprecated "SQLLogDirs cwd" directive; if the current user was "joe" and the current working directory were /tmp, this would translate into the query "UPDATE users SET cwd='/tmp' WHERE userid='joe'". This query would run whenever a user changed directories.

      SQLLog RETR,STOR insertfileinfo
      SQLNamedQuery insertfileinfo INSERT "'%f', %b, '%u@%v', now()" filehistory

    would log the name of any file stored or retrieved, the number of bytes transferred, the user and host doing the transfer, and the time of transfer (at least in MySQL). This would translate into a query like: "INSERT INTO filehistory VALUES ('somefile', 12345, 'joe@joe.org', '21-05-2001 20:01:00')"

    SQLLogFile

    Name

    SQLLogFile -- Specify a log file for mod_sql reporting and debugging

    Synopsis

    SQLLogFile [ file]

    Default

    None

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_sql

    Compatibility

    1.2.8rc2 and later

    Description

    The SQLLogFile directive is used to a specify a log file for mod_sql reporting and debugging, and can be done a per-server basis. The file parameter must be the full path to the file to use for logging. Note that this path must not be to a world-writeable directory and, unless AllowLogSymlinks is explicitly set to on (generally a bad idea), the path must not be a symbolic link.

    If file is "none", no logging will be done at all; this setting can be used to override a SQLLogFile setting inherited from a ;ltgt& context.

    See also

    Examples

    SQLMinID

    Name

    SQLMinID -- Set SQLMinUserGID and SQLMinUserID in one place

    Synopsis

    SQLMinID [ minimum-id]

    Default

    999

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_sql

    Compatibility

    1.2.0 and later

    Description

    SQLMinID is a quick way of setting both SQLMinUserGID and SQLMinUserUID. These values are checked whenever retrieving a user's GID or UID.

    SQLMinUserGID

    Name

    SQLMinUserGID -- Set a minimum GID

    Synopsis

    SQLMinUserGID [ minimum-gid]

    Default

    999

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_sql

    Compatibility

    1.2.5rc1 and later

    Description

    SQLMinUserGID is checked whenever retrieving a user's GID. If the retrieved value for GID is less than the value of SQLMinUserGID, it is reported as the value of SQLDefaultGID.

    See also

    Examples

    SQLMinUserUID

    Name

    SQLMinUserUID -- Set a minimum UID

    Synopsis

    SQLMinUserUID [ minimum-uid]

    Default

    999

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_sql

    Compatibility

    1.2.5rc1 and later

    Description

    SQLMinUserUID is checked whenever retrieving a user's UID. If the retrieved value for UID is less than the value of SQLMinUserUID, it is reported as the value of SQLDefaultUID.

    See also

    Examples

    SQLNamedQuery

    Name

    SQLNamedQuery -- Specify a query and an identifier for SQLShowInfo and SQLLog

    Synopsis

    SQLNamedQuery [ "name" limit|regex|ip value]

    Default

    (docs incomplete)

    Context

    server config, <Global>, <VirtualHost>, <Anonymous>, <Limit>, .ftpaccess

    Module

    mod_sql

    Compatibility

    1.2.5rc1 and later

    Description

    SQLNamedQuery specifies a query and an identifier (name) for later use by SQLShowInfo and SQLLog.

    It is strongly recommended that you read documentation on the LogFormat and ExtendedLog directives, as the meta-sequences available to SQLNamedQuery are largely equivalent.

    The first parameter, name, should be unique across all named queries and must not contain spaces. The result of re-using a name is undefined.

    The second parameter, type, is the type of query, either "SELECT", "UPDATE", "INSERT", or "FREEFORM". See the note below for information on FREEFORM type queries.

    The third parameter is the substance of the database query itself; this should match the form of the second parameter. The meta-sequences accepted are exactly equivalent to the LogFormat directive except the following are not accepted:

    • %{FOOBAR}e

      For LogFormat, this logs the content of environment variable "FOOBAR". This is not bavailable in mod_sql.

    • %{format}t and %t

      These two meta-sequences logged the local server time; they are not available in mod_sql. Your database undoubtedly provides another way to get the time; for example, MySQL provides the now() function.

    and the following is in addition to the LogFormat meta-sequences:

    • %d

      The current working directory or "-" if none.

    • %{n}

      This meta-sequence is used internally by mod_sql and other third-party modules and patches to pass information to the database. Using this meta-sequence in anything other than an INSERT or UPDATE query is an error, and using this meta-sequence unless directed to by a third-party module or patch is also an error.

    • %{env:VAR}

      Starting with ProFTPD 1.3.1rc1 the SQLNamedQuery directive is able to make use of environment variables in the format "%{env:VAR}". The value of the environment variable VAR will be substituted into the SQL statement.

    The correct form of a query will be built from the directive arguments, except in the case of FREEFORM queries which will be sent directly to the database. The examples below show the way queries are built from the arguments.

    The fourth parameter, table, is only necessary for UPDATE or INSERT type queries, but is required for those types.

    Note: FREEFORM queries are a necessary evil; the simplistic query semantics of the UPDATE, INSERT, and SELECT type queries do not sufficiently expose the capabilities of most backend databases. At the same time, using a FREEFORM query makes it impossible for mod_sql to check whether the query type is appropriate, making sure that a SELECT query is not used in a SQLLog directive, for instance. Wherever possible, it is recommended that a specific query type be used.

    Examples

    SQLNamedQuery count SELECT "count from users where userid='%u'"

    creates a query named "count" which could be used by SQLShowInfo to inform a user of their login count. The actual query would look something like "SELECT count FROM users WHERE userid='matilda'" for user "matilda".

    SQLNamedQuery updatecount UPDATE "count=count+1 WHERE userid='%u'" users

    creates a query named "updatecount" which could be used by SQLLog to update a user login counter in the table users. The actual query would look something like "UPDATE users SET count=count+1 WHERE userid='persephone'" for user "persephone".

    SQLNamedQuery accesslog INSERT "now(), '%u'" accesslog

    creates a query named "accesslog" which could be used by SQLLog to track access times by clients. The actual query would look something like "INSERT INTO accesslog VALUES (now(), 'pandora')" for user "pandora". Note that this may be too simplistic for your table structure, since most databases require data for all columns to be provided in an INSERT statement of this form. See the following FREEFORM query for an example of something which may suit your needs better.

    SQLNamedQuery accesslog FREEFORM "INSERT INTO accesslog(date, user) VALUES (now(), '%u')"

    creates a query named "accesslog" which could be used by SQLLog to track access times by clients. The actual query would look something like "INSERT INTO accesslog(date, user) VALUES (now(), 'tilda')" for user "tilda".

    SQLNegativeCache

    Name

    SQLNegativeCache -- Enable negative caching for SQL lookups

    Synopsis

    SQLNegativeCache [ on off ]

    Default

    SQLNegativeCache off

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_sql

    Compatibility

    mod_sql v4.10 and later

    Description

    SQLNegativeCache specifies whether or not to cache negative responses from SQL lookups when using SQL for UID/GID lookups. Depending on your SQL tables, there can be a significant delay when a directory listing is performed as the UIDs not in the SQL database are repeatedly looked up in an attempt to present usernames instead of UIDs in directory listings. With SQLNegativeCache set to on, negative ("not found") responses from SQL queries will be cached and speed will improve on directory listings that contain many users not present in the SQL database.

    See also

    Examples

    SQLRatios

    Name

    SQLRatios -- (docs incomplete)

    Synopsis

    SQLRatios [ "name" limit|regex|ip value]

    Default

    None

    Context

    server config, <Global>

    Module

    mod_sql

    Compatibility

    1.2.5rc1 and later

    Description

    mod_ratio is currently lacking a module maintainer. This directive is left over and not officially supported.

    See also

    Examples

    (docs incomplete)

    SQLRatioStats

    Name

    SQLRatioStats -- (docs incomplete)

    Synopsis

    SQLRatioStats [ "name" limit|regex|ip value]

    Default

    None

    Context

    server config, <Global>

    Module

    mod_sql

    Compatibility

    1.2.5rc1 and later

    Description

    mod_ratio is currently lacking a module maintainer. This directive is left over and not officially supported.

    See also

    Examples

    (docs incomplete)

    SQLShowInfo

    Name

    SQLShowInfo -- Create a message to be sent to the user after any successful command

    Synopsis

    SQLShowInfo [ cmd-set numeric query-string]

    Default

    None

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_sql

    Compatibility

    1.2.5rc1 and later

    Description

    This directive creates a message to be sent to the user after any successful command.

    The first parameter, the cmd-set, is a comma separated (no spaces) list of FTP commands for which this log command will trigger. The list of commands is too long to list in entirety; commands include: CWD, DELE, HELP, LIST, MKD, MODE, NLST, PASS, PASV, PORT and many more. For the complete list check the FTP RFCs.

    FTP commands in the command set will only be triggered if they complete successfully. Prefixing any command with "ERR_" will show information only if there was an error in command processing. To send a message on both errors and successfull completion of a given command X, therefore, you'll need both "X" and "ERR_X" in your cmd-set.

    The special command "*" matches all FTP commands, while "ERR_*" matches all errors.

    The second parameter, numeric, specifies the numeric value of the message returned to the FTP client. Do not choose a number blindly: message numbers may be parsed by clients. In most cases you will want to use 214, the "Help message" numeric. It specifies that the information is only meant to be human readable.

    The third parameter, query-string, is exactly equivalent to the query-string parameter to the SQLLog directive, with one addition:

    • %{name}

      The first return value from the SQLNamedQuery identified by "name". There is currently no way to retrieve more than one value from the database at a time.

    Any references to non-existent named queries, non-SELECT or -FREEFORM type queries, or references to queries which return a NULL first value, will be replaced with the string "{null}".

    See also

    Examples

      SQLNamedQuery count SELECT "count from users where userid='%u'"
      SQLShowInfo PASS "230" "You've logged on %{count} times, %u"

    As long as the information is in the database, these two directives specify that the user will be greeted with their login count each time they successfully login. Note the use of the "230" numeric, which means "User logged in, proceed". "230" is appropriate in this case because the message will be sent immediately after their password has been accepted and the session has started.

    SQLUserInfo

    Name

    SQLUserInfo -- Configure the user table and fields that hold user information

    Synopsis

    SQLUserInfo [ user-table user-name passwd uid gid home-dir shell]

    Default

    "users userid passwd uid gid homedir shell"

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_sql

    Compatibility

    1.2.5rc1 and later

    Description

    The SQLUserInfo directive configures the user table and fields that hold user information. If you need to change any of these field names from the default, you must specify all of them, whether NULL or not. The parameters are described below:

    • usertable

      Specifies the name of the table that holds user information.

    • username

      Specifies the field in the user table that holds the username.

    • passwd

      Specifies the field in the user table that holds the user's password.

    • uid

      Specifies the field in the user table that holds the user's UID. When a UID is retrieved from the database it is checked against the value of SQLMinUserUID. If the field name is specified as "NULL" the database will not be queried for this value and the user's UID will be set to the value of SQLDefaultUID.

    • gid

      Specifies the field in the user table that holds the user's GID. When a GID is retrieved from the database it is checked against the value of SQLMinUserGID. If the field name is specified as "NULL" the database will not be queried for this value and the user's GID will be set to the value of SQLDefaultGID.

    • homedir

      Specifies the field in the user table that holds the user's home directory. If the fieldname is specified as "NULL" the database will not be queried for this value and the user's home directory will be set to the value of SQLDefaultHomedir. If no home directory is set with either directive, user authentication will be automatically turned off.

    • shell

      Specifies the field in the user table that holds the user's shell. If the fieldname is specified as "NULL" the database will not be queried and the shell will be reported as an empty string ("").

    As of 1.2.9rc1, the SQLUserInfo directive accepts an alternate syntax:

      SQLUserInfo custom:/name

    where name refers to a configured SELECT SQLNamedQuery. This named query must return one row, and return the following columns, in this order: username, passwd, uid, gid, homedir, shell. The configured query may make use of the variables mentioned in the SQLLog description. This syntax allows the administrator a flexible way of constructing queries as needed. Note that if you want use the given USER name, you should use the %U variable, not %u; the latter requires the locally authenticated user name, which is exactly what SQLUserInfo is meant to provide.

    Examples

    SQLUserWhereClause

    Name

    SQLUserWhereClause -- Configure a WHERE clause for every user query<

    Synopsis

    SQLUserWhereClause [ where-clause]

    Default

    None

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_sql

    Compatibility

    1.2.5rc1 and later

    Description

    The directive is used to configure a WHERE clause that is added to every user query. The WHERE clause must contain all relevant punctuation, and must not contain a leading "and".

    Starting with ProFTPD 1.3.1rc1 the SQLUserWhereClause also supports the variables supported by SQLNamedQuery except for the "%{n}" variable

    Examples

    As an example of a possible use for this directive, imagine if your user table included a "LoginAllowed" field:

      SQLUserWhereClause "LoginAllowed = 'true'"

    would be appended to every user-related query as the string:

      " WHERE (LoginAllowed = 'true')"

    StoreUniquePrefix

    Name

    StoreUniquePrefix -- Set the prefix to be added to uniquely generated filenames

    Synopsis

    StoreUniquePrefix [ "prefix"]

    Default

    none

    Context

    server config, <Global>, <VirtualHost>, <Global>, <Anonymous>, <Directory> .ftpaccess

    Module

    mod_xfer

    Compatibility

    1.2.6rc1 and later

    Description

    The StoreUniquePrefix is used to configure a prefix for the generated unique random filenames used for the STOU FTP command. The last six characters of the filename will be random. Slashes are not allowed in the prefix string.

    All valid filename characters are allowed except '/'

    See also

    Examples

    StoreUniquePrefix "Wibble"

    SyslogFacility

    Name

    SyslogFacility -- Set the facility level used for logging

    Synopsis

    SyslogFacility [ SyslogFacility facility-level]

    Default

    None

    Context

    server config

    Module

    mod_core

    Compatibility

    1.1.6 and later

    Description

    Proftpd logs its activity via the Unix syslog mechanism, which allows for several different general classifications of logging messages, known as "facilities." Normally, all authentication related messages are logged with the AUTHPRIV (or AUTH) facility [intended to be secure, and never seen by unwanted eyes], while normal operational messages are logged with the DAEMON facility. The SyslogFacility directive allows ALL logging messages to be directed to a different facility than the default. When this directive is used, ALL logging is done with the specified facility, both authentication (secure) and otherwise. The facility-level argument must be one of the following: AUTH (or AUTHPRIV), CRON, DAEMON, KERN, LPR, MAIL, NEWS, USER, UUCP, LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6 or LOCAL7. See Also: SystemLog

    See also

    Examples

    SyslogLevel

    Name

    SyslogLevel -- Set the verbosity level of system logging

    Synopsis

    SyslogLevel [ SyslogLevel emerg|alert|crit|error|warn|notice|info|debug]

    Default

    None

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_core

    Compatibility

    1.2.0rc2+cvs and later

    Description

    SyslogLevel adjusts the verbosity of the messages recorded in the error logs. The following levels are available, in order of decreasing significance: Level Description emerg Emergencies - system is unusable. alert Action must be taken immediately. crit Critical Conditions. error Error conditions. warn Warning conditions. notice Normal but significant condition. info Informational. debug Debug-level messages When a particular level is specified, messages from all other levels of higher significance will be reported as well. E.g., when SyslogLevel info is specified, then messages with log levels of notice and warn will also be posted. Using a level of at least crit is recommended.

    See also

    Examples

    SystemLog

    Name

    SystemLog -- Redirect syslogging to a file

    Synopsis

    SystemLog [ SystemLog filename|NONE]

    Default

    None

    Context

    server config

    Module

    mod_log

    Compatibility

    1.1.6pl1 and later

    Description

    The SystemLog directive disables proftpd's use of the syslog mechanism and instead redirects all logging output to the specified filename. The filename argument should contain an absolute path, and should not be to a file in a nonexistent directory, in a world-writeable directory, or be a symbolic link (unless AllowLogSymlinks is set to on). Use of this directive overrides any facility set by the SyslogFacility directive. Additionally, the special keyword NONE can be used which disables all syslog style logging for the entire configuration.

    Examples

    TCPAccessFiles

    Name

    TCPAccessFiles -- Sets the access files to use

    Synopsis

    TCPAccessFiles [ allow-filename deny-filename]

    Default

    none

    Context

    server config, <VirtualHost>, <Global>, <Anonymous>

    Module

    mod_wrap

    Compatibility

    1.2.1 and later

    Description

    TCPAccessFiles specifies two files, an allow and a deny file, each of which contain the IP addresses, networks or name-based masks to be allowed or denied connections to the server. The files have the same format as the standard tcpwrappers hosts.allow/deny files.

    Both file names are required. Also, the paths to both files must be the full path, with two exceptions: if the path starts with ~/, the check of that path will be delayed until a user requests a connection, at which time the path will be resolved to that user's home directory; or if the path starts with ~user/, where user is some system user. In this latter case, mod_wrap will attempt to resolve and verify the given user's home directory on start-up.

    The service name for which mod_wrap will look in the indicated access files is proftpd by default; this can be configured via the TCPServiceName directive. There is a built-in precedence to the TCPAccessFiles, TCPGroupAccessFiles, and TCPUserAccessFiles directives, if all are used. mod_wrap will look for applicable TCPUserAccessFiles for the connecting user first. If no applicable TCPUserAccessFiles is found, mod_wrap will search for TCPGroupAccessFiles which pertain to the connecting user. If not found, mod_wrap will then look for the server-wide TCPAccessFiles directive. This allows for access control to be set on a per-server basis, and allow for per-user or per-group access control to be handled without interfering with the server access rules.

    Examples

    # server-wide access files TCPAccessFiles /etc/ftpd.allow /etc/ftpd.deny # per-user access files, which are to be found in the user's home directory TCPAccessFiles ~/my.allow ~/my.deny

    TCPAccessSyslogLevels

    Name

    TCPAccessSyslogLevels -- Sets the logging levels for mod_wrap

    Synopsis

    TCPAccessSyslogLevels [ allow-level deny-level]

    Default

    TCPAccessSyslogLevels info warn

    Context

    server config, <VirtualHost>, <Global>, <Anonymous>

    Module

    mod_wrap

    Compatibility

    1.2.1 and later

    Description

    ProFTPD can log when a connection is allowed, or denied, as the result of rules in the files specified in TCPAccessFiles, to the Unix syslog mechanism. A discussion on the syslog levels which can be used is given in the SyslogLevel directive.

    The allow-level parameter sets the syslog level at which allowed connections are logged; the deny-level parameter sets the syslog level for denied connections.

    See also

    SyslogLevel

    Examples

    TCPAccessSyslogLevels debug warn

    tcpBackLog

    Name

    tcpBackLog -- Control the tcp backlog in standalone mode

    Synopsis

    tcpBackLog [ tcpBackLog backlog-size]

    Default

    tcpBackLog 5

    Context

    server config

    Module

    mod_core

    Compatibility

    0.99.0 and later

    Description

    The tcpBackLog directive controls the tcp "backlog queue" when listening for connections in standalone mode (see ServerType). It has no affect upon servers in inetd mode. When a tcp connection is established by the tcp/ip stack inside the kernel, there is a short period of time between the actual establishment of the connection and the acceptance of the connection by a user-space program. The duration of this latency period is widely variable, and can depend upon several factors (hardware, system load, etc). During this period tcp connections cannot be accepted, as the port that was previously "listening" has become filled with the new connection. Under heavy connection load this can result in occasional (or even frequent!) "connection refused" messages returned to the incoming client, even when there is a service available to handle requests. To eliminate this problem, most modern tcp/ip stacks implement a "backlog queue" which is simply a pre-allocation of resources necessary to handle backlog-size connections during the latency period. The larger the backlog queue, the more connections can be established in a very short time period. The trade-off, of course, is kernel memory and/or other kernel resources. Generally it is not necessary to use a tcpBackLog directive, unless you intend to service a large number of virtual hosts (see <VirtualHost>), or have a consistently heavy system load. If you begin to notice or hear of "connection refused" messages from remote clients, try setting a slightly higher value to this directive.

    See also

    Examples

    TCPGroupAccessFiles

    Name

    TCPGroupAccessFiles -- Sets the access files to use

    Synopsis

    TCPGroupAccessFiles [ group-expression allow-filename deny-filename]

    Default

    none

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_wrap

    Compatibility

    1.2.1 and later

    Description

    TCPGroupAccessFiles allows for access control files, the same types of files required by TCPAccessFiles, to be applied to select groups. The given group-expression is a logical AND expression, which means that the connecting user must be a member of all the groups listed for this directive to apply. Group names may be negated with a ! prefix.

    The rules for the filename paths are the same as for TCPAccessFiles settings.

    Examples

    # every member of group wheel must connect from restricted locations TCPGroupAccessFiles wheel /etc/ftpd-strict.allow /etc/ftpd-strict.deny # everyone else gets the standard access rules TCPGroupAccessFiles !wheel /etc/hosts.allow /etc/hosts.deny

    tcpNoDelay

    Name

    tcpNoDelay -- Control the use of TCP_NODELAY

    Synopsis

    tcpNoDelay [ tcpNoDelay on|off]

    Default

    tcpNoDelay on

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_core

    Compatibility

    1.2.0pre3a and later

    Description

    The tcpNoDelay directive controls the use of the TCP_NODELAY socket option (which disables the Nagle algorithm). ProFTPd uses TCP_NODELAY by default, which usually is a benefit but this can occasionally lead to problems with some clients, so tcpNoDelay is provided as a way to disable this option. You will not normally need to use this directive but if you have clients reporting unusually slow connections, try setting this to off.

    See also

    Examples

    TCPServiceName

    Name

    TCPServiceName -- Configures the name proftpd will use with mod_wrap

    Synopsis

    TCPServiceName [ name]

    Default

    TCPServiceName proftpd

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_wrap

    Compatibility

    1.2.1 and later

    Description

    TCPServiceName is used to configure the name of the service under which mod_wrap will check the allow/deny files. By default, this is the name of the program started, i.e. "proftpd". However, some administrators may want to use a different, more generic service name, such as "ftpd"; use this directive for such needs.

    See also

    TCPUserAccessFiles

    Name

    TCPUserAccessFiles -- Sets the access files to use

    Synopsis

    TCPUserAccessFiles [ user-expression allow-filename deny-filename]

    Default

    none

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_wrap

    Compatibility

    1.2.1 and later

    Description

    TCPUserAccessFiles allows for access control files, the same types of files required by TCPAccessFiles, to be applied to select users. The given user-expression is a logical AND expression. Listing multiple users in a user-expression does not make much sense; however, this type of AND evaluation allows for expressions such as "everyone except this user" with the use of the ! negation prefix.

    The rules for the filename paths are the same as for TCPAccessFiles settings.

    Examples

    # user admin might be allowed to connect from anywhere TCPUserAccessFiles admin /etc/ftpd-anywhere.allow /etc/ftpd-anywhere.deny # while every other user has to connect from LAN addresses TCPUserAccessFiles !admin /etc/ftpd-lan.allow /etc/ftpd-lan.deny

    TimeoutIdle

    Name

    TimeoutIdle -- Sets the idle connection timeout

    Synopsis

    TimeoutIdle [ TimeoutIdle seconds]

    Default

    TimeoutIdle 600

    Context

    server config, <VirtualHost>, <Global>, <Anonymous>

    Module

    mod_core

    Compatibility

    0.99.0 and later

    Description

    The TimeoutIdle directive configures the maximum number of seconds that proftpd will allow clients to stay connected without receiving any data on either the control or data connection. If data is received on either connection, the idle timer is reset. Setting TimeoutIdle to 0 disables the idle timer completely (clients can stay connected for ever, without sending data). This is generally a bad idea as a "hung" tcp connection which is never properly disconnected (the remote network may have become disconnected from the Internet, etc) will cause a child server to never exit (at least not for a considerable period of time) until manually killed See Also: TimeoutLogin, TimeoutNoTransfer

    See also

    Examples

    TimeoutLinger

    Name

    TimeoutLinger -- Sets the timeout used for lingering closes

    Synopsis

    TimeoutLinger [ TimeoutLinger seconds]

    Default

    TimeoutLinger 30

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_core

    Compatibility

    1.2.10rc2 and later

    Description

    The TimeoutLinger directive configures the maximum number of seconds that proftpd will wait (or "linger") when closing a data connection. Once the data connection is closed, proftpd will send a message on the control connection indicating the closure. This delay is necessary for properly handling some FTP clients.

    If the client aborts a transfer and there is a long delay, this lingering close is the most likely culprit. So if you encounter this delay, set TimeoutLinger to a low number to remove the delay.

    See also

    Examples

    TimeoutLogin

    Name

    TimeoutLogin -- Sets the login timeout

    Synopsis

    TimeoutLogin [ TimeoutLogin seconds]

    Default

    TimeoutLogin 300

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_auth

    Compatibility

    0.99.0 and later

    Description

    The TimeoutLogin directive configures the maximum number of seconds a client is allowed to spend authenticating. The login timer is not reset when a client transmits data, and is only removed once a client has transmitted an acceptable USER/PASS command combination. See Also: TimeoutIdle, TimeoutNoTransfer

    See also

    Examples

    TimeoutNoTransfer

    Name

    TimeoutNoTransfer -- Sets the connection without transfer timeout

    Synopsis

    TimeoutNoTransfer [ TimeoutNoTransfer seconds]

    Default

    TimeoutNoTransfer 300

    Context

    server config, <VirtualHost>, <Global>, <Anonymous>

    Module

    mod_xfer

    Compatibility

    0.99.0 and later

    Description

    The TimeoutNoTransfer directive configures the maximum number of seconds a client is allowed to spend connected, after authentication, without issuing a command which results in creating an active or passive data connection (i.e. sending/receiving a file, or receiving a directory listing). See Also: TimeoutIdle, TimeoutLogin

    See also

    Examples

    TimeoutSession

    Name

    TimeoutSession -- Sets a timeout for an entire session

    Synopsis

    TimeoutSession [ seconds ["user"|"group"|"class" expression]]

    Default

    None

    Context

    server config, <VirtualHost>, <Global>, <Anonymous>

    Module

    mod_auth

    Compatibility

    1.2.6rc1 and later

    Description

    The TimeoutSession directive sets the maximum number of seconds a control connection between the proftpd server and an FTP client can exist after the client has successfully authenticated. If the seconds argument is set to 0, sessions are allowed to last indefinitely (the default).

    The optional parameters are used to restrict the session time limit only to specific users. If "user" restriction is given, then expression is a user-expression specifying to which users the time limit applies. Similarly for the "group" restriction. For the "class" restriction, the expression is simply the name of connection class for whom the time limit will apply. Note that use of the "user" or "group" classifiers within an <Anonymous> context will not make much sense.

    Example: # set a draconian session time limit TimeoutSession 60 # set session time limits for everyone except a few privileged users TimeoutSession 300 user !bob,!dave,!jenni

    See also

    Examples

    # Kick the user off after 60 minutes
    TimeoutSession 3600

    TimeoutStalled

    Name

    TimeoutStalled -- Sets the timeout on stalled data transfers

    Synopsis

    TimeoutStalled [ TimeoutStalled seconds]

    Default

    TimeoutStalled 3600

    Context

    server config, <VirtualHost>, <Global>, <Anonymous>

    Module

    mod_xfer

    Compatibility

    1.1.6 and later

    Description

    The TimeoutStalled directive sets the maximum number of seconds a data connection between the proftpd server and an FTP client can exist but have no actual data transferred (i.e. "stalled"). If the seconds argument is set to 0, data transfers are allowed to stall indefinitely.

    See also

    Examples

    TimesGMT

    Name

    TimesGMT -- Toggle time display between GMT and local

    Synopsis

    TimesGMT [ TimesGMT on|off]

    Default

    (versions 1.2.0pre9 and beyond) on

    Context

    server config, <VirtualHost>, <Anonymous>, <Global>

    Module

    mod_core

    Compatibility

    Description

    Compatibility: 1.2.0pre9 and later The TimesGMT option causes the server to report all ls and MDTM times in GMT and not local time.

    See also

    Examples

    TLSCACertificateFile

    Name

    TLSCACertificateFile -- Define a CA certificate used to verify your client certificates

    Synopsis

    TLSCACertificateFile [ CA certificate filename]

    Default

    None

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_tls

    Compatibility

    1.2.7rc1 and later

    Description

    The TLSCACertificateFile directive configures one file where you can assemble the certificates of Certification Authorities (CA) for your clients. The CA certificates in the file are then used to verify client certificates, if presented. Such a file is merely the concatenation of the various PEM-encoded CA certificates, in order of preference. This directive can be used in addition to, or as an alternative for, TLSCACertificatePath.

    If neither TLSCACertificateFile nor TLSCACertificatePath are specified, the following message will appear in the TLSLog:

    using default OpenSSL verification locations (see $SSL_CERT_DIR)

    This means that the SSL_CERT_DIR environment variable, if set, will be used to determine the location of a CA certificate directory, to be used when verifying clients.

    Examples

    TLSCACertificateFile /etc/ftpd/ca-bundle.pem

    TLSCACertificatePath

    Name

    TLSCACertificatePath -- Define a path to the CAs used to verify your client certificates

    Synopsis

    TLSCACertificatePath [ Path to your CA certificates]

    Default

    None

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_tls

    Compatibility

    1.2.7rc1 and later

    Description

    The TLSCACertificatePath directive sets the directory for the certificates of Certification Authorities (CAs) for your clients. These are used to verify the client certificates presented. This directive may be used in addition to, or as alternative for, TLSCACertificateFile.

    The files in the configured directory have to be PEM-encoded, and are accessed through hash filenames. This means one cannot simply place the CA certificates there: one also has to create symbolic links named hash-value.N. The c_rehash utility that comes with OpenSSL can be used to create the necessary symlinks.

    If neither TLSCACertificateFile nor TLSCACertificatePath are specified, the following message will appear in the TLSLog:

       using default OpenSSL verification locations (see $SSL_CERT_DIR)
    [1]

    This means that the SSL_CERT_DIR environment variable, if set, will be used to determine the location of a CA certificate directory, to be used when verifying clients.

    Examples

    TLSCACertificatePath /etc/ftpd/ca/

    TLSCARevocationFile

    Name

    TLSCARevocationFile -- Define a file with your CA revocation certifcates

    Synopsis

    TLSCARevocationFile [ CA revocation filename]

    Default

    Define a file holding your Certificate Revocation Lists

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_tls

    Compatibility

    1.2.7rc1 and later

    Description

    The TLSCARevocationFile directive configures one file that can contain the Certificate Revocation Lists (CRL) of Certification Authorities (CA) for your clients. These CRLs are used during the verification of client certificates, if presented. Such a file is merely the concatenation of the various PEM-encoded CRL files, in order of preference. This directive can be used in addition to, or as an alternative for, TLSCARevocationPath.

    Examples

    TLSCARevocationFile /etc/ftpd/ca-crl-bundle.pem

    TLSCARevocationPath

    Name

    TLSCARevocationPath -- Define a path to your CA revocation certificates

    Synopsis

    TLSCARevocationPath [ Path to a directory with CA revocation certificates]

    Default

    None

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_tls

    Compatibility

    1.2.7rc1 and later

    Description

    The TLSCARevocationPath directive sets the directory for the Certificate Revocation Lists (CRL) of Certification Authorities (CAs) for your clients. These are used during the verification of client certificates, if presented. This directive may be used in addition to, or as alternative for, TLSCARevocationFile.

    The files in the configured directory have to be PEM-encoded, and are accessed through hash filenames. This means one cannot simply place the CRLs there: one also has to create symbolic links named hash-value.N. The c_rehash utility that comes with OpenSSL can be used to create the necessary symlinks.

    Examples

    TLSCARevocationPath /etc/ftpd/crl/

    TLSCertificateChainFile

    Name

    TLSCertificateChainFile -- Define an all in one certification file

    Synopsis

    TLSCertificateChainFile [ TLSCertificateChainFile filename]

    Default

    None

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_tls

    Compatibility

    1.2.7rc1 and later

    Description

    The TLSCertificateChainFile directive sets the optional all-in-one file where you can assemble the certificates of Certification Authorities (CA) which form the certificate chain of the server certificate. This starts with the issuing CA certificate of the server certificate and can range up to the root CA certificate. Such a file is simply the concatenation of the various PEM-encoded CA Certificate files in certificate chain order. This server certificate chain is sent to the client, in addition to the server's certificate.

    If TLSCertificateChainFile is not used, and TLSCACertificatePath is used, the certificate chain is built from the certificates in that path. TLSCertificateChainFile should be used as an alternative to TLSCACertificatePath for explicitly constructing the server certificate chain. It is especially useful to avoid conflicts with CA certificates when using client authentication. For although placing a CA certificate of the server certificate chain into the TLSCACertificatePath has the same effect for the certificate chain construction, it has the side-effect that client certificates issued by this same CA certificate are also accepted on client authentication. This is usually not what one expects.

    Be careful: providing the certificate chain works only if you are using a single (either RSA or DSA) based server certificate. If you are using a coupled RSA+DSA certificate pair, this will work only if actually both certificates use the same certificate chain. Otherwise, clients will become confused.

    Examples

    TLSCertificateChainFile /etc/ftpd/client-ca-list.pem

    TLSCipherSuite

    Name

    TLSCipherSuite -- Define a cipher list

    Synopsis

    TLSCipherSuite [ cipher-list]

    Default

    ALL:!ADH

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_tls

    Compatibility

    1.2.7rc1 and later

    Description

    How to put together a cipher list parameter:

      Key Exchange Algorithms:
        "kRSA"      RSA key exchange
        "kDHr"      Diffie-Hellman key exchange (key from RSA cert)
        "kDHd"      Diffie-Hellman key exchange (key from DSA cert)
        "kEDH'      Ephemeral Diffie-Hellman key exchange (temporary key)

      Authentication Algorithm:
        "aNULL"     No authentication
        "aRSA"      RSA authentication
        "aDSS"      DSS authentication
        "aDH"       Diffie-Hellman authentication

      Cipher Encoding Algorithm:
        "eNULL"     No encodiing
        "DES"       DES encoding
        "3DES"      Triple DES encoding
        "RC4"       RC4 encoding
        "RC2"       RC2 encoding
        "IDEA"      IDEA encoding

      MAC Digest Algorithm:
        "MD5"       MD5 hash function
        "SHA1"      SHA1 hash function
        "SHA"       SHA hash function (should not be used)

      Aliases:
        "ALL"       all ciphers
        "SSLv2"     all SSL version 2.0 ciphers (should not be used)
        "SSLv3"     all SSL version 3.0 ciphers
        "EXP"       all export ciphers (40-bit)
        "EXPORT56"  all export ciphers (56-bit)
        "LOW"       all low strength ciphers (no export)
        "MEDIUM"    all ciphers with 128-bit encryption
        "HIGH"      all ciphers using greater than 128-bit encryption
        "RSA"       all ciphers using RSA key exchange
        "DH"        all ciphers using Diffie-Hellman key exchange
        "EDH"       all ciphers using Ephemeral Diffie-Hellman key exchange
        "ADH"       all ciphers using Anonymous Diffie-Hellman key exchange
        "DSS"       all ciphers using DSS authentication
        "NULL"      all ciphers using no encryption

    Each item in the list may include a prefix modifier:

        "+"         move cipher(s) to the current location in the list
        "-"         remove cipher(s) from the list (may be added again by a
                    subsequent list entry)
        "!"         kill cipher from the list (it may not be added again by a
                    subsequent list entry)

    If no modifier is specified the entry is added to the list at the current position. "+" may also be used to combine tags to specify entries such as "RSA+RC4" describes all ciphers that use both RSA and RC4. 

    The OpenSSL command

      openssl ciphers -v <list of ciphers>

    may be used to list all of the ciphers and the order described by a specific .

    See also

    Examples

    For example, all available ciphers not including ADH key exchange:

      ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP

    All algorithms including ADH and export but excluding patented algorithms:

      HIGH:MEDIUM:LOW:EXPORT56:EXP:ADH:!kRSA:!aRSA:!RC4:!RC2:!IDEA

    TLSDHParamFile

    Name

    TLSDHParamFile -- Define a file used in Diffie-Hellman key exchange

    Synopsis

    TLSDHParamFile [ Absolute path to the Diffie-Hellman param file]

    Default

    None

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_tls

    Compatibility

    1.2.7rc1 and later

    Description

    The TLSDHParamFile directive is used to configure a file that mod_tls will use when engaging in a Diffie-Hellman key exchange. Such a key exchange can be computationally intensive, in terms for parameter generation; to help speed up the process, the parameters used may be generated in advance, and stored in a file. The dhparam utility that comes with OpenSSL may be used to generate an appropriate file for this directive. The file parameter must be an absolute path.

    See also

    Examples

    TLSDSACertificateFile

    Name

    TLSDSACertificateFile -- Point to the file containing the DSA certificate

    Synopsis

    TLSDSACertificateFile [ TLSDSACertificateFile filename]

    Default

    None

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_tls

    Compatibility

    1.2.7rc1 and later

    Description

    The TLSDSACertificateFile directive points to the PEM-encoded file containing the DSA certificate file for the server and optionally also the corresponding DSA private key file.

    If the contained private key is encrypted, the administrator will be prompted for the passphrase when the daemon starts up, and when the daemon is restarted.

    Examples

    TLSDSACertificateKeyFile /etc/ftpd/server-dsa-key.pem

    TLSDSACertificateKeyFile

    Name

    TLSDSACertificateKeyFile -- Point to the file containing the private DSA key

    Synopsis

    TLSDSACertificateKeyFile [ TLSDSACertificateKeyFile filename]

    Default

    None

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_tls

    Compatibility

    1.2.7rc1 and later

    Description

    The TLSDSACertificateKeyFile directive points to the PEM-encoded private key file for the server. If the private key is not combined with the certificate in the TLSDSACertificateFile, use this additional directive to point to the file with the standalone private key. When TLSDSACertificateFile is used and the file contains both the certificate and the private key, this directive need not be used. However, this practice is strongly discouraged. Instead we recommend you to separate the certificate and the private key.

    If the contained private key is encrypted, the administrator will be prompted for the passphrase when the daemon starts up, and when the daemon is restarted.

    Examples

    TLSDSACertificateKeyFile /etc/ftpd/server-dsa-key.pem

    TLSEngine

    Name

    TLSEngine -- Enable TLS/SSL connections

    Synopsis

    TLSEngine [ [ on off ]]

    Default

    off

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_tls

    Compatibility

    1.2.7rc1 and later

    Description

    The TLSEngine directive toggles the use of the SSL/TLS protocol engine (e.g. mod_tls). This is usually used inside a <VirtualHost> section to enable SSL/TLS sessions for a particular virtual host. By default mod_tls is disabled for both the main server and all configured virtual hosts.

    See also

    Examples

    TLSLog

    Name

    TLSLog -- Specify a logfile for mod_tls's reporting on a per-server basis

    Synopsis

    TLSLog [ TLSLog filename]

    Default

    None

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_tls

    Compatibility

    1.2.7rc1 and later

    Description

    The TLSLog directive is used to specify a log file for mod_tls's reporting on a per-server basis. The file parameter given must be the full path to the file to use for logging.

    See also

    Examples

    TLSOptions

    Name

    TLSOptions -- Configure optional behaviour of mod_tls

    Synopsis

    TLSOptions [ [ AllowDotLogin ] [ Allow PerUser ] [ ExportCertData ] [ NoCertRequest ] [ StdEnvVars ] [ dNSNameRequired ] [ iPAddressRquired ]]

    Default

    None

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_tls

    Compatibility

    1.2.7rc1 and later

    Description

    The TLSOptions directive is used to configure various optional behavior of mod_tls. The currently implemented options are:

    • AllowDotLogin

      By default, mod_tls still requires that a user supply a password for authentication, even if a valid client certificate is presented. If this option is enabled, mod_tls will check in the user's home directory for a .tlslogin file, which should contain one or more PEM-encoded certificates. If the certificate presented by the client, if any, matches a certificate in this .tlslogin file, the user will be considered authenticated. The server will still prompt for a password, and if the user's .tlslogin does not exist, or does not contain the client's certificate, then the server will fallback to using the password for authentication.

    • AllowPerUser

      This option affects how mod_tls evaluates any TLSRequired directives. Usually mod_tls will reject any FTP commands, when TLSRequired on or TLSRequired ctrl is in effect, if the client has not successfully negotiated a SSL/TLS handshake. The FTPS specification requires that the SSL/TLS handshake occur, via the AUTH FTP command, before the USER and PASS commands. This means that mod_tls does not know the identity of the connecting client when enforcing TLSRequired. If this AllowPerUser is used, mod_tls will wait until after the PASS command has been processed to enforce any TLSRequired settings.

      Important: if AllowPerUser is used, even if TLSRequired on or TLSRequired ctrl are in effect, it will be possible for the connecting client to send usernames and passsword unprotected before mod_tls rejects the connection. This results in a slightly weaker security policy enforcement; please consider carefully if this tradeoff is acceptable for your site.

    • ExportCertData

      Sets the following environment variables, if applicable. Note that doing so increases the memory size of the process quite a bit:

      Table 1-1. Enviroment variables

      TLS_SERVER_CERTServer certificate, PEM-encoded
      TLS_CLIENT_CERTCLient certificate, PEM-encoded
      TLS_CLIENT_CERT_CHAINnPEM-encoded certificates in client certificate chain

    • NoCertRequest

      Some FTP clients are known to be buggy when handling a server's certificate request. This option causes the server not to include such a request during an SSL handshake.

    • StdEnvVars

      Sets the following environment variables, if applicable. These environment variables are then avaiable for use, such as in LogFormats. Note that doing so increases the memory size of the process quite a bit: increases the memory size of the process quite a bit:

      Table 1-2. Enviroment variables

      FTPSPresent if FTP over SSL/TLS is being used
      TLS_PROTOCOLSSL protocol version (e.g. SSLv3, TLSv1)
      TLS_SESSION_IDHex-encoded SSL session ID
      TLS_CIPHERCipher specification name
      TLS_CIPHER_EXPORTPresent if cipher is an export cipher
      TLS_CIPHER_KEYSIZE_POSSIBLENumber of cipher bits possible
      TLS_CIPHER_KEYSIZE_USEDNumber of cipher bits used
      TLS_LIBRARY_VERSIONOpenSSL version
      TLS_CLIENT_M_VERSIONClient certificate version
      TLS_CLIENT_M_SERIALClient certificate serial number
      TLS_CLIENT_S_DNSubject DN of client certificate
      TLS_CLIENT_S_DN_x509Component of client certificate's Subject DN, where x509 is a component of a X509 DN: C,CN,D,I,G,L,O,OU,S,ST,T,UID,Email
      TLS_CLIENT_I_DNIssuer DN of client certificate
      TLS_CLIENT_I_DN_x509Component of client certificate's Issuer DN, where x509 is a component of a X509 DN: C,CN,D,I,G,L,O,OU,S,ST,T,UID,Email
      TLS_CLIENT_V_STARTStart time of client certificate validity
      TLS_CLIENT_V_ENDEnd time of client certificate validity
      TLS_CLIENT_A_SIGClient certificate's signature algorithm
      TLS_CLIENT_A_KEYClient certificate's public key algorithm
      TLS_CLIENT_CERTClient certificate, PEM-encoded
      TLS_CLIENT_CERT_CHAINnPEM-encoded certificates in client certificate chain
      TLS_SERVER_M_VERSIONServer certificate version
      TLS_SERVER_M_SERIALServer certificate serial number
      TLS_SERVER_S_DNSubject DN of server certificate
      TLS_SERVER_S_DN_x509Component of server certificate's Subject DN, where x509 is a component of a X509 DN: C,CN,D,I,G,L,O,OU,S,ST,T,UID,Email
      TLS_SERVER_I_DNIssuer DN of server certificate
      TLS_SERVER_I_DN_x509Component of server certificate's Issuer DN, where x509 is a component of a X509 DN: C,CN,D,I,G,L,O,OU,S,ST,T,UID,Email
      TLS_SERVER_V_STARTStart time of server certificate validity
      TLS_SERVER_V_ENDEnd time of server certificate validity
      TLS_SERVER_A_SIGServer certificate's signature algorithm
      TLS_SERVER_A_KEYServer certificate's public key algorithm
      TLS_SERVER_CERTServer certificate, PEM-encoded

    • dNSNameRequired

      This option will cause mod_tls to perform checks on a client's certificate once the SSL handshake has been completed: the client's certificate will be searched for the subjectAltName X509v3 extension, and, in that extension, the dNSName value will be looked up. Unless a dNSName value is present, and the value matches the DNS name to which the client's IP address resolves, the SSL session is closed. This check is only performed during SSL handshakes on the control channel. Note that if UseReverseDNS is off, this option is automatically disabled.

    • iPAddressRequired

      This option will cause mod_tls to perform checks on a client's certificate once the SSL handshake has been completed: the client's certificate will be searched for the subjectAltName X509v3 extension, and, in that extension, the iPAddress value will be looked up. Unless an iPAddress value is present, and the value matches the IP address of the client, the SSL session is closed. This check is only performed during SSL handshakes on the control channel.

    See also

    Examples

    TLSOptions iPAddressRequired StdEnvVars

    TLSPassPhraseProvider

    Name

    TLSPassPhraseProvider -- FIXFIXFIX

    Synopsis

    TLSPassPhraseProvider [ "name" limit|regex|ip value]

    Default

    FIXFIXFIX

    Context

    server config, <Global>, <VirtualHost>, <Anonymous>, <Limit>, .ftpaccess

    Module

    mod_tls

    Compatibility

    1.3.1rc1 and later

    Description

    FIX FIX FIX

    See also

    Examples

    FIXFIXFIX

    FIXFIX

    TLSProtocol

    Name

    TLSProtocol -- Define the SSL/TLS protocol version mod_tls should use

    Synopsis

    TLSProtocol [ [ SSLv23 SSLv3 TLSv1 ]]

    Default

    SSLv23

    Context

    server config

    Module

    mod_tls

    Compatibility

    1.2.7rc1 and later

    Description

    The TLSProtocol directive is used to configure the SSL/TLS protocol versions that mod_tls should use when establishing SSL/TLS sessions. Clients can then only connect using the configured protocol.

    Since the protocol version used by mod_tls is set only once, when the daemon starts, the TLSProtocol directive is only allowed in the "server config" context.

    The allowed protocols are:

    SSLv23 Compatibility mode, used to allow both SSLv3 and TLSv1

    SSLv3 Allow only SSLv3

    TLSv1 Allow only TLSv1

    All use of SSLv2 is disabled. SSLv2 should not be used.

    See also

    Examples

    TLSRandomSeed

    Name

    TLSRandomSeed -- Define a file for PRNG seeding

    Synopsis

    TLSRandomSeed [ Absolute path to the file]

    Default

    openssl-dir /.rnd

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_tls

    Compatibility

    1.2.7rc1 and later

    Description

    The TLSRandomSeed directive configures the file that mod_tls will use for seeding the PRNG. seed must be an absolute path.

    When the daemon shuts down, any random data left will be written out to the random seed file, so that that data may be used for seeding when the daemon is started again.

    See also

    Examples

    TLSRandomSeed /etc/ftpd/server.rnd

    TLSRenegotiate

    Name

    TLSRenegotiate -- Configure SSL renegotiations

    Synopsis

    TLSRenegotiate [ ["ctrl" secs] ["data" Kbytes] ["timeout" secs]|["required" on|off]|"none"]

    Default

    None

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_tls

    Compatibility

    1.2.7rc1 and later

    Description

    The TLSRenegotiate directive is used to configure when SSL renegotiations are to occur. Renegotiations, and thus this directive, are only supported by mod_tls if the version of OpenSSL installed is 0.9.7 or greater.

    If supported, renegotiations will occur on control channels that have been established for four hours by default, and on data channels that have transferred over one gigabyte of data by default. When renegotiations are requested, the client is given a timeout of 30 seconds, by default, to perform the renegotiation. To change the default control channel renegotiation timeout, use ctrl followed by a number, greater than zero, in seconds. Use data followed by a number, greater than zero, of kilobytes to change the default data channel renegotiation threshhold. The timeout parameter, followed by a positive number of seconds, is used to change the length of time given to a client to complete a requested renegotiation, after which the SSL session will be shutdown. By default, mod_tls will require that the client comply with the requested renegotiation within the TLSRenegotiate timeout. If, however, the client is unwilling or unable to do so, and the daemon needs to support these clients, set required to off. Doing so will cause renegotiations to be requested, but not required.

    By default, mod_tls will perform renegotiations if supported, on the control channel after 4 hours, and on the data channel after one gigabyte of transferred data. The default timeout for a renegotiation is 30 seconds.

    Use none to disable all renegotiation requirements.

    See also

    Examples

        # Change renegotiations to occur on control channels after 1 hour
        TLSRenegotiate ctrl 3600

        # Change renegotiations to occur on data channels after 500 MB
        TLSRenegotiate data 512000

        # Change renegotiations so that they are not required, only requested
        TLSRenegotiate required off

        # Change only the timeout for renegotiations to be 5 minutes
        TLSRenegotiate timeout 300

        # Change all of the above renegotiation threshholds using one directive
        TLSRenegotiate ctrl 3600 data 512000 required off timeout 300

        # To disable renegotiations entirely
        TLSRenegotiate none

    TLSRequired

    Name

    TLSRequired -- Require SSL/TLS on the control and/or data channel

    Synopsis

    TLSRequired [ on | off | ctrl | data | auth | auth+data]

    Default

    off

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_tls

    Compatibility

    1.2.7rc1 and later

    1.3.1rc1 and later provide the auth and auth+data options

    Description

    The TLSRequired directive is used to define a basic security policy, one that dictates whether the control channel, or data channel, or both, of an FTP session must occur over SSL/TLS.

    The "on" parameter enables SSL/TLS requirements on both control and data channels; "off" disables the requirements on both channels. Use "ctrl" and "data" to require SSL/TLS on either channel individually.

    The "auth" parameter requires that SSL/TLS be used on the control channel, but only for authentication. To use this setting and require SSL/TLS for data transfers, use the "auth+data" parameter.

    This "auth+data" parameter allows a very specific security policy: authentication via the USER/PASS commands must be protected via SSL/TLS, as must the data channel, but after authenticating, the client can request that protection be removed from the control channel. This policy allows clients to use the CCC (Clear Command Channel) command, which in turn enables SSL/TLS protected data transfers that are operate better with firewalls that monitor the FTP control channel.

    See also

    Examples

      # Require SSL/TLS on the control channel, so that passwords are not sent
      # in the clear.
      TLSRequired ctrl

      # Require SSL/TLS on both channels.
      TLSRequired on

      # Allow the client to use the CCC command to remove SSL/TLS from the
      # control channel, but only after authentication has been performed.
      # Still enforce the policy of using SSL/TLS for data transfers.
      #
      # Note that if we did not need to protect data transfers, we would
      # set 'TLSRequired auth' instead of using 'TLSRequired auth+data'.
      TLSRequired auth+data

    TLSRSACertificateFile

    Name

    TLSRSACertificateFile -- Point to the file containing the RSA certificate

    Synopsis

    TLSRSACertificateFile [ TLSRSACertificateFile filename]

    Default

    None

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_tls

    Compatibility

    1.2.7rc1 and later

    Description

    The TLSRSACertificateFile directive points to the PEM-encoded file containing the RSA certificate file for the server and optionally also the corresponding RSA private key file.

    If the contained private key is encrypted, the administrator will be prompted for the passphrase when the daemon starts up, and when the daemon is restarted.

    Examples

      TLSRSACertificateFile /etc/ftpd/server-rsa-cert.pem

    TLSRSACertificateKeyFile

    Name

    TLSRSACertificateKeyFile -- Point to the file containing the private RSA key

    Synopsis

    TLSRSACertificateKeyFile [ TLSRSACertificateKeyFile filename]

    Default

    None

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_tls

    Compatibility

    1.2.7rc1 and later

    Description

    The TLSRSACertificateKeyFile directive points to the PEM-encoded private key file for the server. If the private key is not combined with the certificate in the TLSRSACertificateFile, use this additional directive to point to the file with the standalone private key. When TLSRSACertificateFile is used and the file contains both the certificate and the private key, this directive need not be used. However, this practice is strongly discouraged. Instead we recommend you to separate the certificate and the private key.

    If the contained private key is encrypted, the administrator will be prompted for the passphrase when the daemon starts up, and when the daemon is restarted.

    See also

    Examples

      TLSRSACertificateKeyFile /etc/ftpd/server-rsa-key.pem

    TLSVerifyClient

    Name

    TLSVerifyClient -- Configure how to candle certificates presented by clients -- 

    Synopsis

    TLSVerifyClient [ on off]

    Default

    off

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_tls

    Compatibility

    1.2.7rc1 and later

    Description

    The TLSVerifyClient directive configures how mod_tls handles certificates presented by clients. If off, the module will accept the certificate and establish an SSL/TLS session, but will not verify the certificate. If on, the module will verify a client's certificate and, furthermore, will fail all SSL handshake attempts unless the client presents a certificate when the server requests one. Note that the server can be configured to not request a client certificate via the TLSOptions directive's "NoCertRequest" parameter.

    See also

    Examples

    TLSVerifyDepth

    Name

    TLSVerifyDepth -- Define how deeply mod_tls should verify a client certificate

    Synopsis

    TLSVerifyDepth [ depth]

    Default

    9

    Context

    server config, <Global>, <VirtualHost>

    Module

    mod_tls

    Compatibility

    1.2.7rc1 and later

    Description

    The TLSVerifyDepth directive sets how deeply mod_tls should verify before deciding that the client does not have a valid certificate. The depth actually is the maximum number of intermediate certificate issuers, i.e. the number of CA certificates which are allowed to be followed while verifying the client certificate. A depth of 0 means that only self-signed client certificates are accepted, a depth of 1 means the client certificate can be self-signed or has to be signed by a CA which is directly known to the server (i.e. the CA's certificate is under TLSCACertificatePath), etc.

    See also

    Examples

      TLSVerifyDepth 10

    TransferLog

    Name

    TransferLog -- Specify the path to the transfer log

    Synopsis

    TransferLog [ TransferLog filename|NONE]

    Default

    TransferLog /var/log/xferlog

    Context

    server config, <Anonymous>, <VirtualHost>, <Global>

    Module

    mod_core

    Compatibility

    1.1.4 and later

    Description

    The TransferLog directive configures the full path to the "wu-ftpd style" file transfer log. Separate log files can be created for each Anonymous and/or VirtualHost. Additionally, the special keyword NONE can be used, which disables wu-ftpd style transfer logging for the context in which the directive is used (only applicable to version 1.1.7 and later). See Also: ExtendedLog, LogFormat

    See also

    Examples

    TransferRate

    Name

    TransferRate -- Configure upload, download transfer rates

    Synopsis

    TransferRate [ cmds] [ kilobytes-per-sec[:free-bytes]] [ ["user"|"group"|"class" expression]]

    Default

    None

    Context

    server config, <VirtualHost>, <Global>, <Anonymous>, <Directory>, .ftpaccess

    Module

    mod_xfer

    Compatibility

    1.2.8rc1 and later

    Description

    The TransferRate directive is used to set transfer rates limits on the transfer of data. This directive allows for transfer rates to be set in a wide variety of contexts, on a per-command basis, and for certain subsets of users. Note that this limit only applies to a single connection, and not to the overall transfer rate of the server.

    The cmds parameter may be an comma-separated list of any of the following commands: APPE, RETR, STOR, and STOU.

    The kilobytes-per-sec parameter is the actual transfer rate to be applied.

    The free-bytes parameter, if configured, allows that many bytes to be transferred before the rate controls are applied. This allows for clients transferring small files to be unthrottled, but for larger files, such as MP3s and ISO images, to be throttled.

    The optional parameters are used to restrict the application of the rate controls only to specific users. If the "user" restriction is given, then expression is a user-expression specifying to which users the rate applies. Similarly for the "group" restriction. For the "class" restriction, the expression is simply the name of connection class for whom the rate will apply.

    Examples

    # Limit downloads for everyone except the special group of users TransferRate RETR 1.5 group !special-users

    # Limit uploads (and appends!) to the prolific users in the # lotsofuploadfiles.net domain. This presumes that a Class has been defined # for that domain, and that that Class has been named "uploaders". Let them # upload small files without throttling, though. TransferRate APPE,STOR 8.0:1024 class uploaders

    Umask

    Name

    Umask -- Set the default Umask

    Synopsis

    Umask [ Umask file octal-mask [directory octal-mask]]

    Default

    None

    Context

    server config, <Anonymous>, <VirtualHost>, <Directory>, <Global>, .ftpaccess

    Module

    mod_core

    Compatibility

    0.99.0 and later

    Description

    Umask sets the mask applied to newly created file and directory permissions within a given context. By default, the Umask in the server configuration, <VirtualHost> or <Anonymous> block is used, unless overridden by a "per-directory" Umask setting. Any arguments supplied must be an octal number, in the format 0xxx. An optional second argument can specify a Umask to be used when creating directories. If a second argument isn't specified, directories are created using the default Umask in the first argument. For more information on umasks, consult your operating system documentation/man pages.

    Proftpd will not create files that have the execution bit turned on, this is a security driven design decision. The permissions of the uploaded file can be changed by issuing a SITE CHMOD command can be used to change the mode of the uploaded file. Syntax of the command is: SITE CHMOD <mode> <file>.

    See also

    Examples

    UnsetEnv

    Name

    UnsetEnv -- (docs incomplete)

    Synopsis

    UnsetEnv [ key]

    Default

    None

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_core

    Compatibility

    1.2.10rc1 and later

    Description

    (docs incomplete)

    See also

    Examples

    (docs incomplete)

    UseFtpUsers

    Name

    UseFtpUsers -- Block based on /etc/ftpusers

    Synopsis

    UseFtpUsers [ UseFtpUsers on|off]

    Default

    UseFtpUsers on

    Context

    server config, <Anonymous>, <VirtualHost>, <Global>

    Module

    mod_auth

    Compatibility

    0.99.0 and later

    Description

    Legacy FTP servers generally check a special authorization file (typically /etc/ftpusers) when a client attempts to authenticate. If the user's name is found in this file, FTP access is denied. For compatibility sake, proftpd defaults to checking this file during authentication. This behavior can be suppressed using the UseFtpUsers configuration directive.

    See also

    Examples

    UseGlobbing

    Name

    UseGlobbing -- Toggles use of glob() functionality

    Synopsis

    UseGlobbing [ on|off]

    Default

    UseGlobbing on

    Context

    server config, <VirtualHost>, <Global>, <Anonymous>

    Module

    mod_ls

    Compatibility

    1.2.5rc1 and later

    Description

    The UseGlobbing directive controls use of glob() functionality, which is needed for supporting wildcard characters such as *.

    See also

    UseIPv6

    Name

    UseIPv6 -- Disable IPv6 support

    Synopsis

    UseIPv6 [ "on"|"off"]

    Default

    UseIPv6 on

    Context

    server config

    Module

    mod_core

    Compatibility

    1.3.1rc1 and later

    Description

    This directive enables or disables the IPv6 support within proftpd. It's also possible to control this behaviour with command-line options.

    -4, --ipv4     Support IPv4 functionality only
    -6, --ipv6     Support IPv6 functionality

    See also

    Examples

    proftpd -4

    Start Proftpd only with IPv4 functionality enabled.

    User

    Name

    User -- Set the user the daemon will run as

    Synopsis

    User [ User userid]

    Default

    None

    Context

    server config, <VirtualHost>, <Anonymous>, <Global>

    Module

    mod_core

    Compatibility

    0.99.0 and later

    Description

    The User directive configures which user the proftpd daemon will normally run as. By default, proftpd runs as root which is considered undesirable in all but the most trustful network configurations. The User directive used in conjunction with the Group directive instructs the daemon to switch to the specified user and group as quickly as possible after startup. On some unix variants, the daemon will occasionally switch back to root in order to accomplish a task which requires super-user access. Once the task is completed, root privileges are relinquished and the server continues to run as the specified user and group. When applied to a <VirtualServer> block, proftpd will run as the specified user/group on connections destined for the virtual server's address or port. If either User or Group is applied to an <Anonymous> block, proftpd will establish an anonymous login when a user attempts to login with the specified userid, as well as permanently switching to the corresponding uid/gid (matching the User/Group parameters found in the anonymous block) after login. Note: When an authorized unix user is authenticated and logs in, all former privileges are released, the daemon switches permanently to the logged in user's uid/gid, and is never again capable of switching back to root or any other user/group.

    See also

    Examples

    UserAlias

    Name

    UserAlias -- Alias a username to a system user

    Synopsis

    UserAlias [ login-user real-user]

    Default

    None

    Context

    server config, <VirtualHost>, <Anonymous>, <Global>

    Module

    mod_auth

    Compatibility

    0.99.0 and later

    Description

    ProFTPD requires a real username/uid when authenticating users as provided by PAM, AuthUserFile or another authentication mechanism. There are however times when additional aliases are required but it is undesirable to provide additional login accounts.

    UserAlias provides a mechanism to do this, a typical and common example is within Anonymous configuration blocks. It is normal for the server to use 'ftp' as the primary authentication user, however it is common practice for users to login using "anonymous". This is achieved by adding the following to the config file.

    See also

    Examples

    UserAlias anonymous ftp

    UserDirRoot

    Name

    UserDirRoot -- Set the chroot directory to a subdirectory of the anonymous server

    Synopsis

    UserDirRoot [ UserDirRoot on|off]

    Default

    off

    Context

    <Anonymous>

    Module

    mod_auth

    Compatibility

    1.2.0pre2 and later

    Description

    When set to true, the chroot base directory becomes a subdirectory of the anonymous ftp directory, based on the username of the current user. For example, assuming user "foo" is aliased to "ftp", logging in as "foo" causes proftpd to run as real user ftp, but to chroot into ~ftp/foo instead of just ~ftp.

    See also

    Examples

    UseReverseDNS

    Name

    UseReverseDNS -- Toggle rDNS lookups

    Synopsis

    UseReverseDNS [ UseReverseDNS on|off]

    Default

    UseReverseDNS on

    Context

    server config

    Module

    mod_core

    Compatibility

    1.1.7 and later

    Description

    Normally, incoming active mode data connections and outgoing passive mode data connections have a reverse DNS lookup performed on the remote host's IP address. In a chroot environment (such as <Anonymous> or DefaultRoot), the /etc/hosts file cannot be checked and the only possible resolution is via DNS. If for some reason, DNS is not available or improperly configured this can result in proftpd blocking ("stalling") until the libc resolver code times out. Disabling this directive prevents proftpd from attempting to reverse-lookup data connection IP addresses.

    See also

    Examples

    UserOwner

    Name

    UserOwner -- Set the user ownership of new files / directories

    Synopsis

    UserOwner [ UserOwner username]

    Default

    None

    Context

    <Anonymous>, <Directory>

    Module

    mod_core

    Compatibility

    1.2pre11 and later

    Description

    The UserOwner directive configures which user all newly created directories and files will be owned by, within the context that UserOwner is applied to. The user ID of username cannot be 0 (root). Where it is used, the GroupOwner directive is not restricted to groups that the current user is a member of.

    See also

    GroupOwner

    Examples

    UserPassword

    Name

    UserPassword -- Creates a hardcoded username/password pair

    Synopsis

    UserPassword [ UserPassword userid hashed-password]

    Default

    None

    Context

    server config, <VirtualHost>, <Anonymous>, <Global>

    Module

    mod_auth

    Compatibility

    0.99.0pl5 and later

    Description

    The UserPassword directive creates a password for a particular user which overrides the user's normal password in /etc/passwd (or /etc/shadow). The override is only effective inside the context to which UserPassword is applied. The hashed-password argument is a cleartext string which has been passed through the standard unix crypt() function. Do NOT use a cleartext password. This can be useful when combined with UserAlias to provide multiple logins to an Anonymous FTP site. See Also: GroupPassword

    See also

    Examples

    UserRatio

    Name

    UserRatio -- Ratio directive

    Synopsis

    UserRatio [ UserRatio foo1 foo2 foo3]

    Default

    None known

    Context

    <Directory>, <Anonymous>, <Limit>,.ftpaccess

    Module

    mod_ratio

    Compatibility

    at least 1.2.0 and later

    Description

    The UserRatio directive .... Example: UserRatio

    See also

    Examples

    UseSendfile

    Name

    UseSendfile -- Toggles use of sendfile() functionality

    Synopsis

    UseSendfile [ on|off]

    Default

    UseSendfile on

    Context

    server config, <VirtualHost>, <Global>

    Module

    mod_xfer

    Compatibility

    1.3.0rc1 and later

    Description

    The UseSendfile directive controls use of sendfile functionality, which is an optimization for sending files to clients. Use of sendfile functionality avoids separate read and send operations, and buffer allocations. But on some platforms or within some filesystems, it is better to disable this feature to avoid operational problems:

     *  Some platforms may have broken sendfile support that the build system
        did not detect, especially if the binaries were built on another box
        and moved to such a machine with broken sendfile support.
    
     * On Linux the use of sendfile triggers TCP-checksum offloading bugs on
       certain networking cards when using IPv6.
    
     * With a network-mounted directories (e.g. NFS or SMB), the kernel may be
       unable to serve the network file through its own cache.

    Note that if sendfile support is enabled, tools like ftpwho and ftptop will not show the transfer rate for downloads. These tools work by reading the ScoreboardFile, and the ScoreboardFile is updated periodically during uploads and downloads. However, when sendfile support is used, the ScoreboardFile does not have a chance to be updated. This is only true for downloads; the tools will continue to show the transfer rate for uploads.

    UseUTF8

    Name

    UseUTF8 -- FIXFIXFIX

    Synopsis

    UseUTF8 [ "name" limit|regex|ip value]

    Default

    FIXFIXFIX

    Context

    server config, <Global>, <VirtualHost>, <Anonymous>, <Limit>, .ftpaccess

    Module

    mod_core

    Compatibility

    1.3.1rc1 and later

    Description

    FIX FIX FIX

    See also

    Examples

    FIXFIXFIX

    FIXFIX

    VirtualHost

    Name

    VirtualHost -- Define a virtual ftp server

    Synopsis

    VirtualHost [ <VirtualHost addresses seperated by spaces>]

    Default

    None

    Context

    server config

    Module

    mod_core

    Compatibility

    0.99.0 and later

    Description

    The VirtualHost configuration block is used to create an independent set of configuration directives that apply to a particular hostname or IP address. It is often used in conjunction with system level IP aliasing or dummy network interfaces in order to establish one or more "virtual" servers which all run on the same physical machine. The block is terminated with a </VirtualHost> directive. By utilizing the Port directive inside a VirtualHost block, it is possible to create a virtual server which uses the same address as the master server, but listens on a separate tcp port (incompatible with ServerType inetd). When proftpd starts, virtual server connections are handled in one of two ways, depending on the ServerType setting: inetd The daemon examines the destination address and port of the incoming connection handed off from inetd. If the connection matches one of the configured virtual hosts, the connection is serviced based on the appropriate configuration. If no virtual host matches, and the main server does not match, the client is informed that no server is available to service their requests and disconnected. standalone After parsing the configuration file, the daemon begins listening for connections on all configured ports, spawning child processes as necessary to handle connections for either the main server or any virtual servers. Because of the method that the daemon uses to listen for connections when in standalone mode, it is possible to support an exceedingly large number of virtual servers, potentially exceeding the number of per-process file descriptors. This is due to the fact that a single file descriptor is used to listen to each configured port, regardless of the number of addresses being monitored. Note that it may be necessary to increase the tcpBackLog value on heavily loaded servers in order to avoid kernel rejected client connections ("Connection refused").

    Starting with ProFTPD 1.3.0rc1 it's possible to use more than one FQDN or IP Address. With this change the old Bind directive has been deprecated.

    Examples

    <VirtualHost host1.domain.com host2.domain.com> ... </VirtualHost>

    WtmpLog

    Name

    WtmpLog -- Toggle logging to wtmp

    Synopsis

    WtmpLog [ WtmpLog on|off|NONE]

    Default

    WtmpLog on

    Context

    server config, <VirtualHost>, <Anonymous>, <Global>

    Module

    mod_core

    Compatibility

    1.1.7 and later

    Description

    The WtmpLog directive controls proftpd's logging of ftp connections to the host system's wtmp file (used by such commands as `last'). By default, all connections are logged via wtmp. Please report any corrections or additions via http://bugs.proftpd.net/

    See also

    Examples


    Chapter 2. List of modules

    mod_auth

    Name

    mod_auth -- Authentication module

    Synopsis

    mod_auth

    Description

    FIXME FIXME FIXME

    mod_core

    Name

    mod_core -- Core module

    Synopsis

    mod_core

    Description

    This module provides all the core functionality ProFTPD needs to function, this module must be compiled in.

    mod_delay

    Name

    mod_tls -- Prevent information leak through timing attacks

    Synopsis

    mod_delay

    Description

    When proftpd processes the USER and PASS FTP commands from a client, it has to perform checks against configured ACLs, look up user and group information, etc. These checks are not done if the given username is known to not exist for the server, in order to not tie up system resources needlessly. However, this does mean that more work is done when handling "good" users than when handling "bad" users. This difference can be detected in the time it takes for proftpd to send a response to the USER and PASS commands. This means it is possible for an attacker to look for these statistical timing differences, and determine which users are "good" and which are "bad". From there, a determined attacker can focus their attention on the known good usernames. Note that the timings will vary depending on server load, number of users in the user base, type of storage of user data (e.g. LDAP directories, SQL tables, RADIUS servers, flat files, etc).

    The mod_delay module attempts to prevent such timing differences by keeping track of the time taken to process the USER and PASS commands. It does this for the most recent USER and PASS commands. The timing data are stored in the module's DelayTable. If the module detects that proftpd has not taken enough time to handle one of these commands, compared to its past response times, a small delay will be added to the response cycle. The amount of delay is determined by the difference between the current time spent handling the command and the median time spent handling the same command in the past.

    Installation

    The mod_delay module is distributed with ProFTPD and compiled in by default.

    mod_ldap

    Name

    mod_ldap -- LDAP authentication support

    Synopsis

    mod_ldap

    Description

    mod_ldap provides LDAP authentication support for ProFTPD. It supports many features useful in "toaster" environments such as default UID/GID and autocreation/autogeneration of home directories.

    mod_log

    Name

    mod_log -- Logging support

    Synopsis

    mod_log

    Description

    Logging support, including enhanced formatting options.

    mod_ls

    Name

    mod_ls -- file listing functionality

    Synopsis

    mod_ls

    Description

    FIXME FIXME FIXME

    mod_radius

    Name

    mod_radius -- RADIUS based authentication support

    Synopsis

    mod_radius

    Description

    This module provides RADIUS authentication and accounting support.

    Strong authentication is in demand for Internet services. For many, this means using the RADIUS (Remote Authentication Dial-In User Service) protocol.

    However, there are caveats to using RADIUS for authentication. RADIUS packets are sent in the clear, which means that they can easily be sniffed. First, do not have your authenticating RADIUS servers exposed to the Internet; keep them protected within your LAN. Second, it is highly recommended to use separate RADIUS servers for each of your services.

    RADIUS Authentication

    The RADIUS protocol can be used for answering the question "Should this user be allowed to login?" However, the "yes/no" answer is not everything that proftpd needs to log a user in; the server also requires the UID and GID to use for the authenticated user, home directory, and shell. This information is usually not available from the RADIUS servers, which means that using RADIUS to provide all the necessary login information can be problematic. The RadiusUserInfo directive is meant to be used to address this issue, to provide the missing information.

    In those cases where the RADIUS servers can provide that additional login information, via custom attributes, the RadiusUserInfo directive can also be used obtain that information as well.

    RADIUS Accounting

    While RADIUS is primarily used for authentication, the protocol also allows for accounting of user activities. The mod_radius module makes use of this ability, using RADIUS accounting packets to transmit the following data:

    * Acct-Authentic: How the user was authenticated (e.g. locally, or via RADIUS) * Acct-Session-Id: The process ID of the FTP session * Acct-Session-Time: The duration of the FTP session, in seconds * Acct-Input-Octets: The number of bytes uploaded (includes appending to files) * Acct-Output-Octets: The number of bytes downloaded Merely configuring a RadiusAcctServer enables the module's accounting capabilities. Common Attributes The following RADIUS attributes are sent with every RADIUS packet generated by mod_radius: * User-Name: The name of the logging-in user * NAS-Identifier: Always "ftp" * NAS-IP-Address: IP address of FTP server * NAS-Port: Port of FTP server * NAS-Port-Type: Always Virtual. * Calling-Station-Id: IP address of connecting FTP client

    mod_ratio

    Name

    mod_ratio -- FIX ME FIX ME

    Synopsis

    mod_ratio

    Description

    FIXME FIXME FIXME

    mod_readme

    Name

    mod_readme -- "README" file support

    Synopsis

    mod_readme

    Description

    FIXME FIXME FIXME

    mod_sql

    Name

    mod_sql -- SQL support module

    Synopsis

    mod_sql

    Description

    This module provides the necessary support for SQL based authentication, logging and other features as required. It replaces the SQL modules which were shipped with 1.2.0rc2 and earlier.

    mod_tls

    Name

    mod_tls -- TLS/SSL support module

    Synopsis

    mod_tls

    Description

    This module provides the necessary support for encrypting you ftp sessions.

    Installation

    The mod_tls module is distributed with ProFTPD. Simply follow the normal steps for using third-party modules in proftpd: ./configure --with-modules=mod_tls make make install You may need to specify the location of the OpenSSL header and library files in your configure command, e.g.: ./configure --with-modules=mod_tls \ --with-includes=/usr/local/openssl/include \ --with-libraries=/usr/local/openssl

    mod_wrap

    Name

    mod_wrap -- Interface to libwrap

    Synopsis

    mod_wrap

    Description

    It enables the daemon to use the common tcpwrappers access control library while in standalone mode, and in a very configurable manner. It is not compiled by default.

    If not installed on your system, the TCP wrappers library, required by this module, can be found here, on Wietse Venema's site. Once installed, it highly recommended that the hosts_access(3) and hosts_access(5) man pages be read and understood.

    Many programs will automatically add entries in the common allow/deny files, and use of this module will allow a ProFTPD daemon running in standalone mode to adapt as these entries are added. The portsentry program does this, for example: when illegal access is attempted, it will add hosts to the /etc/hosts.deny file.

    mod_xfer

    Name

    mod_xfer -- FIX ME FIX ME

    Synopsis

    mod_xfer

    Description

    FIXME FIXME FIXME


    Chapter 3. List of configuration contexts

    server config

    Name

    server config -- server config

    Synopsis

    server config

    Description

    FIXME FIXME FIXME

    See also

    Global

    Name

    Global -- Global

    Synopsis

    Global

    Description

    FIXME FIXME FIXME

    See also

    VirtualHost

    Name

    VirtualHost -- VirtualHost

    Synopsis

    VirtualHost

    Description

    FIXME FIXME FIXME

    See also

    Anonymous

    Name

    Anonymous -- Anonymous

    Synopsis

    Anonymous

    Description

    FIXME FIXME FIXME

    See also

    Limit

    Name

    Limit -- Limit

    Synopsis

    Limit

    Description

    FIXME FIXME FIXME

    See also

    .ftpaccess

    Name

    .ftpaccess -- .ftpaccess

    Synopsis

    .ftpaccess

    Description

    FIXME FIXME FIXME

    See also

    Notes

    [1]

    proftpd-dfsg-1.3.5~rc3/doc/mod_sample.c0000644000175000017500000002614111566546322017614 0ustar frankiefrankie/* * The following is an *EXAMPLE* ProFTPD module. While it can be compiled * in to ProFTPD, it is not by default, and doesn't really do anything all * that terribly functional. */ /* * ProFTPD - FTP server daemon * Copyright (c) 1997, 1998 Public Flood Software * Copyright (c) 1999, 2000 MacGyver aka Habeeb J. Dihu * Copyright (c) 2001-2011 The ProFTPD Project team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * As a special exemption, Public Flood Software/MacGyver aka Habeeb J. Dihu * and other respective copyright holders give permission to link this program * with OpenSSL, and distribute the resulting executable, without including * the source code for OpenSSL in the source distribution. */ /* sample module for ProFTPD * $Id: mod_sample.c,v 1.11 2011/05/23 21:08:34 castaglia Exp $ */ #include "conf.h" #define MOD_SAMPLE_VERSION "mod_sample/0.0" /* Command handlers */ /* Example of a PRE_CMD handler here, which simply logs all received * commands via pr_log_debug(). We are careful to return PR_DECLINED, * otherwise other PRE_CMD handlers would not get the request. Note that in * order for this to work properly, this module would need to be loaded _last_, * or after any other modules which don't return PR_DECLINED for all * their precmds. In practice you should always return PR_DECLINED unless * you plan on having your module actually handle the command (or deny it). */ MODRET sample_pre_any(cmd_rec *cmd) { pr_log_debug(DEBUG0, "RECEIVED: command '%s', arguments '%s'.", cmd->argv[0], cmd->arg); return PR_DECLINED(cmd); } /* Next, an example of a LOG_CMD handler, which receives all commands * _after_ they have been processed, and additional only IF they were * successful. */ MODRET sample_log_any(cmd_rec *cmd) { pr_log_debug(DEBUG0, "SUCCESSFUL: command '%s', arguments '%s'.", cmd->argv[0], cmd->arg); return PR_DECLINED(cmd); } /* Now, a _slightly_ more useful handler. We define POST_CMD handlers * for RETR, STOR and LIST/NLST, so we can calculate total data transfer * for a session. */ static unsigned long total_rx = 0, total_tx = 0; MODRET sample_post_retr(cmd_rec *cmd) { /* The global variable 'session' contains lots of important data after * a file/directory transfer of any kind. It doesn't get cleared until * mod_xfer gets a LOG_CMD, so we can still get to it here. */ total_tx += session.xfer.total_bytes; return PR_DECLINED(cmd); } MODRET sample_post_stor(cmd_rec *cmd) { total_rx += session.xfer.total_bytes; return PR_DECLINED(cmd); } MODRET sample_post_list(cmd_rec *cmd) { return sample_post_retr(cmd); } MODRET sample_post_nlst(cmd_rec *cmd) { return sample_post_retr(cmd); } /* This command handler is for a non-standard FTP command, "XFOO". It * illustrates how one can write a module that handles such non-standard * commands. */ MODRET sample_xfoo(cmd_rec *cmd) { char *path = NULL; if (cmd->argc < 2) { pr_response_add_err(R_500, "XFOO command needs at least one argument"); return PR_ERROR(cmd); } /* We call pr_fs_decode_path() on the argument here, assuming that the * argument to this fictional XFOO command is indeed a path. RFC2640 * states that clients can encode paths as UTF8 strings; the * pr_fs_decode_path() function converts from UTF8 strings to the local * character set. */ path = dir_realpath(cmd->tmp_pool, pr_fs_decode_path(cmd->tmp_pool, cmd->arg)); if (!path) { pr_response_add_err(R_500, "It appears that '%s' does not exist", cmd->arg); return PR_ERROR(cmd); } pr_response_add_err(R_200, "XFOO command successful (yeah right!)"); return PR_HANDLED(cmd); } /* Configuration handlers */ /* This sample configuration directive handler will get called * whenever the "FooBarDirective" directive is encountered in the * configuration file. */ MODRET set_foobardirective(cmd_rec *cmd) { int bool = 1; config_rec *c = NULL; /* The CHECK_ARGS macro checks the number of arguments passed to the * directive against what we want. Note that this is *one* less than * cmd->argc, because cmd->argc includes cmd->argv[0] (the directive * itself). If CHECK_ARGS fails, a generic error is sent to the user */ CHECK_ARGS(cmd, 1); /* The CHECK_CONF macro makes sure that this directive is not being * "used" in the wrong context (i.e. if the directive is only available * or applicable inside certain contexts). In this case, we are allowing * the directive inside of and , but nowhere else. * If this macro fails a generic error is logged and the handler aborts. */ CHECK_CONF(cmd, CONF_ANON|CONF_LIMIT); /* Get the Boolean value of the first directive parameter. */ bool = get_boolean(cmd, 1); if (bool == -1) { /* The get_boolean() function returns -1 if the parameter was not a * recognized Boolean parameter. */ CONF_ERROR(cmd, "requires a Boolean parameter"); } /* add_config_param() adds a configuration parameter record to our current * configuration context. We're initially setting the value stored in * the config_rec to be NULL, so that we can allocate memory of the * proper size for storing the Boolean value. */ c = add_config_param(cmd->argv[0], 1, NULL); /* Allocate space for the Boolean value. The smallest data type in C * is an unsigned char (1 byte), and a Boolean will easily fit within * that space. */ c->argv[0] = pcalloc(c->pool, sizeof(unsigned char)); *((unsigned char *) c->argv[0]) = bool; /* By adding the CF_MERGEDOWN flag to the parameter we just created * we are telling proftpd that this parameter should be copied and * "merged" into all "lower" contexts until it either hits a * parameter w/ the same name or bottoms out. * * Example _without_ CF_MERGEDOWN: * * * |----------\ * * | - FooBarDirective <------- Config places it here * |-----------\ * <------- Doesn't apply here * |-------------\ * <--- Or here..... * * Now, if we specify CF_MERGDOWN, the tree ends up looking like: * * * |----------\ * * | - FooBarDirective <------- Config places it here * |-----------\ * <------- Now, it DOES apply here * | - FooBarDirective * |-------------\ * <-------- And here ... * | - FooBarDirective * */ c->flags |= CF_MERGEDOWN; /* Tell proftpd that we handled the request w/ no problems. */ return PR_HANDLED(cmd); } /* Initialization routines */ /* Each module can supply up to two initialization routines (via * the module structure at the bottom of this file). The first * init function is called immediately after the module is loaded, * while the second is called after proftpd is connected to a client, * and the main proftpd server (if not in inetd mode) has forked off. * The second init function's purpose is to let the module perform * any necessary work for initializing a session, once a client is connected * and the daemon is ready to service the new client. In inetd mode, the * session initialization function will be called immediately after proftpd is * loaded, because proftpd is _always_ in "child mode" when run from inetd. * Note that both of these initialization routines are optional. If you don't * need them (or only need one), simply set the function pointer to NULL * in the module structure. */ static int sample_init(void) { /* do something useful here, right? */ return 0; } static int sample_sess_init(void) { /* same here */ return 0; } /* Module API tables * * There are three tables which act as the "glue" between proftpd and * a module. None of the tables are _required_ (however having none would * make the module fairly useless). * * The first table is the configuration directive handler table. It specifies * handler routines in the module which will be used during configuration * file parsing. */ static conftable sample_conftab[] = { { "FooBarDirective", set_foobardirective, NULL }, { NULL } }; /* The command handler table: * first : command "type" (see the doc/API for more info) * * second : command "name", or the actual null-terminated ascii text * sent by a client (in uppercase) for this command. see * include/ftp.h for macros which define all rfced FTP protocol * commands. Can also be the special macro C_ANY, which receives * ALL commands. * * third : command "group" (used for access control via Limit directives), * this can be either G_DIRS (for commands related to directory * listing), G_READ (for commands related to reading files), * G_WRITE (for commands related to file writing), or the * special G_NONE for those commands against which the * special will not be applied. * * fourth : function pointer to your handler * * fifth : TRUE if the command cannot be used before authentication * (via USER/PASS), otherwise FALSE. * * sixth : TRUE if the command can be sent during a file transfer * (note: as of 1.1.5, this is obsolete) * */ static cmdtable sample_cmdtab[] = { { PRE_CMD, C_ANY, G_NONE, sample_pre_any, FALSE, FALSE }, { LOG_CMD, C_ANY, G_NONE, sample_log_any, FALSE, FALSE }, { POST_CMD, C_RETR, G_NONE, sample_post_retr, FALSE, FALSE }, { POST_CMD, C_STOR, G_NONE, sample_post_stor, FALSE, FALSE }, { POST_CMD, C_APPE, G_NONE, sample_post_stor, FALSE, FALSE }, { POST_CMD, C_LIST, G_NONE, sample_post_list, FALSE, FALSE }, { POST_CMD, C_NLST, G_NONE, sample_post_nlst, FALSE, FALSE }, { CMD, "XFOO", G_DIRS, sample_xfoo, TRUE, FALSE }, { 0, NULL } }; module sample_module = { /* Always NULL */ NULL, NULL, /* Module API version (2.0) */ 0x20, /* Module name */ "sample", /* Module configuration directive handlers */ sample_conftab, /* Module command handlers */ sample_cmdtab, /* Module authentication handlers (none in this case) */ NULL, /* Module initialization */ sample_init, /* Session initialization */ sample_sess_init, /* Module version */ MOD_SAMPLE_VERSION }; proftpd-dfsg-1.3.5~rc3/lib/0000755000175000017500000000000012156653653015327 5ustar frankiefrankieproftpd-dfsg-1.3.5~rc3/lib/vsnprintf.c0000644000175000017500000002310611566546322017524 0ustar frankiefrankie/* * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; see the file COPYING.LIB. If * not, write to the Free Software Foundation, Inc., 51 Franklin Street, * Suite 500, Boston, MA 02110-1335, USA. */ /* Required to tell conf.h not to include the standard ProFTPD * header files */ #define __PROFTPD_SUPPORT_LIBRARY #include #include #include #if !defined(HAVE_VSNPRINTF) || !defined(HAVE_SNPRINTF) # if defined(HAVE_FCONVERT) || defined(HAVE_FCVT) # ifdef HAVE_FLOATINGPOINT_H # include # endif # ifndef DECIMAL_STRING_LENGTH # define DECIMAL_STRING_LENGTH 512 # endif # endif /* HAVE_FCONVERT || HAVE_FCVT */ static size_t strnlen(const char *s, size_t count) { const char *sc; for(sc = s; count-- && *sc != '\0'; ++sc) ; return sc - s; } static int skip_atoi(const char **s) { int i = 0; while(isdigit(**s)) i = i * 10 + *((*s)++) - '0'; return i; } #define ZEROPAD 1 #define SIGN 2 #define PLUS 4 #define SPACE 8 #define LEFT 16 #define SPECIAL 32 #define LARGE 64 static char *number(char *str, long num, int base, int size, int precision, int type, size_t *max_size) { char c,sign,tmp[66] = {'\0'}; const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; int i; size_t msize; msize = *max_size; if(type & LARGE) digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; if(type & LEFT) type &= ~ZEROPAD; if(base < 2 || base > 36) return 0; c = (type & ZEROPAD) ? '0' : ' '; sign = 0; if(type & SIGN) { if(num < 0) { sign = '-'; num = -num; size--; } else if(type & PLUS) { sign = '+'; size--; } else if(type & SPACE) { sign = ' '; size--; } } if(type & SPECIAL) { if(base == 16) size -= 2; else if(base == 8) size--; } i = 0; if(num == 0) tmp[i++] = '0'; else while(num != 0) { tmp[i++] = digits[((unsigned long) num) % (unsigned) base]; num /= base; } if(i > precision) precision = i; size -= precision; if(!(type & (ZEROPAD+LEFT))) while(size-- > 0 && msize) { *str++ = ' '; msize--; } if(sign && msize) { *str++ = sign; msize--; } if(msize) { if(type & SPECIAL) { if(base == 8) { *str++ = '0'; msize--; } else if(base == 16) { *str++ = '0'; msize--; if(msize) { *str++ = digits[33]; msize--; } } } } if(!(type & LEFT)) while(size-- > 0 && msize) { *str++ = c; msize--; } while(i < precision-- && msize) { *str++ = '0'; msize--; } while(i-- > 0 && msize) { *str++ = tmp[i]; msize--; } while(size-- > 0 && msize) { *str++ = ' '; msize--; } *max_size = msize; return str; } #ifndef HAVE_VSNPRINTF /* ** This vsnprintf() emulation does not implement the conversions: ** %e, %E, %g, %G, %wc, %ws ** The %f implementation is limited. */ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) { int len; unsigned long num; int i, base; char *str; const char *s; int flags; int dotflag; int field_width; int precision; int qualifier; size--; for(str = buf; *fmt && size; ++fmt) { if(*fmt != '%') { *str++ = *fmt; size--; continue; } flags = 0; dotflag = 0; repeat: ++fmt; switch(*fmt) { case '-': flags |= LEFT; goto repeat; case '+': flags |= PLUS; goto repeat; case ' ': flags |= SPACE; goto repeat; case '#': flags |= SPECIAL; goto repeat; case '0': flags |= ZEROPAD; goto repeat; } field_width = -1; if(isdigit(*fmt)) field_width = skip_atoi(&fmt); else if(*fmt == '*') { ++fmt; field_width = va_arg(args,int); if(field_width < 0) { field_width = - field_width; flags |= LEFT; } } precision = -1; if(*fmt == '.') { dotflag++; ++fmt; if(isdigit(*fmt)) precision = skip_atoi(&fmt); else if(*fmt == '*') { ++fmt; precision = va_arg(args,int); } /* NB: the default precision value is conversion dependent */ } qualifier = -1; if(*fmt == 'h' || *fmt == 'l' || *fmt == 'L') { qualifier = *fmt; ++fmt; } base = 10; switch(*fmt) { case 'c': if(!(flags & LEFT)) while(--field_width > 0 && size) { *str++ = ' '; size--; } if(size) { *str++ = (unsigned char)va_arg(args,int); size--; } while(--field_width > 0 && size) { *str++ = ' '; size--; } continue; case 's': if ( dotflag && precision < 0 ) precision = 0; s = va_arg(args,char*); if(!s) s = "(null)"; len = strnlen(s, precision); if(!(flags & LEFT)) while(len < field_width-- && size) { *str++ = ' '; size--; } for(i = 0; i < len && size; ++i) { *str++ = *s++; size--; } while(len < field_width-- && size) { *str++ = ' '; size--; } continue; case 'p': if ( dotflag && precision < 0 ) precision = 0; if(field_width == -1) { field_width = 2 * sizeof(void*); flags |= ZEROPAD; } str = number(str, (unsigned long)va_arg(args,void*),16, field_width, precision, flags, &size); continue; case 'n': if(qualifier == 'l') { long *ip = va_arg(args,long*); *ip = (str - buf); } else { int *ip = va_arg(args,int*); *ip = (str - buf); } continue; case 'o': base = 8; break; case 'X': flags |= LARGE; case 'x': base = 16; break; case 'd': case 'i': flags |= SIGN; case 'u': break; # if defined(HAVE_FCONVERT) || defined(HAVE_FCVT) case 'f': { double dval; int ndigit, decpt, sign; char cvtbuf[DECIMAL_STRING_LENGTH] = {'\0'}; char *cbp; /* Default FP precision */ if ( dotflag && precision < 0 ) precision = 6; /* Let's not press our luck too far */ ndigit = precision < 16 ? precision : 16; dval = va_arg(args, double); /* ** If available fconvert() is preferred, but fcvt() is ** more widely available. It is included in 4.3BSD, ** the SUS1 and SUS2 standards, Gnu libc. */ # if defined(HAVE_FCONVERT) cbp = fconvert(dval, ndigit, &decpt, &sign, cvtbuf); # elif defined(HAVE_FCVT) cbp = fcvt(dval, ndigit, &decpt, &sign); sstrncpy(cvtbuf, cbp, sizeof cvtbuf); cbp = cvtbuf; # endif /* XXX Ought to honor field_width, left/right justification */ /* Result could be "NaN" or "Inf" */ if ( ! isdigit(*cbp) ) { for ( i = 0 ; *cbp != '\0' && size > 0 ; i++ ) { *str++ = *cbp++; size--; } continue; } if ( size > 0 ) { if ( sign ) { *str++ = '-'; size--; } else if ( flags & PLUS ) { *str++ = '+'; size--; } else if ( flags & SPACE ) { *str++ = ' '; size--; } } /* Leading zeros, if needed */ if ( decpt <= 0 && size > 0 ) { /* Prepend '0' */ *str++ = '0'; size--; } if ( decpt < 0 && size > 0 ) { /* Prepend '.' */ *str++ = '.'; size--; for ( i = decpt ; i < 0 && size > 0 ; i++ ) { *str++ = '0'; size--; } } /* Significant digits */ for ( i = 0 ; size > 0 ; i++ ) { if ( i == decpt ) { if ( *cbp != '\0' ) { *str++ = '.'; size--; if ( size <= 0 ) break; } else { /* Tack on "." or ".0"??? */ break; } } if ( *cbp != '\0' ) { *str++ = *cbp++; size--; } else if ( i < decpt ) { *str++ = '0'; size--; } else { /* Tack on "." or ".0"??? */ break; } } } continue; /* break; */ # endif /* HAVE_FCONVERT || HAVE_FCVT */ default: if(*fmt != '%') *str++ = '%'; if(*fmt && size) { *str++ = *fmt; size--; } else --fmt; continue; } if(qualifier == 'l') num = va_arg(args,unsigned long); else if(qualifier == 'h') { if(flags & SIGN) num = va_arg(args,short); else num = va_arg(args,unsigned short); } else if(flags & SIGN) num = va_arg(args,int); else num = va_arg(args, unsigned int); if ( dotflag && precision < 0 ) precision = 0; str = number(str,num,base,field_width,precision,flags,&size); } *str = '\0'; return str - buf; } #else /* HAVE_VSNPRINTF */ void pr_os_already_has_vsnprintf(void) { } #endif /* HAVE_VSNPRINTF */ #ifndef HAVE_SNPRINTF int snprintf(char *buf, size_t size, const char *fmt, ...) { va_list args; int i; va_start(args,fmt); i = vsnprintf(buf,size,fmt,args); va_end(args); return i; } #else /* HAVE_SNPRINTF */ void pr_os_already_has_snprintf(void) { } #endif /* HAVE_SNPRINTF */ #else /* !HAVE_VSNPRINTF || !HAVE_SNPRINTF */ void pr_os_already_has_snprintf_and_vsnprintf(void) { } #endif /* !HAVE_VSNPRINTF || !HAVE_SNPRINTF */ proftpd-dfsg-1.3.5~rc3/lib/pr_fnmatch.c0000644000175000017500000003245511745576245017631 0ustar frankiefrankie/* Copyright (C) 1991,1992,1993,1996,1997,1998,1999,2000,2001,2002,2003,2007 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. */ /* This file comes from the GNU C Library and has been modified for use in * ProFTPD. * * Changes are released under the GNU Public License, version 2. * Copyright (C) 2000 MacGyver aka Habeeb J. Dihu * Copyright (C) 2010-2012 The ProFTPD Project */ /* AIX requires this to be the first thing in the file. */ #if defined _AIX && !defined __GNUC__ #pragma alloca #endif #include /* Make alloca work the best possible way. */ #ifdef __GNUC__ #define alloca __builtin_alloca #else /* not __GNUC__ */ #if HAVE_ALLOCA_H #include #else /* not __GNUC__ or HAVE_ALLOCA_H */ #ifndef _AIX /* Already did AIX, up at the top. */ char *alloca (); #endif /* not _AIX */ #endif /* not HAVE_ALLOCA_H */ #endif /* not __GNUC__ */ /* Necessary for platforms which don't use __alloca. */ #define __alloca alloca /* Required to tell conf.h not to include the standard ProFTPD * header files */ #define __PROFTPD_SUPPORT_LIBRARY #include #include #if 0 /* Not used in ProFTPD */ /* Enable GNU extensions in fnmatch.h. */ #ifndef _GNU_SOURCE # define _GNU_SOURCE 1 #endif #include #include #include #include #if HAVE_STRING_H || defined _LIBC # include #else # include #endif #if defined STDC_HEADERS || defined _LIBC # include #endif /* For platform which support the ISO C amendement 1 functionality we support user defined character classes. */ #if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) /* Solaris 2.5 has a bug: must be included before . */ # include # include #endif /* We need some of the locale data (the collation sequence information) but there is no interface to get this information in general. Therefore we support a correct implementation only in glibc. */ #ifdef _LIBC # include "../locale/localeinfo.h" # include "../locale/elem-hash.h" # include "../locale/coll-lookup.h" # include # define CONCAT(a,b) __CONCAT(a,b) # define mbsrtowcs __mbsrtowcs # define fnmatch __fnmatch extern int fnmatch (const char *pattern, const char *string, int flags); #endif #endif /* Not used in ProFTPD */ /* We often have to test for FNM_FILE_NAME and FNM_PERIOD being both set. */ #define NO_LEADING_PERIOD(flags) \ ((flags & (PR_FNM_FILE_NAME | PR_FNM_PERIOD)) == (PR_FNM_FILE_NAME | PR_FNM_PERIOD)) /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ /* The comment above notwithstanding, we do want to use our own version to * ensure cross-platform compatibility...among other things. */ #undef _LIBC #undef __GNU_LIBRARY__ /* Provide an implementation of the gcc-specific __builtin_expect macro, * for the non-gcc compilers out there. */ #ifndef __builtin_expect # define __builtin_expect(e, n) (e) #endif /* __builtin_expect */ #if defined _LIBC || !defined __GNU_LIBRARY__ # if defined STDC_HEADERS || !defined isascii # define ISASCII(c) 1 # else # define ISASCII(c) isascii(c) # endif # ifdef isblank # define ISBLANK(c) (ISASCII (c) && isblank (c)) # else # define ISBLANK(c) ((c) == ' ' || (c) == '\t') # endif # ifdef isgraph # define ISGRAPH(c) (ISASCII (c) && isgraph (c)) # else # define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c)) # endif # define ISPRINT(c) (ISASCII (c) && isprint (c)) # define ISDIGIT(c) (ISASCII (c) && isdigit (c)) # define ISALNUM(c) (ISASCII (c) && isalnum (c)) # define ISALPHA(c) (ISASCII (c) && isalpha (c)) # define ISCNTRL(c) (ISASCII (c) && iscntrl (c)) # define ISLOWER(c) (ISASCII (c) && islower (c)) # define ISPUNCT(c) (ISASCII (c) && ispunct (c)) # define ISSPACE(c) (ISASCII (c) && isspace (c)) # define ISUPPER(c) (ISASCII (c) && isupper (c)) # define ISXDIGIT(c) (ISASCII (c) && isxdigit (c)) # define STREQ(s1, s2) ((strcmp (s1, s2) == 0)) # define HANDLE_MULTIBYTE 0 # if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) /* The GNU C library provides support for user-defined character classes and the functions from ISO C amendement 1. */ # ifdef CHARCLASS_NAME_MAX # define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX # else /* This shouldn't happen but some implementation might still have this problem. Use a reasonable default value. */ # define CHAR_CLASS_MAX_LENGTH 256 # endif # ifdef _LIBC # define IS_CHAR_CLASS(string) __wctype (string) # else # define IS_CHAR_CLASS(string) wctype (string) # endif # ifdef _LIBC # define ISWCTYPE(WC, WT) __iswctype (WC, WT) # else # define ISWCTYPE(WC, WT) iswctype (WC, WT) # endif # if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || _LIBC /* In this case we are implementing the multibyte character handling. */ # define HANDLE_MULTIBYTE 1 # endif # else # define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */ # define IS_CHAR_CLASS(string) \ (STREQ (string, "alpha") || STREQ (string, "upper") \ || STREQ (string, "lower") || STREQ (string, "digit") \ || STREQ (string, "alnum") || STREQ (string, "xdigit") \ || STREQ (string, "space") || STREQ (string, "print") \ || STREQ (string, "punct") || STREQ (string, "graph") \ || STREQ (string, "cntrl") || STREQ (string, "blank")) # endif /* Avoid depending on library functions or files whose names are inconsistent. */ # ifndef errno extern int errno; # endif /* Global variable. */ static int posixly_correct; # if HANDLE_MULTIBYTE && !defined HAVE___STRCHRNUL && !defined _LIBC static wchar_t * __wcschrnul (const wchar_t *s, wint_t c) { wchar_t *result = wcschr (s, c); if (result == NULL) result = wcschr (s, '\0'); return result; } # endif # ifndef internal_function /* Inside GNU libc we mark some function in a special way. In other environments simply ignore the marking. */ # define internal_function # endif /* Note that this evaluates C many times. */ # ifdef _LIBC # define FOLD(c) ((flags & PR_FNM_CASEFOLD) ? tolower (c) : (c)) # else # define FOLD(c) ((flags & PR_FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c)) # endif # define CHAR char # define UCHAR unsigned char # define INT int # define FCT internal_fnmatch # define EXT ext_match # define END end_pattern # define STRUCT fnmatch_struct # define L(CS) CS # ifdef _LIBC # define BTOWC(C) __btowc (C) # else # define BTOWC(C) btowc (C) # endif # define STRLEN(S) strlen (S) # define STRCAT(D, S) strcat (D, S) # define MEMPCPY(D, S, N) __mempcpy (D, S, N) # define MEMCHR(S, C, N) memchr (S, C, N) # define STRCOLL(S1, S2) strcoll (S1, S2) # include "pr_fnmatch_loop.c" # if HANDLE_MULTIBYTE /* Note that this evaluates C many times. */ # ifdef _LIBC # define FOLD(c) ((flags & PR_FNM_CASEFOLD) ? towlower (c) : (c)) # else # define FOLD(c) ((flags & PR_FNM_CASEFOLD) && ISUPPER (c) ? towlower (c) : (c)) # endif # define CHAR wchar_t # define UCHAR wint_t # define INT wint_t # define FCT internal_fnwmatch # define EXT ext_wmatch # define END end_wpattern # define STRUCT fnwmatch_struct # define L(CS) L##CS # define BTOWC(C) (C) # define STRLEN(S) __wcslen (S) # define STRCAT(D, S) __wcscat (D, S) # define MEMPCPY(D, S, N) __wmempcpy (D, S, N) # define MEMCHR(S, C, N) wmemchr (S, C, N) # define STRCOLL(S1, S2) wcscoll (S1, S2) # define WIDE_CHAR_VERSION 1 # undef IS_CHAR_CLASS /* We have to convert the wide character string in a multibyte string. But we know that the character class names consist of alphanumeric characters from the portable character set, and since the wide character encoding for a member of the portable character set is the same code point as its single-byte encoding, we can use a simplified method to convert the string to a multibyte character string. */ static wctype_t is_char_class (const wchar_t *wcs) { char s[CHAR_CLASS_MAX_LENGTH + 1]; char *cp = s; do { /* Test for a printable character from the portable character set. */ # ifdef _LIBC if (*wcs < 0x20 || *wcs > 0x7e || *wcs == 0x24 || *wcs == 0x40 || *wcs == 0x60) return (wctype_t) 0; # else switch (*wcs) { case L' ': case L'!': case L'"': case L'#': case L'%': case L'&': case L'\'': case L'(': case L')': case L'*': case L'+': case L',': case L'-': case L'.': case L'/': case L'0': case L'1': case L'2': case L'3': case L'4': case L'5': case L'6': case L'7': case L'8': case L'9': case L':': case L';': case L'<': case L'=': case L'>': case L'?': case L'A': case L'B': case L'C': case L'D': case L'E': case L'F': case L'G': case L'H': case L'I': case L'J': case L'K': case L'L': case L'M': case L'N': case L'O': case L'P': case L'Q': case L'R': case L'S': case L'T': case L'U': case L'V': case L'W': case L'X': case L'Y': case L'Z': case L'[': case L'\\': case L']': case L'^': case L'_': case L'a': case L'b': case L'c': case L'd': case L'e': case L'f': case L'g': case L'h': case L'i': case L'j': case L'k': case L'l': case L'm': case L'n': case L'o': case L'p': case L'q': case L'r': case L's': case L't': case L'u': case L'v': case L'w': case L'x': case L'y': case L'z': case L'{': case L'|': case L'}': case L'~': break; default: return (wctype_t) 0; } # endif /* Avoid overrunning the buffer. */ if (cp == s + CHAR_CLASS_MAX_LENGTH) return (wctype_t) 0; *cp++ = (char) *wcs++; } while (*wcs != L'\0'); *cp = '\0'; # ifdef _LIBC return __wctype (s); # else return wctype (s); # endif } # define IS_CHAR_CLASS(string) is_char_class (string) # include "pr_fnmatch_loop.c" # endif int pr_fnmatch (pattern, string, flags) const char *pattern; const char *string; int flags; { # if HANDLE_MULTIBYTE if (__builtin_expect (MB_CUR_MAX, 1) != 1) { mbstate_t ps; size_t n; const char *p; wchar_t *wpattern; wchar_t *wstring; /* Convert the strings into wide characters. */ memset (&ps, '\0', sizeof (ps)); p = pattern; #ifdef _LIBC n = strnlen (pattern, 1024); #else n = strlen (pattern); #endif if (__builtin_expect (n < 1024, 1)) { wpattern = (wchar_t *) __alloca ((n + 1) * sizeof (wchar_t)); n = mbsrtowcs (wpattern, &p, n + 1, &ps); if (__builtin_expect (n == (size_t) -1, 0)) /* Something wrong. XXX Do we have to set `errno' to something which mbsrtows hasn't already done? */ return -1; if (p) { memset (&ps, '\0', sizeof (ps)); goto prepare_wpattern; } } else { prepare_wpattern: n = mbsrtowcs (NULL, &pattern, 0, &ps); if (__builtin_expect (n == (size_t) -1, 0)) /* Something wrong. XXX Do we have to set `errno' to something which mbsrtows hasn't already done? */ return -1; wpattern = (wchar_t *) __alloca ((n + 1) * sizeof (wchar_t)); assert (mbsinit (&ps)); (void) mbsrtowcs (wpattern, &pattern, n + 1, &ps); } assert (mbsinit (&ps)); #ifdef _LIBC n = strnlen (string, 1024); #else n = strlen (string); #endif p = string; if (__builtin_expect (n < 1024, 1)) { wstring = (wchar_t *) __alloca ((n + 1) * sizeof (wchar_t)); n = mbsrtowcs (wstring, &p, n + 1, &ps); if (__builtin_expect (n == (size_t) -1, 0)) /* Something wrong. XXX Do we have to set `errno' to something which mbsrtows hasn't already done? */ return -1; if (p) { memset (&ps, '\0', sizeof (ps)); goto prepare_wstring; } } else { prepare_wstring: n = mbsrtowcs (NULL, &string, 0, &ps); if (__builtin_expect (n == (size_t) -1, 0)) /* Something wrong. XXX Do we have to set `errno' to something which mbsrtows hasn't already done? */ return -1; wstring = (wchar_t *) __alloca ((n + 1) * sizeof (wchar_t)); assert (mbsinit (&ps)); (void) mbsrtowcs (wstring, &string, n + 1, &ps); } return internal_fnwmatch (wpattern, wstring, wstring + n, flags & PR_FNM_PERIOD, flags, NULL); } # endif /* mbstate_t and mbsrtowcs or _LIBC. */ return internal_fnmatch (pattern, string, string + strlen (string), flags & PR_FNM_PERIOD, flags, NULL); } #endif /* _LIBC or not __GNU_LIBRARY__. */ proftpd-dfsg-1.3.5~rc3/lib/tpl.c0000755000175000017500000027051311767655736016320 0ustar frankiefrankie/* Copyright (c) 2005-2010, Troy D. Hanson http://tpl.sourceforge.net All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #define TPL_VERSION 1.5 static const char id[]="$Id: tpl.c,v 1.4 2012/06/18 16:48:30 castaglia Exp $"; #include /* malloc */ #include /* va_list */ #include /* memcpy, memset, strchr */ #include /* printf (tpl_hook.oops default function) */ #ifndef _WIN32 #include /* for ftruncate */ #else #include #define ftruncate(x,y) _chsize(x,y) #endif #include /* for 'open' */ #include /* for 'open' */ #include /* for 'open' */ #include #ifndef _WIN32 #include /* uint32_t, uint64_t, etc */ #else typedef unsigned short ushort; typedef __int16 int16_t; typedef __int32 int32_t; typedef __int64 int64_t; typedef unsigned __int16 uint16_t; typedef unsigned __int32 uint32_t; typedef unsigned __int64 uint64_t; #endif #if ( defined __MINGW32__ || defined _WIN32 ) #include "win/mman.h" /* mmap */ #else #include /* mmap */ #endif #include "tpl.h" #define TPL_GATHER_BUFLEN 8192 #define TPL_MAGIC "tpl" /* macro to add a structure to a doubly-linked list */ #define DL_ADD(head,add) \ do { \ if (head) { \ (add)->prev = (head)->prev; \ (head)->prev->next = (add); \ (head)->prev = (add); \ (add)->next = NULL; \ } else { \ (head)=(add); \ (head)->prev = (head); \ (head)->next = NULL; \ } \ } while (0); #define fatal_oom() tpl_hook.fatal("out of memory\n") /* bit flags (internal). preceded by the external flags in tpl.h */ #define TPL_WRONLY (1 << 9) /* app has initiated tpl packing */ #define TPL_RDONLY (1 << 10) /* tpl was loaded (for unpacking) */ #define TPL_XENDIAN (1 << 11) /* swap endianness when unpacking */ #define TPL_OLD_STRING_FMT (1 << 12) /* tpl has strings in 1.2 format */ /* values for the flags byte that appears after the magic prefix */ #define TPL_SUPPORTED_BITFLAGS 3 #define TPL_FL_BIGENDIAN (1 << 0) #define TPL_FL_NULLSTRINGS (1 << 1) /* char values for node type */ #define TPL_TYPE_ROOT 0 #define TPL_TYPE_INT32 1 #define TPL_TYPE_UINT32 2 #define TPL_TYPE_BYTE 3 #define TPL_TYPE_STR 4 #define TPL_TYPE_ARY 5 #define TPL_TYPE_BIN 6 #define TPL_TYPE_DOUBLE 7 #define TPL_TYPE_INT64 8 #define TPL_TYPE_UINT64 9 #define TPL_TYPE_INT16 10 #define TPL_TYPE_UINT16 11 #define TPL_TYPE_POUND 12 /* error codes */ #define ERR_NOT_MINSIZE (-1) #define ERR_MAGIC_MISMATCH (-2) #define ERR_INCONSISTENT_SZ (-3) #define ERR_FMT_INVALID (-4) #define ERR_FMT_MISSING_NUL (-5) #define ERR_FMT_MISMATCH (-6) #define ERR_FLEN_MISMATCH (-7) #define ERR_INCONSISTENT_SZ2 (-8) #define ERR_INCONSISTENT_SZ3 (-9) #define ERR_INCONSISTENT_SZ4 (-10) #define ERR_UNSUPPORTED_FLAGS (-11) /* access to A(...) nodes by index */ typedef struct tpl_pidx { struct tpl_node *node; struct tpl_pidx *next,*prev; } tpl_pidx; /* A(...) node datum */ typedef struct tpl_atyp { uint32_t num; /* num elements */ size_t sz; /* size of each backbone's datum */ struct tpl_backbone *bb,*bbtail; void *cur; } tpl_atyp; /* backbone to extend A(...) lists dynamically */ typedef struct tpl_backbone { struct tpl_backbone *next; /* when this structure is malloc'd, extra space is alloc'd at the * end to store the backbone "datum", and data points to it. */ #if defined(__STDC_VERSION__) && __STDC_VERSION__ < 199901 char *data; #else char data[]; #endif } tpl_backbone; /* mmap record */ typedef struct tpl_mmap_rec { int fd; void *text; size_t text_sz; } tpl_mmap_rec; /* root node datum */ typedef struct tpl_root_data { int flags; tpl_pidx *pidx; tpl_mmap_rec mmap; char *fmt; int *fxlens, num_fxlens; } tpl_root_data; /* node type to size mapping */ struct tpl_type_t { char c; int sz; }; /* Internal prototypes */ static tpl_node *tpl_node_new(tpl_node *parent); static tpl_node *tpl_find_i(tpl_node *n, int i); static void *tpl_cpv(void *datav, void *data, size_t sz); static void *tpl_extend_backbone(tpl_node *n); static char *tpl_fmt(tpl_node *r); static void *tpl_dump_atyp(tpl_node *n, tpl_atyp* at, void *dv); static size_t tpl_ser_osz(tpl_node *n); static void tpl_free_atyp(tpl_node *n,tpl_atyp *atyp); static int tpl_dump_to_mem(tpl_node *r, void *addr, size_t sz); static int tpl_mmap_file(char *filename, tpl_mmap_rec *map_rec); static int tpl_mmap_output_file(char *filename, size_t sz, void **text_out); static int tpl_cpu_bigendian(void); static int tpl_needs_endian_swap(void *); static void tpl_byteswap(void *word, int len); static void tpl_fatal(char *fmt, ...); static int tpl_serlen(tpl_node *r, tpl_node *n, void *dv, size_t *serlen); static int tpl_unpackA0(tpl_node *r); static int tpl_oops(const char *fmt, ...); static int tpl_gather_mem( char *buf, size_t len, tpl_gather_t **gs, tpl_gather_cb *cb, void *data); static int tpl_gather_nonblocking( int fd, tpl_gather_t **gs, tpl_gather_cb *cb, void *data); static int tpl_gather_blocking(int fd, void **img, size_t *sz); static tpl_node *tpl_map_va(char *fmt, va_list ap); /* This is used internally to help calculate padding when a 'double' * follows a smaller datatype in a structure. Normally under gcc * on x86, d will be aligned at +4, however use of -malign-double * causes d to be aligned at +8 (this is actually faster on x86). * Also SPARC and x86_64 seem to align always on +8. */ struct tpl_double_alignment_detector { char a; double d; /* some platforms align this on +4, others on +8 */ }; /* this is another case where alignment varies. mac os x/gcc was observed * to align the int64_t at +4 under -m32 and at +8 under -m64 */ struct tpl_int64_alignment_detector { int i; int64_t j; /* some platforms align this on +4, others on +8 */ }; typedef struct { size_t inter_elt_len; /* padded inter-element len; i.e. &a[1].field - &a[0].field */ tpl_node *iter_start_node; /* node to jump back to, as we start each new iteration */ size_t iternum; /* current iteration number (total req'd. iter's in n->num) */ } tpl_pound_data; /* Hooks for customizing tpl mem alloc, error handling, etc. Set defaults. */ tpl_hook_t tpl_hook = { /* .oops = */ tpl_oops, /* .malloc = */ malloc, /* .realloc = */ realloc, /* .free = */ free, /* .fatal = */ tpl_fatal, /* .gather_max = */ 0 /* max tpl size (bytes) for tpl_gather */ }; static const char tpl_fmt_chars[] = "AS($)BiucsfIUjv#"; /* valid format chars */ static const char tpl_S_fmt_chars[] = "iucsfIUjv#$()"; /* valid within S(...) */ static const char tpl_datapeek_ok_chars[] = "iucsfIUjv"; /* valid in datapeek */ static const struct tpl_type_t tpl_types[] = { /* [TPL_TYPE_ROOT] = */ {'r', 0}, /* [TPL_TYPE_INT32] = */ {'i', sizeof(int32_t)}, /* [TPL_TYPE_UINT32] = */ {'u', sizeof(uint32_t)}, /* [TPL_TYPE_BYTE] = */ {'c', sizeof(char)}, /* [TPL_TYPE_STR] = */ {'s', sizeof(char*)}, /* [TPL_TYPE_ARY] = */ {'A', 0}, /* [TPL_TYPE_BIN] = */ {'B', 0}, /* [TPL_TYPE_DOUBLE] = */ {'f', 8}, /* not sizeof(double) as that varies */ /* [TPL_TYPE_INT64] = */ {'I', sizeof(int64_t)}, /* [TPL_TYPE_UINT64] = */ {'U', sizeof(uint64_t)}, /* [TPL_TYPE_INT16] = */ {'j', sizeof(int16_t)}, /* [TPL_TYPE_UINT16] = */ {'v', sizeof(uint16_t)}, /* [TPL_TYPE_POUND] = */ {'#', 0}, }; /* default error-reporting function. Just writes to stderr. */ static int tpl_oops(const char *fmt, ...) { va_list ap; va_start(ap,fmt); vfprintf(stderr,fmt,ap); va_end(ap); return 0; } static tpl_node *tpl_node_new(tpl_node *parent) { tpl_node *n; if ((n=tpl_hook.malloc(sizeof(tpl_node))) == NULL) { fatal_oom(); } n->addr=NULL; n->data=NULL; n->num=1; n->ser_osz=0; n->children=NULL; n->next=NULL; n->parent=parent; return n; } /* Used in S(..) formats to pack several fields from a structure based on * only the structure address. We need to calculate field addresses * manually taking into account the size of the fields and intervening padding. * The wrinkle is that double is not normally aligned on x86-32 but the * -malign-double compiler option causes it to be. Double are aligned * on Sparc, and apparently on 64 bit x86. We use a helper structure * to detect whether double is aligned in this compilation environment. */ static char *calc_field_addr(tpl_node *parent, int type,char *struct_addr, int ordinal) { tpl_node *prev; int offset; int align_sz; if (ordinal == 1) return struct_addr; /* first field starts on structure address */ /* generate enough padding so field addr is divisible by it's align_sz. 4, 8, etc */ prev = parent->children->prev; switch(type) { case TPL_TYPE_DOUBLE: align_sz = sizeof(struct tpl_double_alignment_detector) > 12 ? 8 : 4; break; case TPL_TYPE_INT64: case TPL_TYPE_UINT64: align_sz = sizeof(struct tpl_int64_alignment_detector) > 12 ? 8 : 4; break; default: align_sz = tpl_types[type].sz; break; } offset = ((uintptr_t)prev->addr - (uintptr_t)struct_addr) + (tpl_types[prev->type].sz * prev->num); offset = (offset + align_sz - 1) / align_sz * align_sz; return struct_addr + offset; } TPL_API tpl_node *tpl_map(char *fmt,...) { va_list ap; tpl_node *tn; va_start(ap,fmt); tn = tpl_map_va(fmt, ap); va_end(ap); return tn; } static tpl_node *tpl_map_va(char *fmt, va_list ap) { int lparen_level=0,expect_lparen=0,t=0,in_structure=0,ordinal=0; int in_nested_structure=0; char *c, *peek, *struct_addr=NULL, *struct_next; tpl_node *root,*parent,*n=NULL,*preceding,*iter_start_node=NULL, *struct_widest_node=NULL, *np; tpl_pidx *pidx; tpl_pound_data *pd; int *fxlens, num_fxlens, pound_num, pound_prod, applies_to_struct; int contig_fxlens[10]; /* temp space for contiguous fxlens */ int num_contig_fxlens, i, j; ptrdiff_t inter_elt_len=0; /* padded element length of contiguous structs in array */ root = tpl_node_new(NULL); root->type = TPL_TYPE_ROOT; root->data = (tpl_root_data*)tpl_hook.malloc(sizeof(tpl_root_data)); if (!root->data) fatal_oom(); memset((tpl_root_data*)root->data,0,sizeof(tpl_root_data)); /* set up root nodes special ser_osz to reflect overhead of preamble */ root->ser_osz = sizeof(uint32_t); /* tpl leading length */ root->ser_osz += strlen(fmt) + 1; /* fmt + NUL-terminator */ root->ser_osz += 4; /* 'tpl' magic prefix + flags byte */ parent=root; c=fmt; while (*c != '\0') { switch (*c) { case 'c': case 'i': case 'u': case 'j': case 'v': case 'I': case 'U': case 'f': if (*c=='c') t=TPL_TYPE_BYTE; else if (*c=='i') t=TPL_TYPE_INT32; else if (*c=='u') t=TPL_TYPE_UINT32; else if (*c=='j') t=TPL_TYPE_INT16; else if (*c=='v') t=TPL_TYPE_UINT16; else if (*c=='I') t=TPL_TYPE_INT64; else if (*c=='U') t=TPL_TYPE_UINT64; else if (*c=='f') t=TPL_TYPE_DOUBLE; if (expect_lparen) goto fail; n = tpl_node_new(parent); n->type = t; if (in_structure) { if (ordinal == 1) { /* for S(...)# iteration. Apply any changes to case 's' too!!! */ iter_start_node = n; struct_widest_node = n; } if (tpl_types[n->type].sz > tpl_types[struct_widest_node->type].sz) { struct_widest_node = n; } n->addr = calc_field_addr(parent,n->type,struct_addr,ordinal++); } else n->addr = (void*)va_arg(ap,void*); n->data = tpl_hook.malloc(tpl_types[t].sz); if (!n->data) fatal_oom(); if (n->parent->type == TPL_TYPE_ARY) ((tpl_atyp*)(n->parent->data))->sz += tpl_types[t].sz; DL_ADD(parent->children,n); break; case 's': if (expect_lparen) goto fail; n = tpl_node_new(parent); n->type = TPL_TYPE_STR; if (in_structure) { if (ordinal == 1) { iter_start_node = n; /* for S(...)# iteration */ struct_widest_node = n; } if (tpl_types[n->type].sz > tpl_types[struct_widest_node->type].sz) { struct_widest_node = n; } n->addr = calc_field_addr(parent,n->type,struct_addr,ordinal++); } else n->addr = (void*)va_arg(ap,void*); n->data = tpl_hook.malloc(sizeof(char*)); if (!n->data) fatal_oom(); *(char**)(n->data) = NULL; if (n->parent->type == TPL_TYPE_ARY) ((tpl_atyp*)(n->parent->data))->sz += sizeof(void*); DL_ADD(parent->children,n); break; case '#': /* apply a 'num' to preceding atom */ if (!parent->children) goto fail; preceding = parent->children->prev; /* first child's prev is 'last child'*/ t = preceding->type; applies_to_struct = (*(c-1) == ')') ? 1 : 0; if (!applies_to_struct) { if (!(t == TPL_TYPE_BYTE || t == TPL_TYPE_INT32 || t == TPL_TYPE_UINT32 || t == TPL_TYPE_DOUBLE || t == TPL_TYPE_UINT64 || t == TPL_TYPE_INT64 || t == TPL_TYPE_UINT16 || t == TPL_TYPE_INT16 || t == TPL_TYPE_STR )) goto fail; } /* count up how many contiguous # and form their product */ pound_prod=1; num_contig_fxlens=0; for(peek=c; *peek == '#'; peek++) { pound_num = va_arg(ap, int); if (pound_num < 1) { tpl_hook.fatal("non-positive iteration count %d\n", pound_num); } if (num_contig_fxlens >= (sizeof(contig_fxlens)/sizeof(contig_fxlens[0]))) { tpl_hook.fatal("contiguous # exceeds hardcoded limit\n"); } contig_fxlens[num_contig_fxlens++] = pound_num; pound_prod *= pound_num; } /* increment c to skip contiguous # so its points to last one */ c = peek-1; /* differentiate atom-# from struct-# by noting preceding rparen */ if (applies_to_struct) { /* insert # node to induce looping */ n = tpl_node_new(parent); n->type = TPL_TYPE_POUND; n->num = pound_prod; n->data = tpl_hook.malloc(sizeof(tpl_pound_data)); if (!n->data) fatal_oom(); pd = (tpl_pound_data*)n->data; pd->inter_elt_len = inter_elt_len; pd->iter_start_node = iter_start_node; pd->iternum = 0; DL_ADD(parent->children,n); /* multiply the 'num' and data space on each atom in the structure */ for(np = iter_start_node; np != n; np = np->next) { if (n->parent->type == TPL_TYPE_ARY) { ((tpl_atyp*)(n->parent->data))->sz += tpl_types[np->type].sz * (np->num * (n->num - 1)); } np->data = tpl_hook.realloc(np->data, tpl_types[np->type].sz * np->num * n->num); if (!np->data) fatal_oom(); memset(np->data, 0, tpl_types[np->type].sz * np->num * n->num); } } else { /* simple atom-# form does not require a loop */ preceding->num = pound_prod; preceding->data = tpl_hook.realloc(preceding->data, tpl_types[t].sz * preceding->num); if (!preceding->data) fatal_oom(); memset(preceding->data,0,tpl_types[t].sz * preceding->num); if (n->parent->type == TPL_TYPE_ARY) { ((tpl_atyp*)(n->parent->data))->sz += tpl_types[t].sz * (preceding->num-1); } } root->ser_osz += (sizeof(uint32_t) * num_contig_fxlens); j = ((tpl_root_data*)root->data)->num_fxlens; /* before incrementing */ (((tpl_root_data*)root->data)->num_fxlens) += num_contig_fxlens; num_fxlens = ((tpl_root_data*)root->data)->num_fxlens; /* new value */ fxlens = ((tpl_root_data*)root->data)->fxlens; fxlens = tpl_hook.realloc(fxlens, sizeof(int) * num_fxlens); if (!fxlens) fatal_oom(); ((tpl_root_data*)root->data)->fxlens = fxlens; for(i=0; i < num_contig_fxlens; i++) fxlens[j++] = contig_fxlens[i]; break; case 'B': if (expect_lparen) goto fail; if (in_structure) goto fail; n = tpl_node_new(parent); n->type = TPL_TYPE_BIN; n->addr = (tpl_bin*)va_arg(ap,void*); n->data = tpl_hook.malloc(sizeof(tpl_bin*)); if (!n->data) fatal_oom(); *((tpl_bin**)n->data) = NULL; if (n->parent->type == TPL_TYPE_ARY) ((tpl_atyp*)(n->parent->data))->sz += sizeof(tpl_bin); DL_ADD(parent->children,n); break; case 'A': if (in_structure) goto fail; n = tpl_node_new(parent); n->type = TPL_TYPE_ARY; DL_ADD(parent->children,n); parent = n; expect_lparen=1; pidx = (tpl_pidx*)tpl_hook.malloc(sizeof(tpl_pidx)); if (!pidx) fatal_oom(); pidx->node = n; pidx->next = NULL; DL_ADD(((tpl_root_data*)(root->data))->pidx,pidx); /* set up the A's tpl_atyp */ n->data = (tpl_atyp*)tpl_hook.malloc(sizeof(tpl_atyp)); if (!n->data) fatal_oom(); ((tpl_atyp*)(n->data))->num = 0; ((tpl_atyp*)(n->data))->sz = 0; ((tpl_atyp*)(n->data))->bb = NULL; ((tpl_atyp*)(n->data))->bbtail = NULL; ((tpl_atyp*)(n->data))->cur = NULL; if (n->parent->type == TPL_TYPE_ARY) ((tpl_atyp*)(n->parent->data))->sz += sizeof(void*); break; case 'S': if (in_structure) goto fail; expect_lparen=1; ordinal=1; /* index upcoming atoms in S(..) */ in_structure=1+lparen_level; /* so we can tell where S fmt ends */ struct_addr = (char*)va_arg(ap,void*); break; case '$': /* nested structure */ if (!in_structure) goto fail; expect_lparen=1; in_nested_structure++; break; case ')': lparen_level--; if (lparen_level < 0) goto fail; if (*(c-1) == '(') goto fail; if (in_nested_structure) in_nested_structure--; else if (in_structure && (in_structure-1 == lparen_level)) { /* calculate delta between contiguous structures in array */ struct_next = calc_field_addr(parent, struct_widest_node->type, struct_addr, ordinal++); inter_elt_len = struct_next - struct_addr; in_structure=0; } else parent = parent->parent; /* rparen ends A() type, not S() type */ break; case '(': if (!expect_lparen) goto fail; expect_lparen=0; lparen_level++; break; default: tpl_hook.oops("unsupported option %c\n", *c); goto fail; } c++; } if (lparen_level != 0) goto fail; /* copy the format string, save for convenience */ ((tpl_root_data*)(root->data))->fmt = tpl_hook.malloc(strlen(fmt)+1); if (((tpl_root_data*)(root->data))->fmt == NULL) fatal_oom(); memcpy(((tpl_root_data*)(root->data))->fmt,fmt,strlen(fmt)+1); return root; fail: tpl_hook.oops("failed to parse %s\n", fmt); tpl_free(root); return NULL; } static int tpl_unmap_file( tpl_mmap_rec *mr) { if ( munmap( mr->text, mr->text_sz ) == -1 ) { tpl_hook.oops("Failed to munmap: %s\n", strerror(errno)); } close(mr->fd); mr->text = NULL; mr->text_sz = 0; return 0; } static void tpl_free_keep_map(tpl_node *r) { int mmap_bits = (TPL_RDONLY|TPL_FILE); int ufree_bits = (TPL_MEM|TPL_UFREE); tpl_node *nxtc,*c; int find_next_node=0,looking,i; size_t sz; /* For mmap'd files, or for 'ufree' memory images , do appropriate release */ if ((((tpl_root_data*)(r->data))->flags & mmap_bits) == mmap_bits) { tpl_unmap_file( &((tpl_root_data*)(r->data))->mmap); } else if ((((tpl_root_data*)(r->data))->flags & ufree_bits) == ufree_bits) { tpl_hook.free( ((tpl_root_data*)(r->data))->mmap.text ); } c = r->children; if (c) { while(c->type != TPL_TYPE_ROOT) { /* loop until we come back to root node */ switch (c->type) { case TPL_TYPE_BIN: /* free any binary buffer hanging from tpl_bin */ if ( *((tpl_bin**)(c->data)) ) { if ( (*((tpl_bin**)(c->data)))->addr ) { tpl_hook.free( (*((tpl_bin**)(c->data)))->addr ); } *((tpl_bin**)c->data) = NULL; /* reset tpl_bin */ } find_next_node=1; break; case TPL_TYPE_STR: /* free any packed (copied) string */ for(i=0; i < c->num; i++) { char *str = ((char**)c->data)[i]; if (str) { tpl_hook.free(str); ((char**)c->data)[i] = NULL; } } find_next_node=1; break; case TPL_TYPE_INT32: case TPL_TYPE_UINT32: case TPL_TYPE_INT64: case TPL_TYPE_UINT64: case TPL_TYPE_BYTE: case TPL_TYPE_DOUBLE: case TPL_TYPE_INT16: case TPL_TYPE_UINT16: case TPL_TYPE_POUND: find_next_node=1; break; case TPL_TYPE_ARY: c->ser_osz = 0; /* zero out the serialization output size */ sz = ((tpl_atyp*)(c->data))->sz; /* save sz to use below */ tpl_free_atyp(c,c->data); /* make new atyp */ c->data = (tpl_atyp*)tpl_hook.malloc(sizeof(tpl_atyp)); if (!c->data) fatal_oom(); ((tpl_atyp*)(c->data))->num = 0; ((tpl_atyp*)(c->data))->sz = sz; /* restore bb datum sz */ ((tpl_atyp*)(c->data))->bb = NULL; ((tpl_atyp*)(c->data))->bbtail = NULL; ((tpl_atyp*)(c->data))->cur = NULL; c = c->children; break; default: tpl_hook.fatal("unsupported format character\n"); break; } if (find_next_node) { find_next_node=0; looking=1; while(looking) { if (c->next) { nxtc=c->next; c=nxtc; looking=0; } else { if (c->type == TPL_TYPE_ROOT) break; /* root node */ else { nxtc=c->parent; c=nxtc; } } } } } } ((tpl_root_data*)(r->data))->flags = 0; /* reset flags */ } TPL_API void tpl_free(tpl_node *r) { int mmap_bits = (TPL_RDONLY|TPL_FILE); int ufree_bits = (TPL_MEM|TPL_UFREE); tpl_node *nxtc,*c; int find_next_node=0,looking,i; tpl_pidx *pidx,*pidx_nxt; /* For mmap'd files, or for 'ufree' memory images , do appropriate release */ if ((((tpl_root_data*)(r->data))->flags & mmap_bits) == mmap_bits) { tpl_unmap_file( &((tpl_root_data*)(r->data))->mmap); } else if ((((tpl_root_data*)(r->data))->flags & ufree_bits) == ufree_bits) { tpl_hook.free( ((tpl_root_data*)(r->data))->mmap.text ); } c = r->children; if (c) { while(c->type != TPL_TYPE_ROOT) { /* loop until we come back to root node */ switch (c->type) { case TPL_TYPE_BIN: /* free any binary buffer hanging from tpl_bin */ if ( *((tpl_bin**)(c->data)) ) { if ( (*((tpl_bin**)(c->data)))->sz != 0 ) { tpl_hook.free( (*((tpl_bin**)(c->data)))->addr ); } tpl_hook.free(*((tpl_bin**)c->data)); /* free tpl_bin */ } tpl_hook.free(c->data); /* free tpl_bin* */ find_next_node=1; break; case TPL_TYPE_STR: /* free any packed (copied) string */ for(i=0; i < c->num; i++) { char *str = ((char**)c->data)[i]; if (str) { tpl_hook.free(str); ((char**)c->data)[i] = NULL; } } tpl_hook.free(c->data); find_next_node=1; break; case TPL_TYPE_INT32: case TPL_TYPE_UINT32: case TPL_TYPE_INT64: case TPL_TYPE_UINT64: case TPL_TYPE_BYTE: case TPL_TYPE_DOUBLE: case TPL_TYPE_INT16: case TPL_TYPE_UINT16: case TPL_TYPE_POUND: tpl_hook.free(c->data); find_next_node=1; break; case TPL_TYPE_ARY: tpl_free_atyp(c,c->data); if (c->children) c = c->children; /* normal case */ else find_next_node=1; /* edge case, handle bad format A() */ break; default: tpl_hook.fatal("unsupported format character\n"); break; } if (find_next_node) { find_next_node=0; looking=1; while(looking) { if (c->next) { nxtc=c->next; tpl_hook.free(c); c=nxtc; looking=0; } else { if (c->type == TPL_TYPE_ROOT) break; /* root node */ else { nxtc=c->parent; tpl_hook.free(c); c=nxtc; } } } } } } /* free root */ for(pidx=((tpl_root_data*)(r->data))->pidx; pidx; pidx=pidx_nxt) { pidx_nxt = pidx->next; tpl_hook.free(pidx); } tpl_hook.free(((tpl_root_data*)(r->data))->fmt); if (((tpl_root_data*)(r->data))->num_fxlens > 0) { tpl_hook.free(((tpl_root_data*)(r->data))->fxlens); } tpl_hook.free(r->data); /* tpl_root_data */ tpl_hook.free(r); } /* Find the i'th packable ('A' node) */ static tpl_node *tpl_find_i(tpl_node *n, int i) { int j=0; tpl_pidx *pidx; if (n->type != TPL_TYPE_ROOT) return NULL; if (i == 0) return n; /* packable 0 is root */ for(pidx=((tpl_root_data*)(n->data))->pidx; pidx; pidx=pidx->next) { if (++j == i) return pidx->node; } return NULL; } static void *tpl_cpv(void *datav, void *data, size_t sz) { if (sz>0) memcpy(datav,data,sz); return (void*)((uintptr_t)datav + sz); } static void *tpl_extend_backbone(tpl_node *n) { tpl_backbone *bb; bb = (tpl_backbone*)tpl_hook.malloc(sizeof(tpl_backbone) + ((tpl_atyp*)(n->data))->sz ); /* datum hangs on coattails of bb */ if (!bb) fatal_oom(); #if defined(__STDC_VERSION__) && __STDC_VERSION__ < 199901 bb->data = (char*)((uintptr_t)bb + sizeof(tpl_backbone)); #endif memset(bb->data,0,((tpl_atyp*)(n->data))->sz); bb->next = NULL; /* Add the new backbone to the tail, also setting head if necessary */ if (((tpl_atyp*)(n->data))->bb == NULL) { ((tpl_atyp*)(n->data))->bb = bb; ((tpl_atyp*)(n->data))->bbtail = bb; } else { ((tpl_atyp*)(n->data))->bbtail->next = bb; ((tpl_atyp*)(n->data))->bbtail = bb; } ((tpl_atyp*)(n->data))->num++; return bb->data; } /* Get the format string corresponding to a given tpl (root node) */ static char *tpl_fmt(tpl_node *r) { return ((tpl_root_data*)(r->data))->fmt; } /* Get the fmt # lengths as a contiguous buffer of ints (length num_fxlens) */ static int *tpl_fxlens(tpl_node *r, int *num_fxlens) { *num_fxlens = ((tpl_root_data*)(r->data))->num_fxlens; return ((tpl_root_data*)(r->data))->fxlens; } /* called when serializing an 'A' type node into a buffer which has * already been set up with the proper space. The backbone is walked * which was obtained from the tpl_atyp header passed in. */ static void *tpl_dump_atyp(tpl_node *n, tpl_atyp* at, void *dv) { tpl_backbone *bb; tpl_node *c; void *datav; uint32_t slen; tpl_bin *binp; char *strp; tpl_atyp *atypp; tpl_pound_data *pd; int i; size_t itermax; /* handle 'A' nodes */ dv = tpl_cpv(dv,&at->num,sizeof(uint32_t)); /* array len */ for(bb=at->bb; bb; bb=bb->next) { datav = bb->data; c=n->children; while(c) { switch (c->type) { case TPL_TYPE_BYTE: case TPL_TYPE_DOUBLE: case TPL_TYPE_INT32: case TPL_TYPE_UINT32: case TPL_TYPE_INT64: case TPL_TYPE_UINT64: case TPL_TYPE_INT16: case TPL_TYPE_UINT16: dv = tpl_cpv(dv,datav,tpl_types[c->type].sz * c->num); datav = (void*)((uintptr_t)datav + tpl_types[c->type].sz * c->num); break; case TPL_TYPE_BIN: /* dump the buffer length followed by the buffer */ memcpy(&binp,datav,sizeof(tpl_bin*)); /* cp to aligned */ slen = binp->sz; dv = tpl_cpv(dv,&slen,sizeof(uint32_t)); dv = tpl_cpv(dv,binp->addr,slen); datav = (void*)((uintptr_t)datav + sizeof(tpl_bin*)); break; case TPL_TYPE_STR: /* dump the string length followed by the string */ for(i=0; i < c->num; i++) { memcpy(&strp,datav,sizeof(char*)); /* cp to aligned */ slen = strp ? (strlen(strp)+1) : 0; dv = tpl_cpv(dv,&slen,sizeof(uint32_t)); if (slen > 1) dv = tpl_cpv(dv,strp,slen-1); datav = (void*)((uintptr_t)datav + sizeof(char*)); } break; case TPL_TYPE_ARY: memcpy(&atypp,datav,sizeof(tpl_atyp*)); /* cp to aligned */ dv = tpl_dump_atyp(c,atypp,dv); datav = (void*)((uintptr_t)datav + sizeof(void*)); break; case TPL_TYPE_POUND: /* iterate over the preceding nodes */ pd = (tpl_pound_data*)c->data; itermax = c->num; if (++(pd->iternum) < itermax) { c = pd->iter_start_node; continue; } else { /* loop complete. */ pd->iternum = 0; } break; default: tpl_hook.fatal("unsupported format character\n"); break; } c=c->next; } } return dv; } /* figure the serialization output size needed for tpl whose root is n*/ static size_t tpl_ser_osz(tpl_node *n) { tpl_node *c, *np; size_t sz, itermax; tpl_bin *binp; char *strp; tpl_pound_data *pd; int i; /* handle the root node ONLY (subtree's ser_osz have been bubbled-up) */ if (n->type != TPL_TYPE_ROOT) { tpl_hook.fatal("internal error: tpl_ser_osz on non-root node\n"); } sz = n->ser_osz; /* start with fixed overhead, already stored */ c=n->children; while (c) { switch (c->type) { case TPL_TYPE_BYTE: case TPL_TYPE_DOUBLE: case TPL_TYPE_INT32: case TPL_TYPE_UINT32: case TPL_TYPE_INT64: case TPL_TYPE_UINT64: case TPL_TYPE_INT16: case TPL_TYPE_UINT16: sz += tpl_types[c->type].sz * c->num; break; case TPL_TYPE_BIN: sz += sizeof(uint32_t); /* binary buf len */ memcpy(&binp,c->data,sizeof(tpl_bin*)); /* cp to aligned */ sz += binp->sz; break; case TPL_TYPE_STR: for(i=0; i < c->num; i++) { sz += sizeof(uint32_t); /* string len */ memcpy(&strp,&((char**)c->data)[i],sizeof(char*)); /* cp to aligned */ sz += strp ? strlen(strp) : 0; } break; case TPL_TYPE_ARY: sz += sizeof(uint32_t); /* array len */ sz += c->ser_osz; /* bubbled-up child array ser_osz */ break; case TPL_TYPE_POUND: /* iterate over the preceding nodes */ itermax = c->num; pd = (tpl_pound_data*)c->data; if (++(pd->iternum) < itermax) { for(np=pd->iter_start_node; np != c; np = np->next) { np->data = (char*)(np->data) + (tpl_types[np->type].sz * np->num); } c = pd->iter_start_node; continue; } else { /* loop complete. */ pd->iternum = 0; for(np=pd->iter_start_node; np != c; np = np->next) { np->data = (char*)(np->data) - ((itermax-1) * tpl_types[np->type].sz * np->num); } } break; default: tpl_hook.fatal("unsupported format character\n"); break; } c=c->next; } return sz; } TPL_API int tpl_dump(tpl_node *r, int mode, ...) { va_list ap; char *filename, *bufv; void **addr_out,*buf, *pa_addr; int fd,rc=0; size_t sz,*sz_out, pa_sz; if (((tpl_root_data*)(r->data))->flags & TPL_RDONLY) { /* unusual */ tpl_hook.oops("error: tpl_dump called for a loaded tpl\n"); return -1; } sz = tpl_ser_osz(r); /* compute the size needed to serialize */ va_start(ap,mode); if (mode & TPL_FILE) { filename = va_arg(ap,char*); fd = tpl_mmap_output_file(filename, sz, &buf); if (fd == -1) rc = -1; else { rc = tpl_dump_to_mem(r,buf,sz); if (msync(buf,sz,MS_SYNC) == -1) { tpl_hook.oops("msync failed on fd %d: %s\n", fd, strerror(errno)); } if (munmap(buf, sz) == -1) { tpl_hook.oops("munmap failed on fd %d: %s\n", fd, strerror(errno)); } close(fd); } } else if (mode & TPL_FD) { fd = va_arg(ap, int); if ( (buf = tpl_hook.malloc(sz)) == NULL) fatal_oom(); tpl_dump_to_mem(r,buf,sz); bufv = buf; do { rc = write(fd,bufv,sz); if (rc > 0) { sz -= rc; bufv += rc; } else if (rc == -1) { if (errno == EINTR || errno == EAGAIN) continue; tpl_hook.oops("error writing to fd %d: %s\n", fd, strerror(errno)); free(buf); return -1; } } while (sz > 0); free(buf); rc = 0; } else if (mode & TPL_MEM) { if (mode & TPL_PREALLOCD) { /* caller allocated */ pa_addr = (void*)va_arg(ap, void*); pa_sz = va_arg(ap, size_t); if (pa_sz < sz) { tpl_hook.oops("tpl_dump: buffer too small, need %d bytes\n", sz); return -1; } rc=tpl_dump_to_mem(r,pa_addr,sz); } else { /* we allocate */ addr_out = (void**)va_arg(ap, void*); sz_out = va_arg(ap, size_t*); if ( (buf = tpl_hook.malloc(sz)) == NULL) fatal_oom(); *sz_out = sz; *addr_out = buf; rc=tpl_dump_to_mem(r,buf,sz); } } else if (mode & TPL_GETSIZE) { sz_out = va_arg(ap, size_t*); *sz_out = sz; } else { tpl_hook.oops("unsupported tpl_dump mode %d\n", mode); rc=-1; } va_end(ap); return rc; } /* This function expects the caller to have set up a memory buffer of * adequate size to hold the serialized tpl. The sz parameter must be * the result of tpl_ser_osz(r). */ static int tpl_dump_to_mem(tpl_node *r,void *addr,size_t sz) { uint32_t slen, sz32; int *fxlens, num_fxlens, i; void *dv; char *fmt,flags; tpl_node *c, *np; tpl_pound_data *pd; size_t itermax; fmt = tpl_fmt(r); flags = 0; if (tpl_cpu_bigendian()) flags |= TPL_FL_BIGENDIAN; if (strchr(fmt,'s')) flags |= TPL_FL_NULLSTRINGS; sz32 = sz; dv = addr; dv = tpl_cpv(dv,TPL_MAGIC,3); /* copy tpl magic prefix */ dv = tpl_cpv(dv,&flags,1); /* copy flags byte */ dv = tpl_cpv(dv,&sz32,sizeof(uint32_t));/* overall length (inclusive) */ dv = tpl_cpv(dv,fmt,strlen(fmt)+1); /* copy format with NUL-term */ fxlens = tpl_fxlens(r,&num_fxlens); dv = tpl_cpv(dv,fxlens,num_fxlens*sizeof(uint32_t));/* fmt # lengths */ /* serialize the tpl content, iterating over direct children of root */ c = r->children; while (c) { switch (c->type) { case TPL_TYPE_BYTE: case TPL_TYPE_DOUBLE: case TPL_TYPE_INT32: case TPL_TYPE_UINT32: case TPL_TYPE_INT64: case TPL_TYPE_UINT64: case TPL_TYPE_INT16: case TPL_TYPE_UINT16: dv = tpl_cpv(dv,c->data,tpl_types[c->type].sz * c->num); break; case TPL_TYPE_BIN: slen = (*(tpl_bin**)(c->data))->sz; dv = tpl_cpv(dv,&slen,sizeof(uint32_t)); /* buffer len */ dv = tpl_cpv(dv,(*(tpl_bin**)(c->data))->addr,slen); /* buf */ break; case TPL_TYPE_STR: for(i=0; i < c->num; i++) { char *str = ((char**)c->data)[i]; slen = str ? strlen(str)+1 : 0; dv = tpl_cpv(dv,&slen,sizeof(uint32_t)); /* string len */ if (slen>1) dv = tpl_cpv(dv,str,slen-1); /*string*/ } break; case TPL_TYPE_ARY: dv = tpl_dump_atyp(c,(tpl_atyp*)c->data,dv); break; case TPL_TYPE_POUND: pd = (tpl_pound_data*)c->data; itermax = c->num; if (++(pd->iternum) < itermax) { /* in start or midst of loop. advance data pointers. */ for(np=pd->iter_start_node; np != c; np = np->next) { np->data = (char*)(np->data) + (tpl_types[np->type].sz * np->num); } /* do next iteration */ c = pd->iter_start_node; continue; } else { /* loop complete. */ /* reset iteration index and addr/data pointers. */ pd->iternum = 0; for(np=pd->iter_start_node; np != c; np = np->next) { np->data = (char*)(np->data) - ((itermax-1) * tpl_types[np->type].sz * np->num); } } break; default: tpl_hook.fatal("unsupported format character\n"); break; } c = c->next; } return 0; } static int tpl_cpu_bigendian() { unsigned i = 1; char *c; c = (char*)&i; return (c[0] == 1 ? 0 : 1); } /* * algorithm for sanity-checking a tpl image: * scan the tpl whilst not exceeding the buffer size (bufsz) , * formulating a calculated (expected) size of the tpl based * on walking its data. When calcsize has been calculated it * should exactly match the buffer size (bufsz) and the internal * recorded size (intlsz) */ static int tpl_sanity(tpl_node *r, int excess_ok) { uint32_t intlsz; int found_nul=0,rc, octothorpes=0, num_fxlens, *fxlens, flen; void *d, *dv; char intlflags, *fmt, c, *mapfmt; size_t bufsz, serlen; d = ((tpl_root_data*)(r->data))->mmap.text; bufsz = ((tpl_root_data*)(r->data))->mmap.text_sz; dv = d; if (bufsz < (4 + sizeof(uint32_t) + 1)) return ERR_NOT_MINSIZE; /* min sz: magic+flags+len+nul */ if (memcmp(dv,TPL_MAGIC, 3) != 0) return ERR_MAGIC_MISMATCH; /* missing tpl magic prefix */ if (tpl_needs_endian_swap(dv)) ((tpl_root_data*)(r->data))->flags |= TPL_XENDIAN; dv = (void*)((uintptr_t)dv + 3); memcpy(&intlflags,dv,sizeof(char)); /* extract flags */ if (intlflags & ~TPL_SUPPORTED_BITFLAGS) return ERR_UNSUPPORTED_FLAGS; /* TPL1.3 stores strings with a "length+1" prefix to discern NULL strings from empty strings from non-empty strings; TPL1.2 only handled the latter two. So we need to be mindful of which string format we're reading from. */ if (!(intlflags & TPL_FL_NULLSTRINGS)) { ((tpl_root_data*)(r->data))->flags |= TPL_OLD_STRING_FMT; } dv = (void*)((uintptr_t)dv + 1); memcpy(&intlsz,dv,sizeof(uint32_t)); /* extract internal size */ if (((tpl_root_data*)(r->data))->flags & TPL_XENDIAN) tpl_byteswap(&intlsz, sizeof(uint32_t)); if (!excess_ok && (intlsz != bufsz)) return ERR_INCONSISTENT_SZ; /* inconsisent buffer/internal size */ dv = (void*)((uintptr_t)dv + sizeof(uint32_t)); /* dv points to the start of the format string. Look for nul w/in buf sz */ fmt = (char*)dv; while ((uintptr_t)dv-(uintptr_t)d < bufsz && !found_nul) { if ( (c = *(char*)dv) != '\0') { if (strchr(tpl_fmt_chars,c) == NULL) return ERR_FMT_INVALID; /* invalid char in format string */ if ( (c = *(char*)dv) == '#') octothorpes++; dv = (void*)((uintptr_t)dv + 1); } else found_nul = 1; } if (!found_nul) return ERR_FMT_MISSING_NUL; /* runaway format string */ dv = (void*)((uintptr_t)dv + 1); /* advance to octothorpe lengths buffer */ /* compare the map format to the format of this tpl image */ mapfmt = tpl_fmt(r); rc = strcmp(mapfmt,fmt); if (rc != 0) return ERR_FMT_MISMATCH; /* compare octothorpe lengths in image to the mapped values */ if ((((uintptr_t)dv + (octothorpes * 4)) - (uintptr_t)d) > bufsz) return ERR_INCONSISTENT_SZ4; fxlens = tpl_fxlens(r,&num_fxlens); /* mapped fxlens */ while(num_fxlens--) { memcpy(&flen,dv,sizeof(uint32_t)); /* stored flen */ if (((tpl_root_data*)(r->data))->flags & TPL_XENDIAN) tpl_byteswap(&flen, sizeof(uint32_t)); if (flen != *fxlens) return ERR_FLEN_MISMATCH; dv = (void*)((uintptr_t)dv + sizeof(uint32_t)); fxlens++; } /* dv now points to beginning of data */ rc = tpl_serlen(r,r,dv,&serlen); /* get computed serlen of data part */ if (rc == -1) return ERR_INCONSISTENT_SZ2; /* internal inconsistency in tpl image */ serlen += ((uintptr_t)dv - (uintptr_t)d); /* add back serlen of preamble part */ if (excess_ok && (bufsz < serlen)) return ERR_INCONSISTENT_SZ3; if (!excess_ok && (serlen != bufsz)) return ERR_INCONSISTENT_SZ3; /* buffer/internal sz exceeds serlen */ return 0; } static void *tpl_find_data_start(void *d) { int octothorpes=0; d = (void*)((uintptr_t)d + 4); /* skip TPL_MAGIC and flags byte */ d = (void*)((uintptr_t)d + 4); /* skip int32 overall len */ while(*(char*)d != '\0') { if (*(char*)d == '#') octothorpes++; d = (void*)((uintptr_t)d + 1); } d = (void*)((uintptr_t)d + 1); /* skip NUL */ d = (void*)((uintptr_t)d + (octothorpes * sizeof(uint32_t))); /* skip # array lens */ return d; } static int tpl_needs_endian_swap(void *d) { char *c; int cpu_is_bigendian; c = (char*)d; cpu_is_bigendian = tpl_cpu_bigendian(); return ((c[3] & TPL_FL_BIGENDIAN) == cpu_is_bigendian) ? 0 : 1; } static size_t tpl_size_for(char c) { int i; for(i=0; i < sizeof(tpl_types)/sizeof(tpl_types[0]); i++) { if (tpl_types[i].c == c) return tpl_types[i].sz; } return 0; } TPL_API char* tpl_peek(int mode, ...) { va_list ap; int xendian=0,found_nul=0,old_string_format=0; char *filename=NULL, *datapeek_f=NULL, *datapeek_c=NULL, *datapeek_s=NULL; void *addr=NULL, *dv, *datapeek_p=NULL; size_t sz=0, fmt_len, first_atom, num_fxlens=0; uint32_t datapeek_ssz, datapeek_csz, datapeek_flen; tpl_mmap_rec mr = {0,NULL,0}; char *fmt,*fmt_cpy=NULL,c; uint32_t intlsz, **fxlens=NULL, *num_fxlens_out=NULL, *fxlensv; va_start(ap,mode); if ((mode & TPL_FXLENS) && (mode & TPL_DATAPEEK)) { tpl_hook.oops("TPL_FXLENS and TPL_DATAPEEK mutually exclusive\n"); goto fail; } if (mode & TPL_FILE) filename = va_arg(ap,char *); else if (mode & TPL_MEM) { addr = va_arg(ap,void *); sz = va_arg(ap,size_t); } else { tpl_hook.oops("unsupported tpl_peek mode %d\n", mode); goto fail; } if (mode & TPL_DATAPEEK) { datapeek_f = va_arg(ap, char*); } if (mode & TPL_FXLENS) { num_fxlens_out = va_arg(ap,uint32_t *); fxlens = va_arg(ap,uint32_t **); *num_fxlens_out = 0; *fxlens = NULL; } if (mode & TPL_FILE) { if (tpl_mmap_file(filename, &mr) != 0) { tpl_hook.oops("tpl_peek failed for file %s\n", filename); goto fail; } addr = mr.text; sz = mr.text_sz; } dv = addr; if (sz < (4 + sizeof(uint32_t) + 1)) goto fail; /* min sz */ if (memcmp(dv,TPL_MAGIC, 3) != 0) goto fail; /* missing tpl magic prefix */ if (tpl_needs_endian_swap(dv)) xendian=1; if ((((char*)dv)[3] & TPL_FL_NULLSTRINGS)==0) old_string_format=1; dv = (void*)((uintptr_t)dv + 4); memcpy(&intlsz,dv,sizeof(uint32_t)); /* extract internal size */ if (xendian) tpl_byteswap(&intlsz, sizeof(uint32_t)); if (intlsz != sz) goto fail; /* inconsisent buffer/internal size */ dv = (void*)((uintptr_t)dv + sizeof(uint32_t)); /* dv points to the start of the format string. Look for nul w/in buf sz */ fmt = (char*)dv; while ((uintptr_t)dv-(uintptr_t)addr < sz && !found_nul) { if ( (c = *(char*)dv) == '\0') { found_nul = 1; } else if (c == '#') { num_fxlens++; } dv = (void*)((uintptr_t)dv + 1); } if (!found_nul) goto fail; /* runaway format string */ fmt_len = (char*)dv - fmt; /* include space for \0 */ fmt_cpy = tpl_hook.malloc(fmt_len); if (fmt_cpy == NULL) { fatal_oom(); } memcpy(fmt_cpy, fmt, fmt_len); /* retrieve the octothorpic lengths if requested */ if (num_fxlens > 0) { if (sz < ((uintptr_t)dv + (num_fxlens * sizeof(uint32_t)) - (uintptr_t)addr)) { goto fail; } } if ((mode & TPL_FXLENS) && (num_fxlens > 0)) { *fxlens = tpl_hook.malloc(num_fxlens * sizeof(uint32_t)); if (*fxlens == NULL) tpl_hook.fatal("out of memory"); *num_fxlens_out = num_fxlens; fxlensv = *fxlens; while(num_fxlens--) { memcpy(fxlensv,dv,sizeof(uint32_t)); if (xendian) tpl_byteswap(fxlensv, sizeof(uint32_t)); dv = (void*)((uintptr_t)dv + sizeof(uint32_t)); fxlensv++; } } /* if caller requested, peek into the specified data elements */ if (mode & TPL_DATAPEEK) { first_atom = strspn(fmt, "S()"); /* skip any leading S() */ datapeek_flen = strlen(datapeek_f); if (strspn(datapeek_f, tpl_datapeek_ok_chars) < datapeek_flen) { tpl_hook.oops("invalid TPL_DATAPEEK format: %s\n", datapeek_f); tpl_hook.free(fmt_cpy); fmt_cpy = NULL; /* fail */ goto fail; } if (strncmp( &fmt[first_atom], datapeek_f, datapeek_flen) != 0) { tpl_hook.oops("TPL_DATAPEEK format mismatches tpl iamge\n"); tpl_hook.free(fmt_cpy); fmt_cpy = NULL; /* fail */ goto fail; } /* advance to data start, then copy out requested elements */ dv = (void*)((uintptr_t)dv + (num_fxlens * sizeof(uint32_t))); for(datapeek_c = datapeek_f; datapeek_c != NULL && *datapeek_c != '\0'; datapeek_c++) { datapeek_p = va_arg(ap, void*); if (*datapeek_c == 's') { /* special handling for strings */ if ((uintptr_t)dv-(uintptr_t)addr + sizeof(uint32_t) > sz) { tpl_hook.oops("tpl_peek: tpl has insufficient length\n"); tpl_hook.free(fmt_cpy); fmt_cpy = NULL; /* fail */ goto fail; } memcpy(&datapeek_ssz,dv,sizeof(uint32_t)); /* get slen */ if (xendian) tpl_byteswap(&datapeek_ssz, sizeof(uint32_t)); if (old_string_format) datapeek_ssz++; dv = (void*)((uintptr_t)dv + sizeof(uint32_t)); /* adv. to str */ if (datapeek_ssz == 0) datapeek_s = NULL; else { if ((uintptr_t)dv-(uintptr_t)addr + datapeek_ssz-1 > sz) { tpl_hook.oops("tpl_peek: tpl has insufficient length\n"); tpl_hook.free(fmt_cpy); fmt_cpy = NULL; /* fail */ goto fail; } datapeek_s = tpl_hook.malloc(datapeek_ssz); if (datapeek_s == NULL) fatal_oom(); memcpy(datapeek_s, dv, datapeek_ssz-1); datapeek_s[datapeek_ssz-1] = '\0'; dv = (void*)((uintptr_t)dv + datapeek_ssz-1); } *(char**)datapeek_p = datapeek_s; } else { datapeek_csz = tpl_size_for(*datapeek_c); if ((uintptr_t)dv-(uintptr_t)addr + datapeek_csz > sz) { tpl_hook.oops("tpl_peek: tpl has insufficient length\n"); tpl_hook.free(fmt_cpy); fmt_cpy = NULL; /* fail */ goto fail; } memcpy(datapeek_p, dv, datapeek_csz); if (xendian) tpl_byteswap(datapeek_p, datapeek_csz); dv = (void*)((uintptr_t)dv + datapeek_csz); } } } fail: va_end(ap); if ((mode & TPL_FILE) && mr.text != NULL) tpl_unmap_file( &mr ); return fmt_cpy; } /* tpl_jot(TPL_FILE, "file.tpl", "si", &s, &i); */ /* tpl_jot(TPL_MEM, &buf, &sz, "si", &s, &i); */ /* tpl_jot(TPL_FD, fd, "si", &s, &i); */ TPL_API int tpl_jot(int mode, ...) { va_list ap; char *filename, *fmt; size_t *sz; int fd, rc=0; void **buf; tpl_node *tn; va_start(ap,mode); if (mode & TPL_FILE) { filename = va_arg(ap,char*); fmt = va_arg(ap,char*); tn = tpl_map_va(fmt, ap); if (tn == NULL) { rc=-1; goto fail;} tpl_pack(tn, 0); rc = tpl_dump(tn, TPL_FILE, filename); tpl_free(tn); } else if (mode & TPL_MEM) { buf = va_arg(ap,void*); sz = va_arg(ap,size_t*); fmt = va_arg(ap,char*); tn = tpl_map_va(fmt,ap); if (tn == NULL) { rc=-1; goto fail;} tpl_pack(tn,0); rc = tpl_dump(tn, TPL_MEM, buf, sz); tpl_free(tn); } else if (mode & TPL_FD) { fd = va_arg(ap,int); fmt = va_arg(ap,char*); tn = tpl_map_va(fmt,ap); if (tn == NULL) { rc=-1; goto fail;} tpl_pack(tn,0); rc = tpl_dump(tn, TPL_FD, fd); tpl_free(tn); } else { tpl_hook.fatal("invalid tpl_jot mode\n"); } fail: va_end(ap); return rc; } TPL_API int tpl_load(tpl_node *r, int mode, ...) { va_list ap; int rc=0,fd=0; char *filename=NULL; void *addr=NULL; size_t sz; va_start(ap,mode); if (mode & TPL_FILE) filename = va_arg(ap,char *); else if (mode & TPL_MEM) { addr = va_arg(ap,void *); sz = va_arg(ap,size_t); } else if (mode & TPL_FD) { fd = va_arg(ap,int); } else { tpl_hook.oops("unsupported tpl_load mode %d\n", mode); return -1; } va_end(ap); if (r->type != TPL_TYPE_ROOT) { tpl_hook.oops("error: tpl_load to non-root node\n"); return -1; } if (((tpl_root_data*)(r->data))->flags & (TPL_WRONLY|TPL_RDONLY)) { /* already packed or loaded, so reset it as if newly mapped */ tpl_free_keep_map(r); } if (mode & TPL_FILE) { if (tpl_mmap_file(filename, &((tpl_root_data*)(r->data))->mmap) != 0) { tpl_hook.oops("tpl_load failed for file %s\n", filename); return -1; } if ( (rc = tpl_sanity(r, (mode & TPL_EXCESS_OK))) != 0) { if (rc == ERR_FMT_MISMATCH) { tpl_hook.oops("%s: format signature mismatch\n", filename); } else if (rc == ERR_FLEN_MISMATCH) { tpl_hook.oops("%s: array lengths mismatch\n", filename); } else { tpl_hook.oops("%s: not a valid tpl file\n", filename); } tpl_unmap_file( &((tpl_root_data*)(r->data))->mmap ); return -1; } ((tpl_root_data*)(r->data))->flags = (TPL_FILE | TPL_RDONLY); } else if (mode & TPL_MEM) { ((tpl_root_data*)(r->data))->mmap.text = addr; ((tpl_root_data*)(r->data))->mmap.text_sz = sz; if ( (rc = tpl_sanity(r, (mode & TPL_EXCESS_OK))) != 0) { if (rc == ERR_FMT_MISMATCH) { tpl_hook.oops("format signature mismatch\n"); } else { tpl_hook.oops("not a valid tpl file\n"); } return -1; } ((tpl_root_data*)(r->data))->flags = (TPL_MEM | TPL_RDONLY); if (mode & TPL_UFREE) ((tpl_root_data*)(r->data))->flags |= TPL_UFREE; } else if (mode & TPL_FD) { /* if fd read succeeds, resulting mem img is used for load */ if (tpl_gather(TPL_GATHER_BLOCKING,fd,&addr,&sz) > 0) { return tpl_load(r, TPL_MEM|TPL_UFREE, addr, sz); } else return -1; } else { tpl_hook.oops("invalid tpl_load mode %d\n", mode); return -1; } /* this applies to TPL_MEM or TPL_FILE */ if (tpl_needs_endian_swap(((tpl_root_data*)(r->data))->mmap.text)) ((tpl_root_data*)(r->data))->flags |= TPL_XENDIAN; tpl_unpackA0(r); /* prepare root A nodes for use */ return 0; } TPL_API int tpl_Alen(tpl_node *r, int i) { tpl_node *n; n = tpl_find_i(r,i); if (n == NULL) { tpl_hook.oops("invalid index %d to tpl_unpack\n", i); return -1; } if (n->type != TPL_TYPE_ARY) return -1; return ((tpl_atyp*)(n->data))->num; } static void tpl_free_atyp(tpl_node *n, tpl_atyp *atyp) { tpl_backbone *bb,*bbnxt; tpl_node *c; void *dv; tpl_bin *binp; tpl_atyp *atypp; char *strp; size_t itermax; tpl_pound_data *pd; int i; bb = atyp->bb; while (bb) { bbnxt = bb->next; dv = bb->data; c=n->children; while (c) { switch (c->type) { case TPL_TYPE_BYTE: case TPL_TYPE_DOUBLE: case TPL_TYPE_INT32: case TPL_TYPE_UINT32: case TPL_TYPE_INT64: case TPL_TYPE_UINT64: case TPL_TYPE_INT16: case TPL_TYPE_UINT16: dv = (void*)((uintptr_t)dv + tpl_types[c->type].sz*c->num); break; case TPL_TYPE_BIN: memcpy(&binp,dv,sizeof(tpl_bin*)); /* cp to aligned */ if (binp->addr) tpl_hook.free( binp->addr ); /* free buf */ tpl_hook.free(binp); /* free tpl_bin */ dv = (void*)((uintptr_t)dv + sizeof(tpl_bin*)); break; case TPL_TYPE_STR: for(i=0; i < c->num; i++) { memcpy(&strp,dv,sizeof(char*)); /* cp to aligned */ if (strp) tpl_hook.free(strp); /* free string */ dv = (void*)((uintptr_t)dv + sizeof(char*)); } break; case TPL_TYPE_POUND: /* iterate over the preceding nodes */ itermax = c->num; pd = (tpl_pound_data*)c->data; if (++(pd->iternum) < itermax) { c = pd->iter_start_node; continue; } else { /* loop complete. */ pd->iternum = 0; } break; case TPL_TYPE_ARY: memcpy(&atypp,dv,sizeof(tpl_atyp*)); /* cp to aligned */ tpl_free_atyp(c,atypp); /* free atyp */ dv = (void*)((uintptr_t)dv + sizeof(void*)); break; default: tpl_hook.fatal("unsupported format character\n"); break; } c=c->next; } tpl_hook.free(bb); bb = bbnxt; } tpl_hook.free(atyp); } /* determine (by walking) byte length of serialized r/A node at address dv * returns 0 on success, or -1 if the tpl isn't trustworthy (fails consistency) */ static int tpl_serlen(tpl_node *r, tpl_node *n, void *dv, size_t *serlen) { uint32_t slen; int num=0,fidx; tpl_node *c; size_t len=0, alen, buf_past, itermax; tpl_pound_data *pd; buf_past = ((uintptr_t)((tpl_root_data*)(r->data))->mmap.text + ((tpl_root_data*)(r->data))->mmap.text_sz); if (n->type == TPL_TYPE_ROOT) num = 1; else if (n->type == TPL_TYPE_ARY) { if ((uintptr_t)dv + sizeof(uint32_t) > buf_past) return -1; memcpy(&num,dv,sizeof(uint32_t)); if (((tpl_root_data*)(r->data))->flags & TPL_XENDIAN) tpl_byteswap(&num, sizeof(uint32_t)); dv = (void*)((uintptr_t)dv + sizeof(uint32_t)); len += sizeof(uint32_t); } else tpl_hook.fatal("internal error in tpl_serlen\n"); while (num-- > 0) { c=n->children; while (c) { switch (c->type) { case TPL_TYPE_BYTE: case TPL_TYPE_DOUBLE: case TPL_TYPE_INT32: case TPL_TYPE_UINT32: case TPL_TYPE_INT64: case TPL_TYPE_UINT64: case TPL_TYPE_INT16: case TPL_TYPE_UINT16: for(fidx=0; fidx < c->num; fidx++) { /* octothorpe support */ if ((uintptr_t)dv + tpl_types[c->type].sz > buf_past) return -1; dv = (void*)((uintptr_t)dv + tpl_types[c->type].sz); len += tpl_types[c->type].sz; } break; case TPL_TYPE_BIN: len += sizeof(uint32_t); if ((uintptr_t)dv + sizeof(uint32_t) > buf_past) return -1; memcpy(&slen,dv,sizeof(uint32_t)); if (((tpl_root_data*)(r->data))->flags & TPL_XENDIAN) tpl_byteswap(&slen, sizeof(uint32_t)); len += slen; dv = (void*)((uintptr_t)dv + sizeof(uint32_t)); if ((uintptr_t)dv + slen > buf_past) return -1; dv = (void*)((uintptr_t)dv + slen); break; case TPL_TYPE_STR: for(fidx=0; fidx < c->num; fidx++) { /* octothorpe support */ len += sizeof(uint32_t); if ((uintptr_t)dv + sizeof(uint32_t) > buf_past) return -1; memcpy(&slen,dv,sizeof(uint32_t)); if (((tpl_root_data*)(r->data))->flags & TPL_XENDIAN) tpl_byteswap(&slen, sizeof(uint32_t)); if (!(((tpl_root_data*)(r->data))->flags & TPL_OLD_STRING_FMT)) slen = (slen>1) ? (slen-1) : 0; len += slen; dv = (void*)((uintptr_t)dv + sizeof(uint32_t)); if ((uintptr_t)dv + slen > buf_past) return -1; dv = (void*)((uintptr_t)dv + slen); } break; case TPL_TYPE_ARY: if ( tpl_serlen(r,c,dv, &alen) == -1) return -1; dv = (void*)((uintptr_t)dv + alen); len += alen; break; case TPL_TYPE_POUND: /* iterate over the preceding nodes */ itermax = c->num; pd = (tpl_pound_data*)c->data; if (++(pd->iternum) < itermax) { c = pd->iter_start_node; continue; } else { /* loop complete. */ pd->iternum = 0; } break; default: tpl_hook.fatal("unsupported format character\n"); break; } c=c->next; } } *serlen = len; return 0; } static int tpl_mmap_output_file(char *filename, size_t sz, void **text_out) { void *text; int fd,perms; #ifndef _WIN32 perms = S_IRUSR|S_IWUSR|S_IWGRP|S_IRGRP|S_IROTH; /* ug+w o+r */ fd=open(filename,O_CREAT|O_TRUNC|O_RDWR,perms); #else perms = _S_IWRITE; fd=_open(filename,_O_CREAT|_O_TRUNC|_O_RDWR,perms); #endif if ( fd == -1 ) { tpl_hook.oops("Couldn't open file %s: %s\n", filename, strerror(errno)); return -1; } text = mmap(0, sz, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (text == MAP_FAILED) { tpl_hook.oops("Failed to mmap %s: %s\n", filename, strerror(errno)); close(fd); return -1; } if (ftruncate(fd,sz) == -1) { tpl_hook.oops("ftruncate failed: %s\n", strerror(errno)); munmap( text, sz ); close(fd); return -1; } *text_out = text; return fd; } static int tpl_mmap_file(char *filename, tpl_mmap_rec *mr) { struct stat stat_buf; if ( (mr->fd = open(filename, O_RDONLY)) == -1 ) { tpl_hook.oops("Couldn't open file %s: %s\n", filename, strerror(errno)); return -1; } if ( fstat(mr->fd, &stat_buf) == -1) { close(mr->fd); tpl_hook.oops("Couldn't stat file %s: %s\n", filename, strerror(errno)); return -1; } mr->text_sz = (size_t)stat_buf.st_size; mr->text = mmap(0, mr->text_sz, PROT_READ, MAP_PRIVATE, mr->fd, 0); if (mr->text == MAP_FAILED) { close(mr->fd); tpl_hook.oops("Failed to mmap %s: %s\n", filename, strerror(errno)); return -1; } return 0; } TPL_API int tpl_pack(tpl_node *r, int i) { tpl_node *n, *child, *np; void *datav=NULL; size_t sz, itermax; uint32_t slen; char *str; tpl_bin *bin; tpl_pound_data *pd; int fidx; n = tpl_find_i(r,i); if (n == NULL) { tpl_hook.oops("invalid index %d to tpl_pack\n", i); return -1; } if (((tpl_root_data*)(r->data))->flags & TPL_RDONLY) { /* convert to an writeable tpl, initially empty */ tpl_free_keep_map(r); } ((tpl_root_data*)(r->data))->flags |= TPL_WRONLY; if (n->type == TPL_TYPE_ARY) datav = tpl_extend_backbone(n); child = n->children; while(child) { switch(child->type) { case TPL_TYPE_BYTE: case TPL_TYPE_DOUBLE: case TPL_TYPE_INT32: case TPL_TYPE_UINT32: case TPL_TYPE_INT64: case TPL_TYPE_UINT64: case TPL_TYPE_INT16: case TPL_TYPE_UINT16: /* no need to use fidx iteration here; we can copy multiple values in one memcpy */ memcpy(child->data,child->addr,tpl_types[child->type].sz * child->num); if (datav) datav = tpl_cpv(datav,child->data,tpl_types[child->type].sz * child->num); if (n->type == TPL_TYPE_ARY) n->ser_osz += tpl_types[child->type].sz * child->num; break; case TPL_TYPE_BIN: /* copy the buffer to be packed */ slen = ((tpl_bin*)child->addr)->sz; if (slen >0) { str = tpl_hook.malloc(slen); if (!str) fatal_oom(); memcpy(str,((tpl_bin*)child->addr)->addr,slen); } else str = NULL; /* and make a tpl_bin to point to it */ bin = tpl_hook.malloc(sizeof(tpl_bin)); if (!bin) fatal_oom(); bin->addr = str; bin->sz = slen; /* now pack its pointer, first deep freeing any pre-existing bin */ if (*(tpl_bin**)(child->data) != NULL) { if ((*(tpl_bin**)(child->data))->sz != 0) { tpl_hook.free( (*(tpl_bin**)(child->data))->addr ); } tpl_hook.free(*(tpl_bin**)(child->data)); } memcpy(child->data,&bin,sizeof(tpl_bin*)); if (datav) { datav = tpl_cpv(datav, &bin, sizeof(tpl_bin*)); *(tpl_bin**)(child->data) = NULL; } if (n->type == TPL_TYPE_ARY) { n->ser_osz += sizeof(uint32_t); /* binary buf len word */ n->ser_osz += bin->sz; /* binary buf */ } break; case TPL_TYPE_STR: for(fidx=0; fidx < child->num; fidx++) { /* copy the string to be packed. slen includes \0. this block also works if the string pointer is NULL. */ char *caddr = ((char**)child->addr)[fidx]; char **cdata = &((char**)child->data)[fidx]; slen = caddr ? (strlen(caddr) + 1) : 0; if (slen) { str = tpl_hook.malloc(slen); if (!str) fatal_oom(); memcpy(str,caddr,slen); /* include \0 */ } else { str = NULL; } /* now pack its pointer, first freeing any pre-existing string */ if (*cdata != NULL) { tpl_hook.free(*cdata); } memcpy(cdata,&str,sizeof(char*)); if (datav) { datav = tpl_cpv(datav, &str, sizeof(char*)); *cdata = NULL; } if (n->type == TPL_TYPE_ARY) { n->ser_osz += sizeof(uint32_t); /* string len word */ if (slen>1) n->ser_osz += slen-1;/* string (without nul) */ } } break; case TPL_TYPE_ARY: /* copy the child's tpl_atype* and reset it to empty */ if (datav) { sz = ((tpl_atyp*)(child->data))->sz; datav = tpl_cpv(datav, &child->data, sizeof(void*)); child->data = tpl_hook.malloc(sizeof(tpl_atyp)); if (!child->data) fatal_oom(); ((tpl_atyp*)(child->data))->num = 0; ((tpl_atyp*)(child->data))->sz = sz; ((tpl_atyp*)(child->data))->bb = NULL; ((tpl_atyp*)(child->data))->bbtail = NULL; } /* parent is array? then bubble up child array's ser_osz */ if (n->type == TPL_TYPE_ARY) { n->ser_osz += sizeof(uint32_t); /* array len word */ n->ser_osz += child->ser_osz; /* child array ser_osz */ child->ser_osz = 0; /* reset child array ser_osz */ } break; case TPL_TYPE_POUND: /* we need to iterate n times over preceding nodes in S(...). * we may be in the midst of an iteration each time or starting. */ pd = (tpl_pound_data*)child->data; itermax = child->num; /* itermax is total num of iterations needed */ /* pd->iternum is current iteration index */ /* pd->inter_elt_len is element-to-element len of contiguous structs */ /* pd->iter_start_node is where we jump to at each iteration. */ if (++(pd->iternum) < itermax) { /* in start or midst of loop. advance addr/data pointers. */ for(np=pd->iter_start_node; np != child; np = np->next) { np->data = (char*)(np->data) + (tpl_types[np->type].sz * np->num); np->addr = (char*)(np->addr) + pd->inter_elt_len; } /* do next iteration */ child = pd->iter_start_node; continue; } else { /* loop complete. */ /* reset iteration index and addr/data pointers. */ pd->iternum = 0; for(np=pd->iter_start_node; np != child; np = np->next) { np->data = (char*)(np->data) - ((itermax-1) * tpl_types[np->type].sz * np->num); np->addr = (char*)(np->addr) - ((itermax-1) * pd->inter_elt_len); } } break; default: tpl_hook.fatal("unsupported format character\n"); break; } child=child->next; } return 0; } TPL_API int tpl_unpack(tpl_node *r, int i) { tpl_node *n, *c, *np; uint32_t slen; int rc=1, fidx; char *str; void *dv=NULL, *caddr; size_t A_bytes, itermax; tpl_pound_data *pd; void *img; size_t sz; /* handle unusual case of tpl_pack,tpl_unpack without an * intervening tpl_dump. do a dump/load implicitly. */ if (((tpl_root_data*)(r->data))->flags & TPL_WRONLY) { if (tpl_dump(r,TPL_MEM,&img,&sz) != 0) return -1; if (tpl_load(r,TPL_MEM|TPL_UFREE,img,sz) != 0) { tpl_hook.free(img); return -1; }; } n = tpl_find_i(r,i); if (n == NULL) { tpl_hook.oops("invalid index %d to tpl_unpack\n", i); return -1; } /* either root node or an A node */ if (n->type == TPL_TYPE_ROOT) { dv = tpl_find_data_start( ((tpl_root_data*)(n->data))->mmap.text ); } else if (n->type == TPL_TYPE_ARY) { if (((tpl_atyp*)(n->data))->num <= 0) return 0; /* array consumed */ else rc = ((tpl_atyp*)(n->data))->num--; dv = ((tpl_atyp*)(n->data))->cur; if (!dv) tpl_hook.fatal("must unpack parent of node before node itself\n"); } c = n->children; while (c) { switch (c->type) { case TPL_TYPE_BYTE: case TPL_TYPE_DOUBLE: case TPL_TYPE_INT32: case TPL_TYPE_UINT32: case TPL_TYPE_INT64: case TPL_TYPE_UINT64: case TPL_TYPE_INT16: case TPL_TYPE_UINT16: /* unpack elements of cross-endian octothorpic array individually */ if (((tpl_root_data*)(r->data))->flags & TPL_XENDIAN) { for(fidx=0; fidx < c->num; fidx++) { caddr = (void*)((uintptr_t)c->addr + (fidx * tpl_types[c->type].sz)); memcpy(caddr,dv,tpl_types[c->type].sz); tpl_byteswap(caddr, tpl_types[c->type].sz); dv = (void*)((uintptr_t)dv + tpl_types[c->type].sz); } } else { /* bulk unpack ok if not cross-endian */ memcpy(c->addr, dv, tpl_types[c->type].sz * c->num); dv = (void*)((uintptr_t)dv + tpl_types[c->type].sz * c->num); } break; case TPL_TYPE_BIN: memcpy(&slen,dv,sizeof(uint32_t)); if (((tpl_root_data*)(r->data))->flags & TPL_XENDIAN) tpl_byteswap(&slen, sizeof(uint32_t)); if (slen > 0) { str = (char*)tpl_hook.malloc(slen); if (!str) fatal_oom(); } else str=NULL; dv = (void*)((uintptr_t)dv + sizeof(uint32_t)); if (slen>0) memcpy(str,dv,slen); memcpy(&(((tpl_bin*)c->addr)->addr),&str,sizeof(void*)); memcpy(&(((tpl_bin*)c->addr)->sz),&slen,sizeof(uint32_t)); dv = (void*)((uintptr_t)dv + slen); break; case TPL_TYPE_STR: for(fidx=0; fidx < c->num; fidx++) { memcpy(&slen,dv,sizeof(uint32_t)); if (((tpl_root_data*)(r->data))->flags & TPL_XENDIAN) tpl_byteswap(&slen, sizeof(uint32_t)); if (((tpl_root_data*)(r->data))->flags & TPL_OLD_STRING_FMT) slen += 1; dv = (void*)((uintptr_t)dv + sizeof(uint32_t)); if (slen) { /* slen includes \0 */ str = (char*)tpl_hook.malloc(slen); if (!str) fatal_oom(); if (slen>1) memcpy(str,dv,slen-1); str[slen-1] = '\0'; /* nul terminate */ dv = (void*)((uintptr_t)dv + slen-1); } else str=NULL; memcpy(&((char**)c->addr)[fidx],&str,sizeof(char*)); } break; case TPL_TYPE_POUND: /* iterate over preceding nodes */ pd = (tpl_pound_data*)c->data; itermax = c->num; if (++(pd->iternum) < itermax) { /* in start or midst of loop. advance addr/data pointers. */ for(np=pd->iter_start_node; np != c; np = np->next) { np->addr = (char*)(np->addr) + pd->inter_elt_len; } /* do next iteration */ c = pd->iter_start_node; continue; } else { /* loop complete. */ /* reset iteration index and addr/data pointers. */ pd->iternum = 0; for(np=pd->iter_start_node; np != c; np = np->next) { np->addr = (char*)(np->addr) - ((itermax-1) * pd->inter_elt_len); } } break; case TPL_TYPE_ARY: if (tpl_serlen(r,c,dv, &A_bytes) == -1) tpl_hook.fatal("internal error in unpack\n"); memcpy( &((tpl_atyp*)(c->data))->num, dv, sizeof(uint32_t)); if (((tpl_root_data*)(r->data))->flags & TPL_XENDIAN) tpl_byteswap(&((tpl_atyp*)(c->data))->num, sizeof(uint32_t)); ((tpl_atyp*)(c->data))->cur = (void*)((uintptr_t)dv+sizeof(uint32_t)); dv = (void*)((uintptr_t)dv + A_bytes); break; default: tpl_hook.fatal("unsupported format character\n"); break; } c = c->next; } if (n->type == TPL_TYPE_ARY) ((tpl_atyp*)(n->data))->cur = dv; /* next element */ return rc; } /* Specialized function that unpacks only the root's A nodes, after tpl_load */ static int tpl_unpackA0(tpl_node *r) { tpl_node *n, *c; uint32_t slen; int rc=1,fidx,i; void *dv; size_t A_bytes, itermax; tpl_pound_data *pd; n = r; dv = tpl_find_data_start( ((tpl_root_data*)(r->data))->mmap.text); c=n->children; while (c) { switch (c->type) { case TPL_TYPE_BYTE: case TPL_TYPE_DOUBLE: case TPL_TYPE_INT32: case TPL_TYPE_UINT32: case TPL_TYPE_INT64: case TPL_TYPE_UINT64: case TPL_TYPE_INT16: case TPL_TYPE_UINT16: for(fidx=0;fidx < c->num; fidx++) { dv = (void*)((uintptr_t)dv + tpl_types[c->type].sz); } break; case TPL_TYPE_BIN: memcpy(&slen,dv,sizeof(uint32_t)); if (((tpl_root_data*)(r->data))->flags & TPL_XENDIAN) tpl_byteswap(&slen, sizeof(uint32_t)); dv = (void*)((uintptr_t)dv + sizeof(uint32_t)); dv = (void*)((uintptr_t)dv + slen); break; case TPL_TYPE_STR: for(i=0; inum; i++) { memcpy(&slen,dv,sizeof(uint32_t)); if (((tpl_root_data*)(r->data))->flags & TPL_XENDIAN) tpl_byteswap(&slen, sizeof(uint32_t)); if (((tpl_root_data*)(r->data))->flags & TPL_OLD_STRING_FMT) slen += 1; dv = (void*)((uintptr_t)dv + sizeof(uint32_t)); if (slen>1) dv = (void*)((uintptr_t)dv + slen-1); } break; case TPL_TYPE_POUND: /* iterate over the preceding nodes */ itermax = c->num; pd = (tpl_pound_data*)c->data; if (++(pd->iternum) < itermax) { c = pd->iter_start_node; continue; } else { /* loop complete. */ pd->iternum = 0; } break; case TPL_TYPE_ARY: if ( tpl_serlen(r,c,dv, &A_bytes) == -1) tpl_hook.fatal("internal error in unpackA0\n"); memcpy( &((tpl_atyp*)(c->data))->num, dv, sizeof(uint32_t)); if (((tpl_root_data*)(r->data))->flags & TPL_XENDIAN) tpl_byteswap(&((tpl_atyp*)(c->data))->num, sizeof(uint32_t)); ((tpl_atyp*)(c->data))->cur = (void*)((uintptr_t)dv+sizeof(uint32_t)); dv = (void*)((uintptr_t)dv + A_bytes); break; default: tpl_hook.fatal("unsupported format character\n"); break; } c=c->next; } return rc; } /* In-place byte order swapping of a word of length "len" bytes */ static void tpl_byteswap(void *word, int len) { int i; char c, *w; w = (char*)word; for(i=0; i0) ? rc : 0; } while ((rc==-1 && (errno==EINTR||errno==EAGAIN)) || (rc>0 && i<8)); if (rc<0) { tpl_hook.oops("tpl_gather_fd_blocking failed: %s\n", strerror(errno)); return -1; } else if (rc == 0) { /* tpl_hook.oops("tpl_gather_fd_blocking: eof\n"); */ return 0; } else if (i != 8) { tpl_hook.oops("internal error\n"); return -1; } if (preamble[0] == 't' && preamble[1] == 'p' && preamble[2] == 'l') { memcpy(&tpllen,&preamble[4],4); if (tpl_needs_endian_swap(preamble)) tpl_byteswap(&tpllen,4); } else { tpl_hook.oops("tpl_gather_fd_blocking: non-tpl input\n"); return -1; } /* malloc space for remainder of tpl image (overall length tpllen) * and read it in */ if (tpl_hook.gather_max > 0 && tpllen > tpl_hook.gather_max) { tpl_hook.oops("tpl exceeds max length %d\n", tpl_hook.gather_max); return -2; } *sz = tpllen; if ( (*img = tpl_hook.malloc(tpllen)) == NULL) { fatal_oom(); } memcpy(*img,preamble,8); /* copy preamble to output buffer */ i=8; do { rc = read(fd,&((*(char**)img)[i]),tpllen-i); i += (rc>0) ? rc : 0; } while ((rc==-1 && (errno==EINTR||errno==EAGAIN)) || (rc>0 && iimg); tpl_hook.free(*gs); *gs = NULL; } return -1; /* error, caller should close fd */ } } else if (rc == 0) { if (*gs) { tpl_hook.oops("tpl_gather: partial tpl image precedes EOF\n"); tpl_hook.free((*gs)->img); tpl_hook.free(*gs); *gs = NULL; } return 0; /* EOF, caller should close fd */ } else { /* concatenate any partial tpl from last read with new buffer */ if (*gs) { catlen = (*gs)->len + rc; if (tpl_hook.gather_max > 0 && catlen > tpl_hook.gather_max) { tpl_hook.free( (*gs)->img ); tpl_hook.free( (*gs) ); *gs = NULL; tpl_hook.oops("tpl exceeds max length %d\n", tpl_hook.gather_max); return -2; /* error, caller should close fd */ } if ( (img = tpl_hook.realloc((*gs)->img, catlen)) == NULL) { fatal_oom(); } memcpy(img + (*gs)->len, buf, rc); tpl_hook.free(*gs); *gs = NULL; } else { img = buf; catlen = rc; } /* isolate any full tpl(s) in img and invoke cb for each */ tpl = img; keep_looping = (tpl+8 < img+catlen) ? 1 : 0; while (keep_looping) { if (strncmp("tpl", tpl, 3) != 0) { tpl_hook.oops("tpl prefix invalid\n"); if (img != buf) tpl_hook.free(img); tpl_hook.free(*gs); *gs = NULL; return -3; /* error, caller should close fd */ } memcpy(&tpllen,&tpl[4],4); if (tpl_needs_endian_swap(tpl)) tpl_byteswap(&tpllen,4); if (tpl+tpllen <= img+catlen) { cbrc = (cb)(tpl,tpllen,data); /* invoke cb for tpl image */ tpl += tpllen; /* point to next tpl image */ if (cbrc < 0) keep_looping = 0; else keep_looping = (tpl+8 < img+catlen) ? 1 : 0; } else keep_looping=0; } /* check if app callback requested closure of tpl source */ if (cbrc < 0) { tpl_hook.oops("tpl_fd_gather aborted by app callback\n"); if (img != buf) tpl_hook.free(img); if (*gs) tpl_hook.free(*gs); *gs = NULL; return -4; } /* store any leftover, partial tpl fragment for next read */ if (tpl == img && img != buf) { /* consumed nothing from img!=buf */ if ( (*gs = tpl_hook.malloc(sizeof(tpl_gather_t))) == NULL ) { fatal_oom(); } (*gs)->img = tpl; (*gs)->len = catlen; } else if (tpl < img+catlen) { /* consumed 1+ tpl(s) from img!=buf or 0 from img==buf */ if ( (*gs = tpl_hook.malloc(sizeof(tpl_gather_t))) == NULL ) { fatal_oom(); } if ( ((*gs)->img = tpl_hook.malloc(img+catlen - tpl)) == NULL ) { fatal_oom(); } (*gs)->len = img+catlen - tpl; memcpy( (*gs)->img, tpl, img+catlen - tpl); /* free partially consumed concat buffer if used */ if (img != buf) tpl_hook.free(img); } else { /* tpl(s) fully consumed */ /* free consumed concat buffer if used */ if (img != buf) tpl_hook.free(img); } } } } /* gather tpl piecemeal from memory buffer (not fd) e.g., from a lower-level api */ static int tpl_gather_mem( char *buf, size_t len, tpl_gather_t **gs, tpl_gather_cb *cb, void *data) { char *img, *tpl; int keep_looping, cbrc=0; size_t catlen; uint32_t tpllen; /* concatenate any partial tpl from last read with new buffer */ if (*gs) { catlen = (*gs)->len + len; if (tpl_hook.gather_max > 0 && catlen > tpl_hook.gather_max) { tpl_hook.free( (*gs)->img ); tpl_hook.free( (*gs) ); *gs = NULL; tpl_hook.oops("tpl exceeds max length %d\n", tpl_hook.gather_max); return -2; /* error, caller should stop accepting input from source*/ } if ( (img = tpl_hook.realloc((*gs)->img, catlen)) == NULL) { fatal_oom(); } memcpy(img + (*gs)->len, buf, len); tpl_hook.free(*gs); *gs = NULL; } else { img = buf; catlen = len; } /* isolate any full tpl(s) in img and invoke cb for each */ tpl = img; keep_looping = (tpl+8 < img+catlen) ? 1 : 0; while (keep_looping) { if (strncmp("tpl", tpl, 3) != 0) { tpl_hook.oops("tpl prefix invalid\n"); if (img != buf) tpl_hook.free(img); tpl_hook.free(*gs); *gs = NULL; return -3; /* error, caller should stop accepting input from source*/ } memcpy(&tpllen,&tpl[4],4); if (tpl_needs_endian_swap(tpl)) tpl_byteswap(&tpllen,4); if (tpl+tpllen <= img+catlen) { cbrc = (cb)(tpl,tpllen,data); /* invoke cb for tpl image */ tpl += tpllen; /* point to next tpl image */ if (cbrc < 0) keep_looping = 0; else keep_looping = (tpl+8 < img+catlen) ? 1 : 0; } else keep_looping=0; } /* check if app callback requested closure of tpl source */ if (cbrc < 0) { tpl_hook.oops("tpl_mem_gather aborted by app callback\n"); if (img != buf) tpl_hook.free(img); if (*gs) tpl_hook.free(*gs); *gs = NULL; return -4; } /* store any leftover, partial tpl fragment for next read */ if (tpl == img && img != buf) { /* consumed nothing from img!=buf */ if ( (*gs = tpl_hook.malloc(sizeof(tpl_gather_t))) == NULL ) { fatal_oom(); } (*gs)->img = tpl; (*gs)->len = catlen; } else if (tpl < img+catlen) { /* consumed 1+ tpl(s) from img!=buf or 0 from img==buf */ if ( (*gs = tpl_hook.malloc(sizeof(tpl_gather_t))) == NULL ) { fatal_oom(); } if ( ((*gs)->img = tpl_hook.malloc(img+catlen - tpl)) == NULL ) { fatal_oom(); } (*gs)->len = img+catlen - tpl; memcpy( (*gs)->img, tpl, img+catlen - tpl); /* free partially consumed concat buffer if used */ if (img != buf) tpl_hook.free(img); } else { /* tpl(s) fully consumed */ /* free consumed concat buffer if used */ if (img != buf) tpl_hook.free(img); } return 1; } proftpd-dfsg-1.3.5~rc3/lib/glibc-mkstemp.c0000644000175000017500000000613611566546322020235 0ustar frankiefrankie/* Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. */ #define __PROFTPD_SUPPORT_LIBRARY #include #include #ifndef HAVE_MKSTEMP /* These are the characters used in temporary filenames. */ static const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; /* Generate a temporary file name based on TMPL. TMPL must match the rules for mk[s]temp (i.e. end in "XXXXXX"). The name constructed does not exist at the time of the call to mkstemp(). TMPL is overwritten with the result. Creates the file and returns a read-write fd; the file is mode 0600 modulo umask. We use a clever algorithm to get hard-to-predict names. */ int mkstemp (char *tmpl) { int len; char *XXXXXX; static uint64_t value; struct timeval tv; int count, fd; int save_errno = errno; len = strlen (tmpl); if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX")) { errno = EINVAL; return -1; } /* This is where the Xs start. */ XXXXXX = &tmpl[len - 6]; /* Get some more or less random data. */ gettimeofday (&tv, NULL); value += ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec ^ getpid (); for (count = 0; count < TMP_MAX; value += 7777, ++count) { uint64_t v = value; /* Fill in the random bits. */ XXXXXX[0] = letters[v % 62]; v /= 62; XXXXXX[1] = letters[v % 62]; v /= 62; XXXXXX[2] = letters[v % 62]; v /= 62; XXXXXX[3] = letters[v % 62]; v /= 62; XXXXXX[4] = letters[v % 62]; v /= 62; XXXXXX[5] = letters[v % 62]; /* NOTE: this, or test for _LARGEFILE_SOURCE in order to use the O_LARGEFILE * open flag */ #ifdef _LARGEFILE_SOURCE fd = open64 (tmpl, O_RDWR | O_CREAT | O_EXCL, 0600); #else fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL, 0600); #endif if (fd >= 0) { errno = save_errno; return fd; } else if (errno != EEXIST) /* Any other error will apply also to other names we might try, and there are 2^32 or so of them, so give up now. */ return -1; } /* We got out of the loop because we ran out of combinations to try. */ errno = EEXIST; return -1; } #else /* HAVE_MKSTEMP */ void pr_os_already_has_mkstemp(void) { } #endif /* HAVE_MKSTEMP */ proftpd-dfsg-1.3.5~rc3/lib/libltdl/0000755000175000017500000000000012156653653016755 5ustar frankiefrankieproftpd-dfsg-1.3.5~rc3/lib/libltdl/m4/0000755000175000017500000000000012156653653017275 5ustar frankiefrankieproftpd-dfsg-1.3.5~rc3/lib/libltdl/m4/libtool.m40000644000175000017500000077426611300565264021217 0ustar frankiefrankie# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ]) # serial 56 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_CC_BASENAME(CC) # ------------------- # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. m4_defun([_LT_CC_BASENAME], [for cc_temp in $1""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl _LT_PROG_ECHO_BACKSLASH case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from `configure', and `config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # `config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain="$ac_aux_dir/ltmain.sh" ])# _LT_PROG_LTMAIN ## ------------------------------------- ## ## Accumulate code for creating libtool. ## ## ------------------------------------- ## # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the `libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) ## ------------------------ ## ## FIXME: Eliminate VARNAME ## ## ------------------------ ## # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to `config.status' so that its # declaration there will have the same value as in `configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "X$][$1" | $Xsed -e "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "X$" | $Xsed -e "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags="_LT_TAGS"dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the `libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into `config.status', and then the shell code to quote escape them in # for loops in `config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Fix-up fallback echo if it was mangled by the above quoting rules. case \$lt_ECHO in *'\\\[$]0 --fallback-echo"')dnl " lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\[$]0 --fallback-echo"\[$]/\[$]0 --fallback-echo"/'\` ;; esac _LT_OUTPUT_LIBTOOL_INIT ]) # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) cat >"$CONFIG_LT" <<_LTEOF #! $SHELL # Generated by $as_me. # Run this file to recreate a libtool stub with the current configuration. lt_cl_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ \`$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2008 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test $[#] != 0 do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try \`$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try \`$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. if test "$no_create" != yes; then lt_cl_success=: test "$silent" = yes && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) fi ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # _LT_COPYING _LT_LIBTOOL_TAGS # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) _LT_PROG_XSI_SHELLFNS sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS="$save_LDFLAGS" ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[[012]]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES # -------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(whole_archive_flag_spec, $1)='' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=echo _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" m4_if([$1], [CXX], [ if test "$lt_cv_apple_cc_single_mod" != "yes"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX # ----------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl AC_LINK_IFELSE(AC_LANG_PROGRAM,[ lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/ p } }' aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [ifdef([AC_DIVERSION_NOTICE], [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], [AC_DIVERT_PUSH(NOTICE)]) $1 AC_DIVERT_POP ])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Add some code to the start of the generated configure script which # will find an echo command which doesn't interpret backslashes. m4_defun([_LT_PROG_ECHO_BACKSLASH], [_LT_SHELL_INIT([ # Check that we are running under the correct shell. SHELL=${CONFIG_SHELL-/bin/sh} case X$lt_ECHO in X*--fallback-echo) # Remove one level of quotation (which was required for Make). ECHO=`echo "$lt_ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` ;; esac ECHO=${lt_ECHO-echo} if test "X[$]1" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test "X[$]1" = X--fallback-echo; then # Avoid inline document here, it may be left over : elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then # Yippee, $ECHO works! : else # Restart under the correct shell. exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} fi if test "X[$]1" = X--fallback-echo; then # used as fallback echo shift cat <<_LT_EOF [$]* _LT_EOF exit 0 fi # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test -z "$lt_ECHO"; then if test "X${echo_test_string+set}" != Xset; then # find a string as large as possible, as long as the shell can cope with it for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... if { echo_test_string=`eval $cmd`; } 2>/dev/null && { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null then break fi done fi if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then : else # The Solaris, AIX, and Digital Unix default echo programs unquote # backslashes. This makes it impossible to quote backslashes using # echo "$something" | sed 's/\\/\\\\/g' # # So, first we look for a working echo in the user's PATH. lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for dir in $PATH /usr/ucb; do IFS="$lt_save_ifs" if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then ECHO="$dir/echo" break fi done IFS="$lt_save_ifs" if test "X$ECHO" = Xecho; then # We didn't find a better echo, so look for alternatives. if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # This shell has a builtin print -r that does the trick. ECHO='print -r' elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && test "X$CONFIG_SHELL" != X/bin/ksh; then # If we have ksh, try running configure again with it. ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} export ORIGINAL_CONFIG_SHELL CONFIG_SHELL=/bin/ksh export CONFIG_SHELL exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} else # Try using printf. ECHO='printf %s\n' if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # Cool, printf works : elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL export CONFIG_SHELL SHELL="$CONFIG_SHELL" export SHELL ECHO="$CONFIG_SHELL [$]0 --fallback-echo" elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then ECHO="$CONFIG_SHELL [$]0 --fallback-echo" else # maybe with a smaller string... prev=: for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null then break fi prev="$cmd" done if test "$prev" != 'sed 50q "[$]0"'; then echo_test_string=`eval $prev` export echo_test_string exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} else # Oops. We lost completely, so just stick with echo. ECHO=echo fi fi fi fi fi fi # Copy echo and quote the copy suitably for passing to libtool from # the Makefile, instead of quoting the original, which is used later. lt_ECHO=$ECHO if test "X$lt_ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then lt_ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" fi AC_SUBST(lt_ECHO) ]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that does not interpret backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '[#]line __oline__ "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; sparc*-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) LD="${LD-ld} -m elf64_sparc" ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" ])# _LT_ENABLE_LOCK # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [AC_CHECK_TOOL(AR, ar, false) test -z "$AR" && AR=ar test -z "$AR_FLAGS" && AR_FLAGS=cru _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1]) AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" fi _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test x"[$]$2" = xyes; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" ]) if test x"[$]$2" = xyes; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ = "XX$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n $lt_cv_sys_max_cmd_len ; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "$cross_compiling" = yes; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line __oline__ "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif void fnord() { int i=42;} int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen="shl_load"], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen="dlopen"], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) ]) ]) ]) ]) ]) ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links="nottested" if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test "$hard_links" = no; then AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", [Define to the sub-directory in which libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then # We can hardcode non-existent directories. if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` else lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[[4-9]]*) version_type=linux need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$host_os in yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH printed by # mingw gcc, but we are running on Cygwin. Gcc prints its search # path with ; separators, and with drive letters. We can handle the # drive letters (cygwin fileutils understands them), so leave them, # especially as we might pass files found there to a mingw objdump, # which wouldn't understand a cygwinified path. Ahh. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; esac ;; *) library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' ;; esac dynamic_linker='Win32 ld.exe' # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd1*) dynamic_linker=no ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[123]]*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555. postinstall_cmds='chmod 555 $lib' ;; interix[[3-9]]*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be Linux ELF. linux* | k*bsd*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[[89]] | openbsd2.[[89]].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([], [sys_lib_dlsearch_path_spec], [2], [Run-time system search path for libraries]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program which can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$1; then lt_cv_path_MAGIC_CMD="$ac_dir/$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac]) MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program which can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test "$withval" = no || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; gnu*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be Linux ELF. linux* | k*bsd*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method == "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi]) if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. AC_CHECK_TOOLS(DUMPBIN, ["dumpbin -symbols" "link -dump -symbols"], :) AC_SUBST([DUMPBIN]) if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:__oline__: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:__oline__: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:__oline__: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM="-lm") ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test "$GCC" = yes; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ const struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_save_LIBS="$LIBS" lt_save_CFLAGS="$CFLAGS" LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS="$lt_save_LIBS" CFLAGS="$lt_save_CFLAGS" else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= AC_MSG_CHECKING([for $compiler option to produce PIC]) m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64 which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC*) # IBM XL 8.0 on PPC _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test "$GCC" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; pgcc* | pgf77* | pgf90* | pgf95*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl*) # IBM XL C 8.0/Fortran 10.1 on PPC _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Sun\ F*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_MSG_RESULT([$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ;; cygwin* | mingw* | cegcc*) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' ;; linux* | k*bsd*-gnu) _LT_TAGVAR(link_all_deplibs, $1)=no ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes if test "$with_gnu_ld" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.9.1, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to modify your PATH *** so that a non-GNU linker is found, and then restart. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag= tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; xl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi _LT_TAGVAR(link_all_deplibs, $1)=no else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; freebsd1*) _LT_TAGVAR(ld_shlibs, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; hpux10*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" AC_LINK_IFELSE(int foo(void) {}, _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' ) LDFLAGS="$save_LDFLAGS" else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' else case $host_os in openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ;; esac fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_MSG_CHECKING([whether -lc should be explicitly linked in]) $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then _LT_TAGVAR(archive_cmds_need_lc, $1)=no else _LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* AC_MSG_RESULT([$_LT_TAGVAR(archive_cmds_need_lc, $1)]) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1], [[If ld is used when linking, flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting ${shlibpath_var} if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [fix_srcfile_path], [1], [Fix the shell variable $srcfile for the compiler]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC="$CC" AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report which library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC="$lt_save_CC" ])# _LT_LANG_C_CONFIG # _LT_PROG_CXX # ------------ # Since AC_PROG_CXX is broken, in that it returns g++ if there is no c++ # compiler, we have our own version here. m4_defun([_LT_PROG_CXX], [ pushdef([AC_MSG_ERROR], [_lt_caught_CXX_error=yes]) AC_PROG_CXX if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi popdef([AC_MSG_ERROR]) ])# _LT_PROG_CXX dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([_LT_PROG_CXX], []) # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [AC_REQUIRE([_LT_PROG_CXX])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_caught_CXX_error" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test "$GXX" = yes; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='${wl}' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GXX" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared # libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd[[12]]*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; gnu*) ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; *) if test "$GXX" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]]* | *pgcpp\ [[1-5]]*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; *) # Version 6 will use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; xl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='echo' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd2*) # C++ shared libraries are fairly broken _LT_TAGVAR(ld_shlibs, $1)=no ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' fi output_verbose_link_cmd=echo else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='echo' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(GCC, $1)="$GXX" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test "$_lt_caught_CXX_error" != yes AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ]) dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case $p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" || test $p = "-R"; then prev=$p continue else prev= fi if test "$pre_test_object_deps_done" = no; then case $p in -L* | -R*) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)="${prev}${p}" else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" fi fi ;; *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test "$pre_test_object_deps_done" = no; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)="$p" else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)="$p" else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; solaris*) case $cc_basename in CC*) # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_PROG_F77 # ------------ # Since AC_PROG_F77 is broken, in that it returns the empty string # if there is no fortran compiler, we have our own version here. m4_defun([_LT_PROG_F77], [ pushdef([AC_MSG_ERROR], [_lt_disable_F77=yes]) AC_PROG_F77 if test -z "$F77" || test "X$F77" = "Xno"; then _lt_disable_F77=yes fi popdef([AC_MSG_ERROR]) ])# _LT_PROG_F77 dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([_LT_PROG_F77], []) # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_REQUIRE([_LT_PROG_F77])dnl AC_LANG_PUSH(Fortran 77) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_F77" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC CC=${F77-"f77"} compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$G77" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC="$lt_save_CC" fi # test "$_lt_disable_F77" != yes AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_PROG_FC # ----------- # Since AC_PROG_FC is broken, in that it returns the empty string # if there is no fortran compiler, we have our own version here. m4_defun([_LT_PROG_FC], [ pushdef([AC_MSG_ERROR], [_lt_disable_FC=yes]) AC_PROG_FC if test -z "$FC" || test "X$FC" = "Xno"; then _lt_disable_FC=yes fi popdef([AC_MSG_ERROR]) ])# _LT_PROG_FC dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([_LT_PROG_FC], []) # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_REQUIRE([_LT_PROG_FC])dnl AC_LANG_PUSH(Fortran) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_FC" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC CC=${FC-"f95"} compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC="$lt_save_CC" fi # test "$_lt_disable_FC" != yes AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC="$lt_save_CC" ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code="$lt_simple_compile_test_code" # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC GCC= CC=${RC-"windres"} compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC="$lt_save_CC" ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f $lt_ac_sed && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test $lt_ac_count -gt 10 && break lt_ac_count=`expr $lt_ac_count + 1` if test $lt_ac_count -gt $lt_ac_max; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [AC_MSG_CHECKING([whether the shell understands some XSI constructs]) # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes AC_MSG_RESULT([$xsi_shell]) _LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) AC_MSG_CHECKING([whether the shell understands "+="]) lt_shell_append=no ( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes AC_MSG_RESULT([$lt_shell_append]) _LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PROG_XSI_SHELLFNS # --------------------- # Bourne and XSI compatible variants of some useful shell functions. m4_defun([_LT_PROG_XSI_SHELLFNS], [case $xsi_shell in yes) cat << \_LT_EOF >> "$cfgfile" # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac } # func_basename file func_basename () { func_basename_result="${1##*/}" } # func_dirname_and_basename file append nondir_replacement # perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac func_basename_result="${1##*/}" } # func_stripname prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). func_stripname () { # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary parameter first. func_stripname_result=${3} func_stripname_result=${func_stripname_result#"${1}"} func_stripname_result=${func_stripname_result%"${2}"} } # func_opt_split func_opt_split () { func_opt_split_opt=${1%%=*} func_opt_split_arg=${1#*=} } # func_lo2o object func_lo2o () { case ${1} in *.lo) func_lo2o_result=${1%.lo}.${objext} ;; *) func_lo2o_result=${1} ;; esac } # func_xform libobj-or-source func_xform () { func_xform_result=${1%.*}.lo } # func_arith arithmetic-term... func_arith () { func_arith_result=$(( $[*] )) } # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=${#1} } _LT_EOF ;; *) # Bourne compatible functions. cat << \_LT_EOF >> "$cfgfile" # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi } # func_basename file func_basename () { func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` } dnl func_dirname_and_basename dnl A portable version of this function is already defined in general.m4sh dnl so there is no need for it here. # func_stripname prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # func_strip_suffix prefix name func_stripname () { case ${2} in .*) func_stripname_result=`$ECHO "X${3}" \ | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "X${3}" \ | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; esac } # sed scripts: my_sed_long_opt='1s/^\(-[[^=]]*\)=.*/\1/;q' my_sed_long_arg='1s/^-[[^=]]*=//' # func_opt_split func_opt_split () { func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` } # func_lo2o object func_lo2o () { func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` } # func_xform libobj-or-source func_xform () { func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[[^.]]*$/.lo/'` } # func_arith arithmetic-term... func_arith () { func_arith_result=`expr "$[@]"` } # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=`expr "$[1]" : ".*" 2>/dev/null || echo $max_cmd_len` } _LT_EOF esac case $lt_shell_append in yes) cat << \_LT_EOF >> "$cfgfile" # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "$[1]+=\$[2]" } _LT_EOF ;; *) cat << \_LT_EOF >> "$cfgfile" # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "$[1]=\$$[1]\$[2]" } _LT_EOF ;; esac ]) proftpd-dfsg-1.3.5~rc3/lib/libltdl/m4/ltdl.m40000644000175000017500000006327611301117674020501 0ustar frankiefrankie# ltdl.m4 - Configure ltdl for the target system. -*-Autoconf-*- # # Copyright (C) 1999-2006, 2007, 2008 Free Software Foundation, Inc. # Written by Thomas Tanner, 1999 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 17 LTDL_INIT # LT_CONFIG_LTDL_DIR(DIRECTORY, [LTDL-MODE]) # ------------------------------------------ # DIRECTORY contains the libltdl sources. It is okay to call this # function multiple times, as long as the same DIRECTORY is always given. AC_DEFUN([LT_CONFIG_LTDL_DIR], [AC_BEFORE([$0], [LTDL_INIT]) _$0($*) ])# LT_CONFIG_LTDL_DIR # We break this out into a separate macro, so that we can call it safely # internally without being caught accidentally by the sed scan in libtoolize. m4_defun([_LT_CONFIG_LTDL_DIR], [dnl remove trailing slashes m4_pushdef([_ARG_DIR], m4_bpatsubst([$1], [/*$])) m4_case(_LTDL_DIR, [], [dnl only set lt_ltdl_dir if _ARG_DIR is not simply `.' m4_if(_ARG_DIR, [.], [], [m4_define([_LTDL_DIR], _ARG_DIR) _LT_SHELL_INIT([lt_ltdl_dir=']_ARG_DIR['])])], [m4_if(_ARG_DIR, _LTDL_DIR, [], [m4_fatal([multiple libltdl directories: `]_LTDL_DIR[', `]_ARG_DIR['])])]) m4_popdef([_ARG_DIR]) ])# _LT_CONFIG_LTDL_DIR # Initialise: m4_define([_LTDL_DIR], []) # _LT_BUILD_PREFIX # ---------------- # If Autoconf is new enough, expand to `${top_build_prefix}', otherwise # to `${top_builddir}/'. m4_define([_LT_BUILD_PREFIX], [m4_ifdef([AC_AUTOCONF_VERSION], [m4_if(m4_version_compare(m4_defn([AC_AUTOCONF_VERSION]), [2.62]), [-1], [m4_ifdef([_AC_HAVE_TOP_BUILD_PREFIX], [${top_build_prefix}], [${top_builddir}/])], [${top_build_prefix}])], [${top_builddir}/])[]dnl ]) # LTDL_CONVENIENCE # ---------------- # sets LIBLTDL to the link flags for the libltdl convenience library and # LTDLINCL to the include flags for the libltdl header and adds # --enable-ltdl-convenience to the configure arguments. Note that # AC_CONFIG_SUBDIRS is not called here. LIBLTDL will be prefixed with # '${top_build_prefix}' if available, otherwise with '${top_builddir}/', # and LTDLINCL will be prefixed with '${top_srcdir}/' (note the single # quotes!). If your package is not flat and you're not using automake, # define top_build_prefix, top_builddir, and top_srcdir appropriately # in your Makefiles. AC_DEFUN([LTDL_CONVENIENCE], [AC_BEFORE([$0], [LTDL_INIT])dnl dnl Although the argument is deprecated and no longer documented, dnl LTDL_CONVENIENCE used to take a DIRECTORY orgument, if we have one dnl here make sure it is the same as any other declaration of libltdl's dnl location! This also ensures lt_ltdl_dir is set when configure.ac is dnl not yet using an explicit LT_CONFIG_LTDL_DIR. m4_ifval([$1], [_LT_CONFIG_LTDL_DIR([$1])])dnl _$0() ])# LTDL_CONVENIENCE # AC_LIBLTDL_CONVENIENCE accepted a directory argument in older libtools, # now we have LT_CONFIG_LTDL_DIR: AU_DEFUN([AC_LIBLTDL_CONVENIENCE], [_LT_CONFIG_LTDL_DIR([m4_default([$1], [libltdl])]) _LTDL_CONVENIENCE]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBLTDL_CONVENIENCE], []) # _LTDL_CONVENIENCE # ----------------- # Code shared by LTDL_CONVENIENCE and LTDL_INIT([convenience]). m4_defun([_LTDL_CONVENIENCE], [case $enable_ltdl_convenience in no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; "") enable_ltdl_convenience=yes ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; esac LIBLTDL='_LT_BUILD_PREFIX'"${lt_ltdl_dir+$lt_ltdl_dir/}libltdlc.la" LTDLDEPS=$LIBLTDL LTDLINCL='-I${top_srcdir}'"${lt_ltdl_dir+/$lt_ltdl_dir}" AC_SUBST([LIBLTDL]) AC_SUBST([LTDLDEPS]) AC_SUBST([LTDLINCL]) # For backwards non-gettext consistent compatibility... INCLTDL="$LTDLINCL" AC_SUBST([INCLTDL]) ])# _LTDL_CONVENIENCE # LTDL_INSTALLABLE # ---------------- # sets LIBLTDL to the link flags for the libltdl installable library # and LTDLINCL to the include flags for the libltdl header and adds # --enable-ltdl-install to the configure arguments. Note that # AC_CONFIG_SUBDIRS is not called from here. If an installed libltdl # is not found, LIBLTDL will be prefixed with '${top_build_prefix}' if # available, otherwise with '${top_builddir}/', and LTDLINCL will be # prefixed with '${top_srcdir}/' (note the single quotes!). If your # package is not flat and you're not using automake, define top_build_prefix, # top_builddir, and top_srcdir appropriately in your Makefiles. # In the future, this macro may have to be called after LT_INIT. AC_DEFUN([LTDL_INSTALLABLE], [AC_BEFORE([$0], [LTDL_INIT])dnl dnl Although the argument is deprecated and no longer documented, dnl LTDL_INSTALLABLE used to take a DIRECTORY orgument, if we have one dnl here make sure it is the same as any other declaration of libltdl's dnl location! This also ensures lt_ltdl_dir is set when configure.ac is dnl not yet using an explicit LT_CONFIG_LTDL_DIR. m4_ifval([$1], [_LT_CONFIG_LTDL_DIR([$1])])dnl _$0() ])# LTDL_INSTALLABLE # AC_LIBLTDL_INSTALLABLE accepted a directory argument in older libtools, # now we have LT_CONFIG_LTDL_DIR: AU_DEFUN([AC_LIBLTDL_INSTALLABLE], [_LT_CONFIG_LTDL_DIR([m4_default([$1], [libltdl])]) _LTDL_INSTALLABLE]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBLTDL_INSTALLABLE], []) # _LTDL_INSTALLABLE # ----------------- # Code shared by LTDL_INSTALLABLE and LTDL_INIT([installable]). m4_defun([_LTDL_INSTALLABLE], [if test -f $prefix/lib/libltdl.la; then lt_save_LDFLAGS="$LDFLAGS" LDFLAGS="-L$prefix/lib $LDFLAGS" AC_CHECK_LIB([ltdl], [lt_dlinit], [lt_lib_ltdl=yes]) LDFLAGS="$lt_save_LDFLAGS" if test x"${lt_lib_ltdl-no}" = xyes; then if test x"$enable_ltdl_install" != xyes; then # Don't overwrite $prefix/lib/libltdl.la without --enable-ltdl-install AC_MSG_WARN([not overwriting libltdl at $prefix, force with `--enable-ltdl-install']) enable_ltdl_install=no fi elif test x"$enable_ltdl_install" = xno; then AC_MSG_WARN([libltdl not installed, but installation disabled]) fi fi # If configure.ac declared an installable ltdl, and the user didn't override # with --disable-ltdl-install, we will install the shipped libltdl. case $enable_ltdl_install in no) ac_configure_args="$ac_configure_args --enable-ltdl-install=no" LIBLTDL="-lltdl" LTDLDEPS= LTDLINCL= ;; *) enable_ltdl_install=yes ac_configure_args="$ac_configure_args --enable-ltdl-install" LIBLTDL='_LT_BUILD_PREFIX'"${lt_ltdl_dir+$lt_ltdl_dir/}libltdl.la" LTDLDEPS=$LIBLTDL LTDLINCL='-I${top_srcdir}'"${lt_ltdl_dir+/$lt_ltdl_dir}" ;; esac AC_SUBST([LIBLTDL]) AC_SUBST([LTDLDEPS]) AC_SUBST([LTDLINCL]) # For backwards non-gettext consistent compatibility... INCLTDL="$LTDLINCL" AC_SUBST([INCLTDL]) ])# LTDL_INSTALLABLE # _LTDL_MODE_DISPATCH # ------------------- m4_define([_LTDL_MODE_DISPATCH], [dnl If _LTDL_DIR is `.', then we are configuring libltdl itself: m4_if(_LTDL_DIR, [], [], dnl if _LTDL_MODE was not set already, the default value is `subproject': [m4_case(m4_default(_LTDL_MODE, [subproject]), [subproject], [AC_CONFIG_SUBDIRS(_LTDL_DIR) _LT_SHELL_INIT([lt_dlopen_dir="$lt_ltdl_dir"])], [nonrecursive], [_LT_SHELL_INIT([lt_dlopen_dir="$lt_ltdl_dir"; lt_libobj_prefix="$lt_ltdl_dir/"])], [recursive], [], [m4_fatal([unknown libltdl mode: ]_LTDL_MODE)])])dnl dnl Be careful not to expand twice: m4_define([$0], []) ])# _LTDL_MODE_DISPATCH # _LT_LIBOBJ(MODULE_NAME) # ----------------------- # Like AC_LIBOBJ, except that MODULE_NAME goes into _LT_LIBOBJS instead # of into LIBOBJS. AC_DEFUN([_LT_LIBOBJ], [ m4_pattern_allow([^_LT_LIBOBJS$]) _LT_LIBOBJS="$_LT_LIBOBJS $1.$ac_objext" ])# _LT_LIBOBJS # LTDL_INIT([OPTIONS]) # -------------------- # Clients of libltdl can use this macro to allow the installer to # choose between a shipped copy of the ltdl sources or a preinstalled # version of the library. If the shipped ltdl sources are not in a # subdirectory named libltdl, the directory name must be given by # LT_CONFIG_LTDL_DIR. AC_DEFUN([LTDL_INIT], [dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) dnl We need to keep our own list of libobjs separate from our parent project, dnl and the easiest way to do that is redefine the AC_LIBOBJs macro while dnl we look for our own LIBOBJs. m4_pushdef([AC_LIBOBJ], m4_defn([_LT_LIBOBJ])) m4_pushdef([AC_LIBSOURCES]) dnl If not otherwise defined, default to the 1.5.x compatible subproject mode: m4_if(_LTDL_MODE, [], [m4_define([_LTDL_MODE], m4_default([$2], [subproject])) m4_if([-1], [m4_bregexp(_LTDL_MODE, [\(subproject\|\(non\)?recursive\)])], [m4_fatal([unknown libltdl mode: ]_LTDL_MODE)])]) AC_ARG_WITH([included_ltdl], [AS_HELP_STRING([--with-included-ltdl], [use the GNU ltdl sources included here])]) if test "x$with_included_ltdl" != xyes; then # We are not being forced to use the included libltdl sources, so # decide whether there is a useful installed version we can use. AC_CHECK_HEADER([ltdl.h], [AC_CHECK_DECL([lt_dlinterface_register], [AC_CHECK_LIB([ltdl], [lt_dladvise_preload], [with_included_ltdl=no], [with_included_ltdl=yes])], [with_included_ltdl=yes], [AC_INCLUDES_DEFAULT #include ])], [with_included_ltdl=yes], [AC_INCLUDES_DEFAULT] ) fi dnl If neither LT_CONFIG_LTDL_DIR, LTDL_CONVENIENCE nor LTDL_INSTALLABLE dnl was called yet, then for old times' sake, we assume libltdl is in an dnl eponymous directory: AC_PROVIDE_IFELSE([LT_CONFIG_LTDL_DIR], [], [_LT_CONFIG_LTDL_DIR([libltdl])]) AC_ARG_WITH([ltdl_include], [AS_HELP_STRING([--with-ltdl-include=DIR], [use the ltdl headers installed in DIR])]) if test -n "$with_ltdl_include"; then if test -f "$with_ltdl_include/ltdl.h"; then : else AC_MSG_ERROR([invalid ltdl include directory: `$with_ltdl_include']) fi else with_ltdl_include=no fi AC_ARG_WITH([ltdl_lib], [AS_HELP_STRING([--with-ltdl-lib=DIR], [use the libltdl.la installed in DIR])]) if test -n "$with_ltdl_lib"; then if test -f "$with_ltdl_lib/libltdl.la"; then : else AC_MSG_ERROR([invalid ltdl library directory: `$with_ltdl_lib']) fi else with_ltdl_lib=no fi case ,$with_included_ltdl,$with_ltdl_include,$with_ltdl_lib, in ,yes,no,no,) m4_case(m4_default(_LTDL_TYPE, [convenience]), [convenience], [_LTDL_CONVENIENCE], [installable], [_LTDL_INSTALLABLE], [m4_fatal([unknown libltdl build type: ]_LTDL_TYPE)]) ;; ,no,no,no,) # If the included ltdl is not to be used, then use the # preinstalled libltdl we found. AC_DEFINE([HAVE_LTDL], [1], [Define this if a modern libltdl is already installed]) LIBLTDL=-lltdl LTDLDEPS= LTDLINCL= ;; ,no*,no,*) AC_MSG_ERROR([`--with-ltdl-include' and `--with-ltdl-lib' options must be used together]) ;; *) with_included_ltdl=no LIBLTDL="-L$with_ltdl_lib -lltdl" LTDLDEPS= LTDLINCL="-I$with_ltdl_include" ;; esac INCLTDL="$LTDLINCL" # Report our decision... AC_MSG_CHECKING([where to find libltdl headers]) AC_MSG_RESULT([$LTDLINCL]) AC_MSG_CHECKING([where to find libltdl library]) AC_MSG_RESULT([$LIBLTDL]) _LTDL_SETUP dnl restore autoconf definition. m4_popdef([AC_LIBOBJ]) m4_popdef([AC_LIBSOURCES]) AC_CONFIG_COMMANDS_PRE([ _ltdl_libobjs= _ltdl_ltlibobjs= if test -n "$_LT_LIBOBJS"; then # Remove the extension. _lt_sed_drop_objext='s/\.o$//;s/\.obj$//' for i in `for i in $_LT_LIBOBJS; do echo "$i"; done | sed "$_lt_sed_drop_objext" | sort -u`; do _ltdl_libobjs="$_ltdl_libobjs $lt_libobj_prefix$i.$ac_objext" _ltdl_ltlibobjs="$_ltdl_ltlibobjs $lt_libobj_prefix$i.lo" done fi AC_SUBST([ltdl_LIBOBJS], [$_ltdl_libobjs]) AC_SUBST([ltdl_LTLIBOBJS], [$_ltdl_ltlibobjs]) ]) # Only expand once: m4_define([LTDL_INIT]) ])# LTDL_INIT # Old names: AU_DEFUN([AC_LIB_LTDL], [LTDL_INIT($@)]) AU_DEFUN([AC_WITH_LTDL], [LTDL_INIT($@)]) AU_DEFUN([LT_WITH_LTDL], [LTDL_INIT($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIB_LTDL], []) dnl AC_DEFUN([AC_WITH_LTDL], []) dnl AC_DEFUN([LT_WITH_LTDL], []) # _LTDL_SETUP # ----------- # Perform all the checks necessary for compilation of the ltdl objects # -- including compiler checks and header checks. This is a public # interface mainly for the benefit of libltdl's own configure.ac, most # other users should call LTDL_INIT instead. AC_DEFUN([_LTDL_SETUP], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_SYS_MODULE_EXT])dnl AC_REQUIRE([LT_SYS_MODULE_PATH])dnl AC_REQUIRE([LT_SYS_DLSEARCH_PATH])dnl AC_REQUIRE([LT_LIB_DLLOAD])dnl AC_REQUIRE([LT_SYS_SYMBOL_USCORE])dnl AC_REQUIRE([LT_FUNC_DLSYM_USCORE])dnl AC_REQUIRE([LT_SYS_DLOPEN_DEPLIBS])dnl AC_REQUIRE([gl_FUNC_ARGZ])dnl m4_require([_LT_CHECK_OBJDIR])dnl m4_require([_LT_HEADER_DLFCN])dnl m4_require([_LT_CHECK_DLPREOPEN])dnl m4_require([_LT_DECL_SED])dnl dnl Don't require this, or it will be expanded earlier than the code dnl that sets the variables it relies on: _LT_ENABLE_INSTALL dnl _LTDL_MODE specific code must be called at least once: _LTDL_MODE_DISPATCH # In order that ltdl.c can compile, find out the first AC_CONFIG_HEADERS # the user used. This is so that ltdl.h can pick up the parent projects # config.h file, The first file in AC_CONFIG_HEADERS must contain the # definitions required by ltdl.c. # FIXME: Remove use of undocumented AC_LIST_HEADERS (2.59 compatibility). AC_CONFIG_COMMANDS_PRE([dnl m4_pattern_allow([^LT_CONFIG_H$])dnl m4_ifset([AH_HEADER], [LT_CONFIG_H=AH_HEADER], [m4_ifset([AC_LIST_HEADERS], [LT_CONFIG_H=`echo "AC_LIST_HEADERS" | $SED 's,^[[ ]]*,,;s,[[ :]].*$,,'`], [])])]) AC_SUBST([LT_CONFIG_H]) AC_CHECK_HEADERS([unistd.h dl.h sys/dl.h dld.h mach-o/dyld.h dirent.h], [], [], [AC_INCLUDES_DEFAULT]) AC_CHECK_FUNCS([closedir opendir readdir], [], [AC_LIBOBJ([lt__dirent])]) AC_CHECK_FUNCS([strlcat strlcpy], [], [AC_LIBOBJ([lt__strl])]) AC_DEFINE_UNQUOTED([LT_LIBEXT],["$libext"],[The archive extension]) name=ltdl LTDLOPEN=`eval "\\$ECHO \"$libname_spec\""` AC_SUBST([LTDLOPEN]) ])# _LTDL_SETUP # _LT_ENABLE_INSTALL # ------------------ dnl NOTE: I have deliberately emasculated this macro, since proftpd will never dnl provide an installable libltdl. m4_define([_LT_ENABLE_INSTALL]) # LT_SYS_DLOPEN_DEPLIBS # --------------------- AC_DEFUN([LT_SYS_DLOPEN_DEPLIBS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_CACHE_CHECK([whether deplibs are loaded by dlopen], [lt_cv_sys_dlopen_deplibs], [# PORTME does your system automatically load deplibs for dlopen? # or its logical equivalent (e.g. shl_load for HP-UX < 11) # For now, we just catch OSes we know something about -- in the # future, we'll try test this programmatically. lt_cv_sys_dlopen_deplibs=unknown case $host_os in aix3*|aix4.1.*|aix4.2.*) # Unknown whether this is true for these versions of AIX, but # we want this `case' here to explicitly catch those versions. lt_cv_sys_dlopen_deplibs=unknown ;; aix[[4-9]]*) lt_cv_sys_dlopen_deplibs=yes ;; amigaos*) case $host_cpu in powerpc) lt_cv_sys_dlopen_deplibs=no ;; esac ;; darwin*) # Assuming the user has installed a libdl from somewhere, this is true # If you are looking for one http://www.opendarwin.org/projects/dlcompat lt_cv_sys_dlopen_deplibs=yes ;; freebsd* | dragonfly*) lt_cv_sys_dlopen_deplibs=yes ;; gnu* | linux* | k*bsd*-gnu) # GNU and its variants, using gnu ld.so (Glibc) lt_cv_sys_dlopen_deplibs=yes ;; hpux10*|hpux11*) lt_cv_sys_dlopen_deplibs=yes ;; interix*) lt_cv_sys_dlopen_deplibs=yes ;; irix[[12345]]*|irix6.[[01]]*) # Catch all versions of IRIX before 6.2, and indicate that we don't # know how it worked for any of those versions. lt_cv_sys_dlopen_deplibs=unknown ;; irix*) # The case above catches anything before 6.2, and it's known that # at 6.2 and later dlopen does load deplibs. lt_cv_sys_dlopen_deplibs=yes ;; netbsd* | netbsdelf*-gnu) lt_cv_sys_dlopen_deplibs=yes ;; openbsd*) lt_cv_sys_dlopen_deplibs=yes ;; osf[[1234]]*) # dlopen did load deplibs (at least at 4.x), but until the 5.x series, # it did *not* use an RPATH in a shared library to find objects the # library depends on, so we explicitly say `no'. lt_cv_sys_dlopen_deplibs=no ;; osf5.0|osf5.0a|osf5.1) # dlopen *does* load deplibs and with the right loader patch applied # it even uses RPATH in a shared library to search for shared objects # that the library depends on, but there's no easy way to know if that # patch is installed. Since this is the case, all we can really # say is unknown -- it depends on the patch being installed. If # it is, this changes to `yes'. Without it, it would be `no'. lt_cv_sys_dlopen_deplibs=unknown ;; osf*) # the two cases above should catch all versions of osf <= 5.1. Read # the comments above for what we know about them. # At > 5.1, deplibs are loaded *and* any RPATH in a shared library # is used to find them so we can finally say `yes'. lt_cv_sys_dlopen_deplibs=yes ;; qnx*) lt_cv_sys_dlopen_deplibs=yes ;; solaris*) lt_cv_sys_dlopen_deplibs=yes ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) libltdl_cv_sys_dlopen_deplibs=yes ;; esac ]) if test "$lt_cv_sys_dlopen_deplibs" != yes; then AC_DEFINE([LTDL_DLOPEN_DEPLIBS], [1], [Define if the OS needs help to load dependent libraries for dlopen().]) fi ])# LT_SYS_DLOPEN_DEPLIBS # Old name: AU_ALIAS([AC_LTDL_SYS_DLOPEN_DEPLIBS], [LT_SYS_DLOPEN_DEPLIBS]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LTDL_SYS_DLOPEN_DEPLIBS], []) # LT_SYS_MODULE_EXT # ----------------- AC_DEFUN([LT_SYS_MODULE_EXT], [m4_require([_LT_SYS_DYNAMIC_LINKER])dnl AC_CACHE_CHECK([which extension is used for runtime loadable modules], [libltdl_cv_shlibext], [ module=yes eval libltdl_cv_shlibext=$shrext_cmds ]) if test -n "$libltdl_cv_shlibext"; then m4_pattern_allow([LT_MODULE_EXT])dnl AC_DEFINE_UNQUOTED([LT_MODULE_EXT], ["$libltdl_cv_shlibext"], [Define to the extension used for runtime loadable modules, say, ".so".]) fi ])# LT_SYS_MODULE_EXT # Old name: AU_ALIAS([AC_LTDL_SHLIBEXT], [LT_SYS_MODULE_EXT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LTDL_SHLIBEXT], []) # LT_SYS_MODULE_PATH # ------------------ AC_DEFUN([LT_SYS_MODULE_PATH], [m4_require([_LT_SYS_DYNAMIC_LINKER])dnl AC_CACHE_CHECK([which variable specifies run-time module search path], [lt_cv_module_path_var], [lt_cv_module_path_var="$shlibpath_var"]) if test -n "$lt_cv_module_path_var"; then m4_pattern_allow([LT_MODULE_PATH_VAR])dnl AC_DEFINE_UNQUOTED([LT_MODULE_PATH_VAR], ["$lt_cv_module_path_var"], [Define to the name of the environment variable that determines the run-time module search path.]) fi ])# LT_SYS_MODULE_PATH # Old name: AU_ALIAS([AC_LTDL_SHLIBPATH], [LT_SYS_MODULE_PATH]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LTDL_SHLIBPATH], []) # LT_SYS_DLSEARCH_PATH # -------------------- AC_DEFUN([LT_SYS_DLSEARCH_PATH], [m4_require([_LT_SYS_DYNAMIC_LINKER])dnl AC_CACHE_CHECK([for the default library search path], [lt_cv_sys_dlsearch_path], [lt_cv_sys_dlsearch_path="$sys_lib_dlsearch_path_spec"]) if test -n "$lt_cv_sys_dlsearch_path"; then sys_dlsearch_path= for dir in $lt_cv_sys_dlsearch_path; do if test -z "$sys_dlsearch_path"; then sys_dlsearch_path="$dir" else sys_dlsearch_path="$sys_dlsearch_path$PATH_SEPARATOR$dir" fi done m4_pattern_allow([LT_DLSEARCH_PATH])dnl AC_DEFINE_UNQUOTED([LT_DLSEARCH_PATH], ["$sys_dlsearch_path"], [Define to the system default library search path.]) fi ])# LT_SYS_DLSEARCH_PATH # Old name: AU_ALIAS([AC_LTDL_SYSSEARCHPATH], [LT_SYS_DLSEARCH_PATH]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LTDL_SYSSEARCHPATH], []) # _LT_CHECK_DLPREOPEN # ------------------- m4_defun([_LT_CHECK_DLPREOPEN], [m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl AC_CACHE_CHECK([whether libtool supports -dlopen/-dlpreopen], [libltdl_cv_preloaded_symbols], [if test -n "$lt_cv_sys_global_symbol_pipe"; then libltdl_cv_preloaded_symbols=yes else libltdl_cv_preloaded_symbols=no fi ]) if test x"$libltdl_cv_preloaded_symbols" = xyes; then AC_DEFINE([HAVE_PRELOADED_SYMBOLS], [1], [Define if libtool can extract symbol lists from object files.]) fi ])# _LT_CHECK_DLPREOPEN # LT_LIB_DLLOAD # ------------- AC_DEFUN([LT_LIB_DLLOAD], [m4_pattern_allow([^LT_DLLOADERS$]) LT_DLLOADERS= AC_SUBST([LT_DLLOADERS]) AC_LANG_PUSH([C]) LIBADD_DLOPEN= AC_SEARCH_LIBS([dlopen], [dl], [AC_DEFINE([HAVE_LIBDL], [1], [Define if you have the libdl library or equivalent.]) if test "$ac_cv_search_dlopen" != "none required" ; then LIBADD_DLOPEN="-ldl" fi libltdl_cv_lib_dl_dlopen="yes" LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la"], [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#if HAVE_DLFCN_H # include #endif ]], [[dlopen(0, 0);]])], [AC_DEFINE([HAVE_LIBDL], [1], [Define if you have the libdl library or equivalent.]) libltdl_cv_func_dlopen="yes" LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la"], [AC_CHECK_LIB([svld], [dlopen], [AC_DEFINE([HAVE_LIBDL], [1], [Define if you have the libdl library or equivalent.]) LIBADD_DLOPEN="-lsvld" libltdl_cv_func_dlopen="yes" LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la"])])]) if test x"$libltdl_cv_func_dlopen" = xyes || test x"$libltdl_cv_lib_dl_dlopen" = xyes then lt_save_LIBS="$LIBS" LIBS="$LIBS $LIBADD_DLOPEN" AC_CHECK_FUNCS([dlerror]) LIBS="$lt_save_LIBS" fi AC_SUBST([LIBADD_DLOPEN]) LIBADD_SHL_LOAD= AC_CHECK_FUNC([shl_load], [AC_DEFINE([HAVE_SHL_LOAD], [1], [Define if you have the shl_load function.]) LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}shl_load.la"], [AC_CHECK_LIB([dld], [shl_load], [AC_DEFINE([HAVE_SHL_LOAD], [1], [Define if you have the shl_load function.]) LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}shl_load.la" LIBADD_SHL_LOAD="-ldld"])]) AC_SUBST([LIBADD_SHL_LOAD]) case $host_os in darwin[[1567]].*) # We only want this for pre-Mac OS X 10.4. AC_CHECK_FUNC([_dyld_func_lookup], [AC_DEFINE([HAVE_DYLD], [1], [Define if you have the _dyld_func_lookup function.]) LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dyld.la"]) ;; beos*) LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}load_add_on.la" ;; cygwin* | mingw* | os2* | pw32*) AC_CHECK_DECLS([cygwin_conv_path], [], [], [[#include ]]) LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}loadlibrary.la" ;; esac AC_CHECK_LIB([dld], [dld_link], [AC_DEFINE([HAVE_DLD], [1], [Define if you have the GNU dld library.]) LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dld_link.la"]) AC_SUBST([LIBADD_DLD_LINK]) m4_pattern_allow([^LT_DLPREOPEN$]) LT_DLPREOPEN= if test -n "$LT_DLLOADERS" then for lt_loader in $LT_DLLOADERS; do LT_DLPREOPEN="$LT_DLPREOPEN-dlpreopen $lt_loader " done AC_DEFINE([HAVE_LIBDLLOADER], [1], [Define if libdlloader will be built on this platform]) fi AC_SUBST([LT_DLPREOPEN]) dnl This isn't used anymore, but set it for backwards compatibility LIBADD_DL="$LIBADD_DLOPEN $LIBADD_SHL_LOAD" AC_SUBST([LIBADD_DL]) AC_LANG_POP ])# LT_LIB_DLLOAD # Old name: AU_ALIAS([AC_LTDL_DLLIB], [LT_LIB_DLLOAD]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LTDL_DLLIB], []) # LT_SYS_SYMBOL_USCORE # -------------------- # does the compiler prefix global symbols with an underscore? AC_DEFUN([LT_SYS_SYMBOL_USCORE], [m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl AC_CACHE_CHECK([for _ prefix in compiled symbols], [lt_cv_sys_symbol_underscore], [lt_cv_sys_symbol_underscore=no cat > conftest.$ac_ext <<_LT_EOF void nm_test_func(){} int main(){nm_test_func;return 0;} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. ac_nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then # See whether the symbols have a leading underscore. if grep '^. _nm_test_func' "$ac_nlist" >/dev/null; then lt_cv_sys_symbol_underscore=yes else if grep '^. nm_test_func ' "$ac_nlist" >/dev/null; then : else echo "configure: cannot find nm_test_func in $ac_nlist" >&AS_MESSAGE_LOG_FD fi fi else echo "configure: cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "configure: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.c >&AS_MESSAGE_LOG_FD fi rm -rf conftest* ]) sys_symbol_underscore=$lt_cv_sys_symbol_underscore AC_SUBST([sys_symbol_underscore]) ])# LT_SYS_SYMBOL_USCORE # Old name: AU_ALIAS([AC_LTDL_SYMBOL_USCORE], [LT_SYS_SYMBOL_USCORE]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LTDL_SYMBOL_USCORE], []) # LT_FUNC_DLSYM_USCORE # -------------------- AC_DEFUN([LT_FUNC_DLSYM_USCORE], [AC_REQUIRE([LT_SYS_SYMBOL_USCORE])dnl if test x"$lt_cv_sys_symbol_underscore" = xyes; then if test x"$libltdl_cv_func_dlopen" = xyes || test x"$libltdl_cv_lib_dl_dlopen" = xyes ; then AC_CACHE_CHECK([whether we have to add an underscore for dlsym], [libltdl_cv_need_uscore], [libltdl_cv_need_uscore=unknown save_LIBS="$LIBS" LIBS="$LIBS $LIBADD_DLOPEN" _LT_TRY_DLOPEN_SELF( [libltdl_cv_need_uscore=no], [libltdl_cv_need_uscore=yes], [], [libltdl_cv_need_uscore=cross]) LIBS="$save_LIBS" ]) fi fi if test x"$libltdl_cv_need_uscore" = xyes; then AC_DEFINE([NEED_USCORE], [1], [Define if dlsym() requires a leading underscore in symbol names.]) fi ])# LT_FUNC_DLSYM_USCORE # Old name: AU_ALIAS([AC_LTDL_DLSYM_USCORE], [LT_FUNC_DLSYM_USCORE]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LTDL_DLSYM_USCORE], []) proftpd-dfsg-1.3.5~rc3/lib/libltdl/m4/ltversion.m40000644000175000017500000000127511300565264021557 0ustar frankiefrankie# ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # Generated from ltversion.in. # serial 3012 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.2.6]) m4_define([LT_PACKAGE_REVISION], [1.3012]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.2.6' macro_revision='1.3012' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) proftpd-dfsg-1.3.5~rc3/lib/libltdl/m4/lt~obsolete.m40000644000175000017500000001311311300565264022076 0ustar frankiefrankie# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 4 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_RC], [AC_DEFUN([AC_LIBTOOL_RC])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) proftpd-dfsg-1.3.5~rc3/lib/libltdl/m4/ltoptions.m40000644000175000017500000002724211300565264021567 0ustar frankiefrankie# Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option `$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl `shared' nor `disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [0], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [0], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [0], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the `shared' and # `disable-shared' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the `static' and # `disable-static' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the `fast-install' # and `disable-fast-install' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the `pic-only' and `no-pic' # LT_INIT options. # MODE is either `yes' or `no'. If omitted, it defaults to `both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [pic_mode="$withval"], [pic_mode=default]) test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) proftpd-dfsg-1.3.5~rc3/lib/libltdl/m4/argz.m40000644000175000017500000000506711300565264020500 0ustar frankiefrankie# Portability macros for glibc argz. -*- Autoconf -*- # # Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc. # Written by Gary V. Vaughan # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 5 argz.m4 AC_DEFUN([gl_FUNC_ARGZ], [gl_PREREQ_ARGZ AC_CHECK_HEADERS([argz.h], [], [], [AC_INCLUDES_DEFAULT]) AC_CHECK_TYPES([error_t], [], [AC_DEFINE([error_t], [int], [Define to a type to use for `error_t' if it is not otherwise available.]) AC_DEFINE([__error_t_defined], [1], [Define so that glibc/gnulib argp.h does not typedef error_t.])], [#if defined(HAVE_ARGZ_H) # include #endif]) ARGZ_H= AC_CHECK_FUNCS([argz_add argz_append argz_count argz_create_sep argz_insert \ argz_next argz_stringify], [], [ARGZ_H=argz.h; AC_LIBOBJ([argz])]) dnl if have system argz functions, allow forced use of dnl libltdl-supplied implementation (and default to do so dnl on "known bad" systems). Could use a runtime check, but dnl (a) detecting malloc issues is notoriously unreliable dnl (b) only known system that declares argz functions, dnl provides them, yet they are broken, is cygwin dnl releases prior to 16-Mar-2007 (1.5.24 and earlier) dnl So, it's more straightforward simply to special case dnl this for known bad systems. AS_IF([test -z "$ARGZ_H"], [AC_CACHE_CHECK( [if argz actually works], [lt_cv_sys_argz_works], [[case $host_os in #( *cygwin*) lt_cv_sys_argz_works=no if test "$cross_compiling" != no; then lt_cv_sys_argz_works="guessing no" else lt_sed_extract_leading_digits='s/^\([0-9\.]*\).*/\1/' save_IFS=$IFS IFS=-. set x `uname -r | sed -e "$lt_sed_extract_leading_digits"` IFS=$save_IFS lt_os_major=${2-0} lt_os_minor=${3-0} lt_os_micro=${4-0} if test "$lt_os_major" -gt 1 \ || { test "$lt_os_major" -eq 1 \ && { test "$lt_os_minor" -gt 5 \ || { test "$lt_os_minor" -eq 5 \ && test "$lt_os_micro" -gt 24; }; }; }; then lt_cv_sys_argz_works=yes fi fi ;; #( *) lt_cv_sys_argz_works=yes ;; esac]]) AS_IF([test $lt_cv_sys_argz_works = yes], [AC_DEFINE([HAVE_WORKING_ARGZ], 1, [This value is set to 1 to indicate that the system argz facility works])], [ARGZ_H=argz.h AC_LIBOBJ([argz])])]) AC_SUBST([ARGZ_H]) ]) # Prerequisites of lib/argz.c. AC_DEFUN([gl_PREREQ_ARGZ], [:]) proftpd-dfsg-1.3.5~rc3/lib/libltdl/m4/ltsugar.m40000644000175000017500000001042411300565264021207 0ustar frankiefrankie# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59 which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) proftpd-dfsg-1.3.5~rc3/lib/libltdl/aclocal.m40000644000175000017500000007725411300565263020621 0ustar frankiefrankie# generated automatically by aclocal 1.10.1 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(AC_AUTOCONF_VERSION, [2.61],, [m4_warning([this file was generated for autoconf 2.61. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically `autoreconf'.])]) # Copyright (C) 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.10' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.10.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AC_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.10.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(AC_AUTOCONF_VERSION)]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to # `$srcdir', `$srcdir/..', or `$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is `.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 8 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ(2.52)dnl ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 9 # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "GCJ", or "OBJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], UPC, [depcc="$UPC" am_compiler_list=], [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE(dependency-tracking, [ --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. #serial 3 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [for mf in $CONFIG_FILES; do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each `.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 13 # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.60])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) AM_MISSING_PROG(AUTOCONF, autoconf) AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) AM_MISSING_PROG(AUTOHEADER, autoheader) AM_MISSING_PROG(MAKEINFO, makeinfo) AM_PROG_INSTALL_SH AM_PROG_INSTALL_STRIP AC_REQUIRE([AM_PROG_MKDIR_P])dnl # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES(CC)], [define([AC_PROG_CC], defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES(OBJC)], [define([AC_PROG_OBJC], defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl ]) ]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"} AC_SUBST(install_sh)]) # Copyright (C) 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 3 # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo done .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 5 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it supports --run. # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_MKDIR_P # --------------- # Check for `mkdir -p'. AC_DEFUN([AM_PROG_MKDIR_P], [AC_PREREQ([2.60])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, dnl while keeping a definition of mkdir_p for backward compatibility. dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of dnl Makefile.ins that do not define MKDIR_P, so we do our own dnl adjustment using top_builddir (which is defined more often than dnl MKDIR_P). AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl case $mkdir_p in [[\\/$]]* | ?:[[\\/]]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 3 # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # ------------------------------ # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) # _AM_SET_OPTIONS(OPTIONS) # ---------------------------------- # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 4 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftest.file` fi rm -f conftest.file if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT(yes)]) # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in `make install-strip', and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be `maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of `v7', `ustar', or `pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. AM_MISSING_PROG([AMTAR], [tar]) m4_if([$1], [v7], [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of `-'. for _am_tool in $_am_tools do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([m4/argz.m4]) m4_include([m4/libtool.m4]) m4_include([m4/ltdl.m4]) m4_include([m4/ltoptions.m4]) m4_include([m4/ltsugar.m4]) m4_include([m4/ltversion.m4]) m4_include([m4/lt~obsolete.m4]) proftpd-dfsg-1.3.5~rc3/lib/libltdl/COPYING.LIB0000644000175000017500000006365611146444656020434 0ustar frankiefrankie GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. ^L Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. ^L GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. ^L Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. ^L 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. ^L 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. ^L 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. ^L 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS ^L How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! proftpd-dfsg-1.3.5~rc3/lib/libltdl/README0000644000175000017500000000276611300565263017635 0ustar frankiefrankieThis is GNU libltdl, a system independent dlopen wrapper for GNU libtool. It supports the following dlopen interfaces: * dlopen (Solaris, Linux and various BSD flavors) * shl_load (HP-UX) * LoadLibrary (Win16 and Win32) * load_add_on (BeOS) * GNU DLD (emulates dynamic linking for static libraries) * dyld (darwin/Mac OS X) * libtool's dlpreopen -- Copyright (C) 1999, 2003 Free Software Foundation, Inc. Written by Thomas Tanner, 1999 This file is part of GNU Libtool. GNU Libtool is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exception to the GNU General Public License, if you distribute this file as part of a program or library that is built using GNU Libtool, you may include this file under the same distribution terms that you use for the rest of that program. GNU Libtool is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Libtool; see the file COPYING. If not, a copy can be downloaded from http://www.gnu.org/licenses/gpl.html, or obtained by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. proftpd-dfsg-1.3.5~rc3/lib/libltdl/configure0000755000175000017500000153526611300565263020673 0ustar frankiefrankie#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for libltdl 2.2.6. # # Report bugs to . # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) as_nl=' ' IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH if test "x$CONFIG_SHELL" = x; then if (eval ":") 2>/dev/null; then as_have_required=yes else as_have_required=no fi if test $as_have_required = yes && (eval ": (as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=\$LINENO as_lineno_2=\$LINENO test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } ") 2> /dev/null; then : else as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. case $as_dir in /*) for as_base in sh bash ksh sh5; do as_candidate_shells="$as_candidate_shells $as_dir/$as_base" done;; esac done IFS=$as_save_IFS for as_shell in $as_candidate_shells $SHELL; do # Try only shells that exist, to save several forks. if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { ("$as_shell") 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi : _ASEOF }; then CONFIG_SHELL=$as_shell as_have_required=yes if { "$as_shell" 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi : (as_func_return () { (exit $1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = "$1" ); then : else exitcode=1 echo positional parameters were not saved. fi test $exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } _ASEOF }; then break fi fi done if test "x$CONFIG_SHELL" != x; then for as_var in BASH_ENV ENV do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test $as_have_required = no; then echo This script requires a shell more modern than all the echo shells that I found on your system. Please install a echo modern shell, or manually run the script under such a echo shell if you do have one. { (exit 1); exit 1; } fi fi fi (eval "as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0") || { echo No shell found that supports shell functions. echo Please tell autoconf@gnu.org about your system, echo including any error possibly output before this echo message } as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir fi echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # Check that we are running under the correct shell. SHELL=${CONFIG_SHELL-/bin/sh} case X$lt_ECHO in X*--fallback-echo) # Remove one level of quotation (which was required for Make). ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','` ;; esac ECHO=${lt_ECHO-echo} if test "X$1" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test "X$1" = X--fallback-echo; then # Avoid inline document here, it may be left over : elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then # Yippee, $ECHO works! : else # Restart under the correct shell. exec $SHELL "$0" --no-reexec ${1+"$@"} fi if test "X$1" = X--fallback-echo; then # used as fallback echo shift cat <<_LT_EOF $* _LT_EOF exit 0 fi # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test -z "$lt_ECHO"; then if test "X${echo_test_string+set}" != Xset; then # find a string as large as possible, as long as the shell can cope with it for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... if { echo_test_string=`eval $cmd`; } 2>/dev/null && { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null then break fi done fi if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then : else # The Solaris, AIX, and Digital Unix default echo programs unquote # backslashes. This makes it impossible to quote backslashes using # echo "$something" | sed 's/\\/\\\\/g' # # So, first we look for a working echo in the user's PATH. lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for dir in $PATH /usr/ucb; do IFS="$lt_save_ifs" if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then ECHO="$dir/echo" break fi done IFS="$lt_save_ifs" if test "X$ECHO" = Xecho; then # We didn't find a better echo, so look for alternatives. if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # This shell has a builtin print -r that does the trick. ECHO='print -r' elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && test "X$CONFIG_SHELL" != X/bin/ksh; then # If we have ksh, try running configure again with it. ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} export ORIGINAL_CONFIG_SHELL CONFIG_SHELL=/bin/ksh export CONFIG_SHELL exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} else # Try using printf. ECHO='printf %s\n' if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # Cool, printf works : elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL export CONFIG_SHELL SHELL="$CONFIG_SHELL" export SHELL ECHO="$CONFIG_SHELL $0 --fallback-echo" elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then ECHO="$CONFIG_SHELL $0 --fallback-echo" else # maybe with a smaller string... prev=: for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null then break fi prev="$cmd" done if test "$prev" != 'sed 50q "$0"'; then echo_test_string=`eval $prev` export echo_test_string exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} else # Oops. We lost completely, so just stick with echo. ECHO=echo fi fi fi fi fi fi # Copy echo and quote the copy suitably for passing to libtool from # the Makefile, instead of quoting the original, which is used later. lt_ECHO=$ECHO if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" fi exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='libltdl' PACKAGE_TARNAME='libltdl' PACKAGE_VERSION='2.2.6' PACKAGE_STRING='libltdl 2.2.6' PACKAGE_BUGREPORT='bug-libtool@gnu.org' ac_unique_file="ltdl.c" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datarootdir datadir sysconfdir sharedstatedir localstatedir includedir oldincludedir docdir infodir htmldir dvidir pdfdir psdir libdir localedir mandir DEFS ECHO_C ECHO_N ECHO_T LIBS build_alias host_alias target_alias INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA am__isrc CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar AS DLLTOOL OBJDUMP LIBTOOL build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE SED GREP EGREP FGREP LD DUMPBIN ac_ct_DUMPBIN NM LN_S AR RANLIB lt_ECHO DSYMUTIL NMEDIT LIPO OTOOL OTOOL64 CPP LT_DLLOADERS LIBADD_DLOPEN LIBADD_SHL_LOAD LIBADD_DLD_LINK LT_DLPREOPEN LIBADD_DL sys_symbol_underscore LIBOBJS ARGZ_H INSTALL_LTDL_TRUE INSTALL_LTDL_FALSE CONVENIENCE_LTDL_TRUE CONVENIENCE_LTDL_FALSE LT_CONFIG_H LTDLOPEN LTLIBOBJS' ac_subst_files='' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` eval enable_$ac_feature=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` eval enable_$ac_feature=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/[-.]/_/g'` eval with_$ac_package=\$ac_optarg ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/[-.]/_/g'` eval with_$ac_package=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) { echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute directory names. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; } done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || { echo "$as_me: error: Working directory cannot be determined" >&2 { (exit 1); exit 1; }; } test "X$ac_ls_di" = "X$ac_pwd_ls_di" || { echo "$as_me: error: pwd does not report name of working directory" >&2 { (exit 1); exit 1; }; } # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$0" || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X"$0" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 { (exit 1); exit 1; }; } pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures libltdl 2.2.6 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/libltdl] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of libltdl 2.2.6:";; esac cat <<\_ACEOF Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors --disable-libtool-lock avoid locking (might break parallel builds) --enable-ltdl-install install libltdl Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic try to use only PIC/non-PIC objects [default=use both] --with-gnu-ld assume the C compiler uses GNU ld [default=no] Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF libltdl configure 2.2.6 generated by GNU Autoconf 2.61 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by libltdl $as_me 2.2.6, which was generated by GNU Autoconf 2.61. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( *) $as_unset $ac_var ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------------- ## ## File substitutions. ## ## ------------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo cat confdefs.h echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. if test -n "$CONFIG_SITE"; then set x "$CONFIG_SITE" elif test "x$prefix" != xNONE; then set x "$prefix/share/config.site" "$prefix/etc/config.site" else set x "$ac_default_prefix/share/config.site" \ "$ac_default_prefix/etc/config.site" fi shift for ac_site_file do if test -r "$ac_site_file"; then { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { echo "$as_me:$LINENO: creating cache $cache_file" >&5 echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers config.h:config-h.in" ac_aux_dir= for ac_dir in config "$srcdir"/config; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in config \"$srcdir\"/config" >&5 echo "$as_me: error: cannot find install-sh or install.sh in config \"$srcdir\"/config" >&2;} { (exit 1); exit 1; }; } fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # I am me! ## ------------------------ ## ## Automake Initialisation. ## ## ------------------------ ## am__api_version='1.10' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. { echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done IFS=$as_save_IFS fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { echo "$as_me:$LINENO: checking whether build environment is sane" >&5 echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6; } # Just in case sleep 1 echo timestamp > conftest.file # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftest.file` fi rm -f conftest.file if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&5 echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&2;} { (exit 1); exit 1; }; } fi test "$2" = conftest.file ) then # Ok. : else { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! Check your system clock" >&5 echo "$as_me: error: newly created file is older than distributed files! Check your system clock" >&2;} { (exit 1); exit 1; }; } fi { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. echo might interpret backslashes. # By default was `s,x,x', remove it if useless. cat <<\_ACEOF >conftest.sed s/[\\$]/&&/g;s/;s,x,x,$// _ACEOF program_transform_name=`echo $program_transform_name | sed -f conftest.sed` rm -f conftest.sed # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi { echo "$as_me:$LINENO: checking for a thread-safe mkdir -p" >&5 echo $ECHO_N "checking for a thread-safe mkdir -p... $ECHO_C" >&6; } if test -z "$MKDIR_P"; then if test "${ac_cv_path_mkdir+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. test -d ./--version && rmdir ./--version MKDIR_P="$ac_install_sh -d" fi fi { echo "$as_me:$LINENO: result: $MKDIR_P" >&5 echo "${ECHO_T}$MKDIR_P" >&6; } mkdir_p="$MKDIR_P" case $mkdir_p in [\\/$]* | ?:[\\/]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_AWK+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AWK="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { echo "$as_me:$LINENO: result: $AWK" >&5 echo "${ECHO_T}$AWK" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$AWK" && break done { echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; } set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } SET_MAKE= else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} { (exit 1); exit 1; }; } fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='libltdl' VERSION='2.2.6' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"} # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { echo "$as_me:$LINENO: result: $STRIP" >&5 echo "${ECHO_T}$STRIP" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 echo "${ECHO_T}$ac_ct_STRIP" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. AMTAR=${AMTAR-"${am_missing_run}tar"} am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' ## ------------------------------- ## ## Libtool specific configuration. ## ## ------------------------------- ## pkgdatadir='${datadir}'"/${PACKAGE}" ## ----------------------- ## ## Libtool initialisation. ## ## ----------------------- ## case `pwd` in *\ * | *\ *) { echo "$as_me:$LINENO: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.2.6' macro_revision='1.3012' ltmain="$ac_aux_dir/ltmain.sh" # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} { (exit 1); exit 1; }; } { echo "$as_me:$LINENO: checking build system type" >&5 echo $ECHO_N "checking build system type... $ECHO_C" >&6; } if test "${ac_cv_build+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 echo "$as_me: error: cannot guess build type; you must specify one" >&2;} { (exit 1); exit 1; }; } ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} { (exit 1); exit 1; }; } fi { echo "$as_me:$LINENO: result: $ac_cv_build" >&5 echo "${ECHO_T}$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 echo "$as_me: error: invalid value of canonical build" >&2;} { (exit 1); exit 1; }; };; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { echo "$as_me:$LINENO: checking host system type" >&5 echo $ECHO_N "checking host system type... $ECHO_C" >&6; } if test "${ac_cv_host+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} { (exit 1); exit 1; }; } fi fi { echo "$as_me:$LINENO: result: $ac_cv_host" >&5 echo "${ECHO_T}$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 echo "$as_me: error: invalid value of canonical host" >&2;} { (exit 1); exit 1; }; };; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo done .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi { echo "$as_me:$LINENO: result: $_am_result" >&5 echo "${ECHO_T}$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } # Provide some information about the compiler. echo "$as_me:$LINENO: checking for C compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # # List of possible output files, starting from the most likely. # The algorithm is not robust to junk in `.', hence go to wildcards (a.*) # only as a last resort. b.out is created by i960 compilers. ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' # # The IRIX 6 linker writes into existing files which may not be # executable, retaining their permissions. Remove them first so a # subsequent execution test works. ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { (ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link_default") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi { echo "$as_me:$LINENO: result: $ac_file" >&5 echo "${ECHO_T}$ac_file" >&6; } if test -z "$ac_file"; then echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi ac_exeext=$ac_cv_exeext # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { echo "$as_me:$LINENO: checking whether the C compiler works" >&5 echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi fi { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } { echo "$as_me:$LINENO: result: $cross_compiling" >&5 echo "${ECHO_T}$cross_compiling" >&6; } { echo "$as_me:$LINENO: checking for suffix of executables" >&5 echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest$ac_cv_exeext { echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 echo "${ECHO_T}$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT { echo "$as_me:$LINENO: checking for suffix of object files" >&5 echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } if test "${ac_cv_objext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 echo "${ECHO_T}$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } if test "${ac_cv_c_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } GCC=`test $ac_compiler_gnu = yes && echo yes` ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } if test "${ac_cv_prog_cc_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } if test "${ac_cv_prog_cc_c89+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_c89=$ac_arg else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { echo "$as_me:$LINENO: result: none needed" >&5 echo "${ECHO_T}none needed" >&6; } ;; xno) { echo "$as_me:$LINENO: result: unsupported" >&5 echo "${ECHO_T}unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; } if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi { echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5 echo $ECHO_N "checking for a sed that does not truncate output... $ECHO_C" >&6; } if test "${ac_cv_path_SED+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" | sed 99q >conftest.sed $as_unset ac_script || ac_script= # Extract the first word of "sed gsed" to use in msg output if test -z "$SED"; then set dummy sed gsed; ac_prog_name=$2 if test "${ac_cv_path_SED+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS fi SED="$ac_cv_path_SED" if test -z "$SED"; then { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in \$PATH" >&5 echo "$as_me: error: no acceptable $ac_prog_name could be found in \$PATH" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_SED=$SED fi fi { echo "$as_me:$LINENO: result: $ac_cv_path_SED" >&5 echo "${ECHO_T}$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } if test "${ac_cv_path_GREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Extract the first word of "grep ggrep" to use in msg output if test -z "$GREP"; then set dummy grep ggrep; ac_prog_name=$2 if test "${ac_cv_path_GREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS fi GREP="$ac_cv_path_GREP" if test -z "$GREP"; then { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_GREP=$GREP fi fi { echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 echo "${ECHO_T}$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { echo "$as_me:$LINENO: checking for egrep" >&5 echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } if test "${ac_cv_path_EGREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else # Extract the first word of "egrep" to use in msg output if test -z "$EGREP"; then set dummy egrep; ac_prog_name=$2 if test "${ac_cv_path_EGREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS fi EGREP="$ac_cv_path_EGREP" if test -z "$EGREP"; then { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_EGREP=$EGREP fi fi fi { echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { echo "$as_me:$LINENO: checking for fgrep" >&5 echo $ECHO_N "checking for fgrep... $ECHO_C" >&6; } if test "${ac_cv_path_FGREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else # Extract the first word of "fgrep" to use in msg output if test -z "$FGREP"; then set dummy fgrep; ac_prog_name=$2 if test "${ac_cv_path_FGREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" echo 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS fi FGREP="$ac_cv_path_FGREP" if test -z "$FGREP"; then { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_FGREP=$FGREP fi fi fi { echo "$as_me:$LINENO: result: $ac_cv_path_FGREP" >&5 echo "${ECHO_T}$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { echo "$as_me:$LINENO: checking for ld used by $CC" >&5 echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then { echo "$as_me:$LINENO: checking for GNU ld" >&5 echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6; } else { echo "$as_me:$LINENO: checking for non-GNU ld" >&5 echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6; } fi if test "${lt_cv_path_LD+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 echo "${ECHO_T}$LD" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} { (exit 1); exit 1; }; } { echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6; } if test "${lt_cv_prog_gnu_ld+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { echo "$as_me:$LINENO: checking for BSD- or MS-compatible name lister (nm)" >&5 echo $ECHO_N "checking for BSD- or MS-compatible name lister (nm)... $ECHO_C" >&6; } if test "${lt_cv_path_NM+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi fi { echo "$as_me:$LINENO: result: $lt_cv_path_NM" >&5 echo "${ECHO_T}$lt_cv_path_NM" >&6; } if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$ac_tool_prefix"; then for ac_prog in "dumpbin -symbols" "link -dump -symbols" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_DUMPBIN+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { echo "$as_me:$LINENO: result: $DUMPBIN" >&5 echo "${ECHO_T}$DUMPBIN" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in "dumpbin -symbols" "link -dump -symbols" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_DUMPBIN+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { echo "$as_me:$LINENO: result: $ac_ct_DUMPBIN" >&5 echo "${ECHO_T}$ac_ct_DUMPBIN" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm { echo "$as_me:$LINENO: checking the name lister ($NM) interface" >&5 echo $ECHO_N "checking the name lister ($NM) interface... $ECHO_C" >&6; } if test "${lt_cv_nm_interface+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:4294: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:4297: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:4300: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { echo "$as_me:$LINENO: result: $lt_cv_nm_interface" >&5 echo "${ECHO_T}$lt_cv_nm_interface" >&6; } { echo "$as_me:$LINENO: checking whether ln -s works" >&5 echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else { echo "$as_me:$LINENO: result: no, using $LN_S" >&5 echo "${ECHO_T}no, using $LN_S" >&6; } fi # find the maximum length of command line arguments { echo "$as_me:$LINENO: checking the maximum length of command line arguments" >&5 echo $ECHO_N "checking the maximum length of command line arguments... $ECHO_C" >&6; } if test "${lt_cv_sys_max_cmd_len+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`$SHELL $0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ = "XX$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n $lt_cv_sys_max_cmd_len ; then { echo "$as_me:$LINENO: result: $lt_cv_sys_max_cmd_len" >&5 echo "${ECHO_T}$lt_cv_sys_max_cmd_len" >&6; } else { echo "$as_me:$LINENO: result: none" >&5 echo "${ECHO_T}none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} { echo "$as_me:$LINENO: checking whether the shell understands some XSI constructs" >&5 echo $ECHO_N "checking whether the shell understands some XSI constructs... $ECHO_C" >&6; } # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes { echo "$as_me:$LINENO: result: $xsi_shell" >&5 echo "${ECHO_T}$xsi_shell" >&6; } { echo "$as_me:$LINENO: checking whether the shell understands \"+=\"" >&5 echo $ECHO_N "checking whether the shell understands \"+=\"... $ECHO_C" >&6; } lt_shell_append=no ( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes { echo "$as_me:$LINENO: result: $lt_shell_append" >&5 echo "${ECHO_T}$lt_shell_append" >&6; } if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5 echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6; } if test "${lt_cv_ld_reload_flag+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_cv_ld_reload_flag='-r' fi { echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5 echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in darwin*) if test "$GCC" = yes; then reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_OBJDUMP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { echo "$as_me:$LINENO: result: $OBJDUMP" >&5 echo "${ECHO_T}$OBJDUMP" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OBJDUMP="objdump" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { echo "$as_me:$LINENO: result: $ac_ct_OBJDUMP" >&5 echo "${ECHO_T}$ac_ct_OBJDUMP" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { echo "$as_me:$LINENO: checking how to recognize dependent libraries" >&5 echo $ECHO_N "checking how to recognize dependent libraries... $ECHO_C" >&6; } if test "${lt_cv_deplibs_check_method+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # `unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # which responds to the $file_magic_cmd with a given extended regex. # If you have `file' or equivalent on your system and you're not sure # whether `pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; gnu*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be Linux ELF. linux* | k*bsd*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac fi { echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5 echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6; } file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. set dummy ${ac_tool_prefix}ar; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_AR+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AR="${ac_tool_prefix}ar" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { echo "$as_me:$LINENO: result: $AR" >&5 echo "${ECHO_T}$AR" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_AR"; then ac_ct_AR=$AR # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_AR+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_AR="ar" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { echo "$as_me:$LINENO: result: $ac_ct_AR" >&5 echo "${ECHO_T}$ac_ct_AR" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi else AR="$ac_cv_prog_AR" fi test -z "$AR" && AR=ar test -z "$AR_FLAGS" && AR_FLAGS=cru if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { echo "$as_me:$LINENO: result: $STRIP" >&5 echo "${ECHO_T}$STRIP" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 echo "${ECHO_T}$ac_ct_STRIP" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { echo "$as_me:$LINENO: result: $RANLIB" >&5 echo "${ECHO_T}$RANLIB" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RANLIB="ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 echo "${ECHO_T}$ac_ct_RANLIB" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" fi # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { echo "$as_me:$LINENO: checking command to parse $NM output from $compiler object" >&5 echo $ECHO_N "checking command to parse $NM output from $compiler object... $ECHO_C" >&6; } if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Now try to grab the symbols. nlist=conftest.nm if { (eval echo "$as_me:$LINENO: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\"") >&5 (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ const struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_save_LIBS="$LIBS" lt_save_CFLAGS="$CFLAGS" LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS="$lt_save_LIBS" CFLAGS="$lt_save_CFLAGS" else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { echo "$as_me:$LINENO: result: failed" >&5 echo "${ECHO_T}failed" >&6; } else { echo "$as_me:$LINENO: result: ok" >&5 echo "${ECHO_T}ok" >&6; } fi # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then enableval=$enable_libtool_lock; fi test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '#line 5519 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" { echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5 echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6; } if test "${lt_cv_cc_needs_belf+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then lt_cv_cc_needs_belf=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5 echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6; } if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; sparc*-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) LD="${LD-ld} -m elf64_sparc" ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_DSYMUTIL+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { echo "$as_me:$LINENO: result: $DSYMUTIL" >&5 echo "${ECHO_T}$DSYMUTIL" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { echo "$as_me:$LINENO: result: $ac_ct_DSYMUTIL" >&5 echo "${ECHO_T}$ac_ct_DSYMUTIL" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_NMEDIT+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { echo "$as_me:$LINENO: result: $NMEDIT" >&5 echo "${ECHO_T}$NMEDIT" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_NMEDIT="nmedit" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { echo "$as_me:$LINENO: result: $ac_ct_NMEDIT" >&5 echo "${ECHO_T}$ac_ct_NMEDIT" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_LIPO+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { echo "$as_me:$LINENO: result: $LIPO" >&5 echo "${ECHO_T}$LIPO" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_LIPO+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_LIPO="lipo" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { echo "$as_me:$LINENO: result: $ac_ct_LIPO" >&5 echo "${ECHO_T}$ac_ct_LIPO" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_OTOOL+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { echo "$as_me:$LINENO: result: $OTOOL" >&5 echo "${ECHO_T}$OTOOL" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_OTOOL+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OTOOL="otool" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { echo "$as_me:$LINENO: result: $ac_ct_OTOOL" >&5 echo "${ECHO_T}$ac_ct_OTOOL" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_OTOOL64+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { echo "$as_me:$LINENO: result: $OTOOL64" >&5 echo "${ECHO_T}$OTOOL64" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_OTOOL64+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OTOOL64="otool64" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { echo "$as_me:$LINENO: result: $ac_ct_OTOOL64" >&5 echo "${ECHO_T}$ac_ct_OTOOL64" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { echo "$as_me:$LINENO: checking for -single_module linker flag" >&5 echo $ECHO_N "checking for -single_module linker flag... $ECHO_C" >&6; } if test "${lt_cv_apple_cc_single_mod+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { echo "$as_me:$LINENO: result: $lt_cv_apple_cc_single_mod" >&5 echo "${ECHO_T}$lt_cv_apple_cc_single_mod" >&6; } { echo "$as_me:$LINENO: checking for -exported_symbols_list linker flag" >&5 echo $ECHO_N "checking for -exported_symbols_list linker flag... $ECHO_C" >&6; } if test "${lt_cv_ld_exported_symbols_list+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then lt_cv_ld_exported_symbols_list=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { echo "$as_me:$LINENO: result: $lt_cv_ld_exported_symbols_list" >&5 echo "${ECHO_T}$lt_cv_ld_exported_symbols_list" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[91]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[012]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { echo "$as_me:$LINENO: result: $CPP" >&5 echo "${ECHO_T}$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in dlfcn.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # Set options enable_dlopen=yes enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. set dummy ${ac_tool_prefix}as; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_AS+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$AS"; then ac_cv_prog_AS="$AS" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AS="${ac_tool_prefix}as" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AS=$ac_cv_prog_AS if test -n "$AS"; then { echo "$as_me:$LINENO: result: $AS" >&5 echo "${ECHO_T}$AS" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_AS"; then ac_ct_AS=$AS # Extract the first word of "as", so it can be a program name with args. set dummy as; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_AS+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_AS"; then ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_AS="as" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AS=$ac_cv_prog_ac_ct_AS if test -n "$ac_ct_AS"; then { echo "$as_me:$LINENO: result: $ac_ct_AS" >&5 echo "${ECHO_T}$ac_ct_AS" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_AS" = x; then AS="false" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac AS=$ac_ct_AS fi else AS="$ac_cv_prog_AS" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_DLLTOOL+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { echo "$as_me:$LINENO: result: $DLLTOOL" >&5 echo "${ECHO_T}$DLLTOOL" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_DLLTOOL+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { echo "$as_me:$LINENO: result: $ac_ct_DLLTOOL" >&5 echo "${ECHO_T}$ac_ct_DLLTOOL" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_OBJDUMP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { echo "$as_me:$LINENO: result: $OBJDUMP" >&5 echo "${ECHO_T}$OBJDUMP" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OBJDUMP="objdump" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { echo "$as_me:$LINENO: result: $ac_ct_OBJDUMP" >&5 echo "${ECHO_T}$ac_ct_OBJDUMP" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi ;; esac test -z "$AS" && AS=as test -z "$DLLTOOL" && DLLTOOL=dlltool test -z "$OBJDUMP" && OBJDUMP=objdump # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac else enable_shared=yes fi # Check whether --enable-static was given. if test "${enable_static+set}" = set; then enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac else enable_static=yes fi # Check whether --with-pic was given. if test "${with_pic+set}" = set; then withval=$with_pic; pic_mode="$withval" else pic_mode=default fi test -z "$pic_mode" && pic_mode=default # Check whether --enable-fast-install was given. if test "${enable_fast_install+set}" = set; then enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac else enable_fast_install=yes fi # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi { echo "$as_me:$LINENO: checking for objdir" >&5 echo $ECHO_N "checking for objdir... $ECHO_C" >&6; } if test "${lt_cv_objdir+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { echo "$as_me:$LINENO: result: $lt_cv_objdir" >&5 echo "${ECHO_T}$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir cat >>confdefs.h <<_ACEOF #define LT_OBJDIR "$lt_cv_objdir/" _ACEOF case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5 echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6; } if test "${lt_cv_path_MAGIC_CMD+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/${ac_tool_prefix}file; then lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 echo "${ECHO_T}$MAGIC_CMD" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { echo "$as_me:$LINENO: checking for file" >&5 echo $ECHO_N "checking for file... $ECHO_C" >&6; } if test "${lt_cv_path_MAGIC_CMD+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/file; then lt_cv_path_MAGIC_CMD="$ac_dir/file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 echo "${ECHO_T}$MAGIC_CMD" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC="$CC" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test "$GCC" = yes; then lt_prog_compiler_no_builtin_flag=' -fno-builtin' { echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6; } if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:7679: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:7683: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= { echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } if test "$GCC" = yes; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; pgcc* | pgf77* | pgf90* | pgf95*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl*) # IBM XL C 8.0/Fortran 10.1 on PPC lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Sun\ F*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { echo "$as_me:$LINENO: result: $lt_prog_compiler_pic" >&5 echo "${ECHO_T}$lt_prog_compiler_pic" >&6; } # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic works... $ECHO_C" >&6; } if test "${lt_cv_prog_compiler_pic_works+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:8018: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:8022: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_pic_works" >&5 echo "${ECHO_T}$lt_cv_prog_compiler_pic_works" >&6; } if test x"$lt_cv_prog_compiler_pic_works" = xyes; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; } if test "${lt_cv_prog_compiler_static_works+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_cv_prog_compiler_static_works=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_static_works" >&5 echo "${ECHO_T}$lt_cv_prog_compiler_static_works" >&6; } if test x"$lt_cv_prog_compiler_static_works" = xyes; then : else lt_prog_compiler_static= fi { echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; } if test "${lt_cv_prog_compiler_c_o+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:8123: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:8127: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5 echo "${ECHO_T}$lt_cv_prog_compiler_c_o" >&6; } { echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; } if test "${lt_cv_prog_compiler_c_o+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:8178: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:8182: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5 echo "${ECHO_T}$lt_cv_prog_compiler_c_o" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { echo "$as_me:$LINENO: result: $hard_links" >&5 echo "${ECHO_T}$hard_links" >&6; } if test "$hard_links" = no; then { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_flag_spec_ld= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; esac ld_shlibs=yes if test "$with_gnu_ld" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' export_dynamic_flag_spec='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.9.1, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to modify your PATH *** so that a non-GNU linker is found, and then restart. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag= tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; xl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec= hardcode_libdir_flag_spec_ld='-rpath $libdir' archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test "$ld_shlibs" = no; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi link_all_deplibs=no else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi export_dynamic_flag_spec='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/ p } }' aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/ p } }' aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' ${wl}-bernotok' allow_undefined_flag=' ${wl}-berok' # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' archive_cmds_need_lc=yes # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' fix_srcfile_path='`cygpath -w "$srcfile"`' enable_shared_with_static_runtimes=yes ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported whole_archive_flag_spec='' link_all_deplibs=yes allow_undefined_flag="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=echo archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; freebsd1*) ld_shlibs=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test "$GCC" = yes; then archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='${wl}-E' ;; hpux10*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_flag_spec_ld='+b $libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" cat >conftest.$ac_ext <<_ACEOF int foo(void) {} _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' else case $host_os in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-R$libdir' ;; *) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; esac fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='${wl}-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='${wl}-z,text' allow_undefined_flag='${wl}-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='${wl}-Blargedynsym' ;; esac fi fi { echo "$as_me:$LINENO: result: $ld_shlibs" >&5 echo "${ECHO_T}$ld_shlibs" >&6; } test "$ld_shlibs" = no && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; } $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { (eval echo "$as_me:$LINENO: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\"") >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } then archive_cmds_need_lc=no else archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* { echo "$as_me:$LINENO: result: $archive_cmds_need_lc" >&5 echo "${ECHO_T}$archive_cmds_need_lc" >&6; } ;; esac fi ;; esac { echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; } if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` else lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[4-9]*) version_type=linux need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$host_os in yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH printed by # mingw gcc, but we are running on Cygwin. Gcc prints its search # path with ; separators, and with drive letters. We can handle the # drive letters (cygwin fileutils understands them), so leave them, # especially as we might pass files found there to a mingw objdump, # which wouldn't understand a cygwinified path. Ahh. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac ;; *) library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' ;; esac dynamic_linker='Win32 ld.exe' # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd1*) dynamic_linker=no ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[123]*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555. postinstall_cmds='chmod 555 $lib' ;; interix[3-9]*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be Linux ELF. linux* | k*bsd*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then shlibpath_overrides_runpath=yes fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { echo "$as_me:$LINENO: result: $dynamic_linker" >&5 echo "${ECHO_T}$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi { echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test "X$hardcode_automatic" = "Xyes" ; then # We can hardcode non-existent directories. if test "$hardcode_direct" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && test "$hardcode_minus_L" != no; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { echo "$as_me:$LINENO: result: $hardcode_action" >&5 echo "${ECHO_T}$hardcode_action" >&6; } if test "$hardcode_action" = relink || test "$inherit_rpath" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; } if test "${ac_cv_lib_dl_dlopen+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_dl_dlopen=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; } if test $ac_cv_lib_dl_dlopen = yes; then lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; *) { echo "$as_me:$LINENO: checking for shl_load" >&5 echo $ECHO_N "checking for shl_load... $ECHO_C" >&6; } if test "${ac_cv_func_shl_load+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define shl_load to an innocuous variant, in case declares shl_load. For example, HP-UX 11i declares gettimeofday. */ #define shl_load innocuous_shl_load /* System header to define __stub macros and hopefully few prototypes, which can conflict with char shl_load (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef shl_load /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_shl_load || defined __stub___shl_load choke me #endif int main () { return shl_load (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_func_shl_load=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_shl_load=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 echo "${ECHO_T}$ac_cv_func_shl_load" >&6; } if test $ac_cv_func_shl_load = yes; then lt_cv_dlopen="shl_load" else { echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6; } if test "${ac_cv_lib_dld_shl_load+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_dld_shl_load=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6; } if test $ac_cv_lib_dld_shl_load = yes; then lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" else { echo "$as_me:$LINENO: checking for dlopen" >&5 echo $ECHO_N "checking for dlopen... $ECHO_C" >&6; } if test "${ac_cv_func_dlopen+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define dlopen to an innocuous variant, in case declares dlopen. For example, HP-UX 11i declares gettimeofday. */ #define dlopen innocuous_dlopen /* System header to define __stub macros and hopefully few prototypes, which can conflict with char dlopen (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef dlopen /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_dlopen || defined __stub___dlopen choke me #endif int main () { return dlopen (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_func_dlopen=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 echo "${ECHO_T}$ac_cv_func_dlopen" >&6; } if test $ac_cv_func_dlopen = yes; then lt_cv_dlopen="dlopen" else { echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; } if test "${ac_cv_lib_dl_dlopen+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_dl_dlopen=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; } if test $ac_cv_lib_dl_dlopen = yes; then lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else { echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6; } if test "${ac_cv_lib_svld_dlopen+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_svld_dlopen=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6; } if test $ac_cv_lib_svld_dlopen = yes; then lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" else { echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6; } if test "${ac_cv_lib_dld_dld_link+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_dld_dld_link=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6; } if test $ac_cv_lib_dld_dld_link = yes; then lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" fi fi fi fi fi fi ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" { echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5 echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6; } if test "${lt_cv_dlopen_self+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line 10947 "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif void fnord() { int i=42;} int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5 echo "${ECHO_T}$lt_cv_dlopen_self" >&6; } if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5 echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6; } if test "${lt_cv_dlopen_self_static+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line 11043 "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif void fnord() { int i=42;} int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5 echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6; } if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi ;; *) { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } ;; esac fi # Report which library types will actually be built { echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6; } { echo "$as_me:$LINENO: result: $can_build_shared" >&5 echo "${ECHO_T}$can_build_shared" >&6; } { echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6; } test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac { echo "$as_me:$LINENO: result: $enable_shared" >&5 echo "${ECHO_T}$enable_shared" >&6; } { echo "$as_me:$LINENO: checking whether to build static libraries" >&5 echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6; } # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes { echo "$as_me:$LINENO: result: $enable_static" >&5 echo "${ECHO_T}$enable_static" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC="$lt_save_CC" ac_config_commands="$ac_config_commands libtool" # Only expand once: { echo "$as_me:$LINENO: checking which extension is used for runtime loadable modules" >&5 echo $ECHO_N "checking which extension is used for runtime loadable modules... $ECHO_C" >&6; } if test "${libltdl_cv_shlibext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else module=yes eval libltdl_cv_shlibext=$shrext_cmds fi { echo "$as_me:$LINENO: result: $libltdl_cv_shlibext" >&5 echo "${ECHO_T}$libltdl_cv_shlibext" >&6; } if test -n "$libltdl_cv_shlibext"; then cat >>confdefs.h <<_ACEOF #define LT_MODULE_EXT "$libltdl_cv_shlibext" _ACEOF fi { echo "$as_me:$LINENO: checking which variable specifies run-time module search path" >&5 echo $ECHO_N "checking which variable specifies run-time module search path... $ECHO_C" >&6; } if test "${lt_cv_module_path_var+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_cv_module_path_var="$shlibpath_var" fi { echo "$as_me:$LINENO: result: $lt_cv_module_path_var" >&5 echo "${ECHO_T}$lt_cv_module_path_var" >&6; } if test -n "$lt_cv_module_path_var"; then cat >>confdefs.h <<_ACEOF #define LT_MODULE_PATH_VAR "$lt_cv_module_path_var" _ACEOF fi { echo "$as_me:$LINENO: checking for the default library search path" >&5 echo $ECHO_N "checking for the default library search path... $ECHO_C" >&6; } if test "${lt_cv_sys_dlsearch_path+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_cv_sys_dlsearch_path="$sys_lib_dlsearch_path_spec" fi { echo "$as_me:$LINENO: result: $lt_cv_sys_dlsearch_path" >&5 echo "${ECHO_T}$lt_cv_sys_dlsearch_path" >&6; } if test -n "$lt_cv_sys_dlsearch_path"; then sys_dlsearch_path= for dir in $lt_cv_sys_dlsearch_path; do if test -z "$sys_dlsearch_path"; then sys_dlsearch_path="$dir" else sys_dlsearch_path="$sys_dlsearch_path$PATH_SEPARATOR$dir" fi done cat >>confdefs.h <<_ACEOF #define LT_DLSEARCH_PATH "$sys_dlsearch_path" _ACEOF fi LT_DLLOADERS= ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu LIBADD_DLOPEN= { echo "$as_me:$LINENO: checking for library containing dlopen" >&5 echo $ECHO_N "checking for library containing dlopen... $ECHO_C" >&6; } if test "${ac_cv_search_dlopen+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF for ac_lib in '' dl; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_search_dlopen=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_dlopen+set}" = set; then break fi done if test "${ac_cv_search_dlopen+set}" = set; then : else ac_cv_search_dlopen=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_search_dlopen" >&5 echo "${ECHO_T}$ac_cv_search_dlopen" >&6; } ac_res=$ac_cv_search_dlopen if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" cat >>confdefs.h <<\_ACEOF #define HAVE_LIBDL 1 _ACEOF if test "$ac_cv_search_dlopen" != "none required" ; then LIBADD_DLOPEN="-ldl" fi libltdl_cv_lib_dl_dlopen="yes" LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la" else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #if HAVE_DLFCN_H # include #endif int main () { dlopen(0, 0); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIBDL 1 _ACEOF libltdl_cv_func_dlopen="yes" LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6; } if test "${ac_cv_lib_svld_dlopen+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_svld_dlopen=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6; } if test $ac_cv_lib_svld_dlopen = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIBDL 1 _ACEOF LIBADD_DLOPEN="-lsvld" libltdl_cv_func_dlopen="yes" LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la" fi fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi if test x"$libltdl_cv_func_dlopen" = xyes || test x"$libltdl_cv_lib_dl_dlopen" = xyes then lt_save_LIBS="$LIBS" LIBS="$LIBS $LIBADD_DLOPEN" for ac_func in dlerror do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done LIBS="$lt_save_LIBS" fi LIBADD_SHL_LOAD= { echo "$as_me:$LINENO: checking for shl_load" >&5 echo $ECHO_N "checking for shl_load... $ECHO_C" >&6; } if test "${ac_cv_func_shl_load+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define shl_load to an innocuous variant, in case declares shl_load. For example, HP-UX 11i declares gettimeofday. */ #define shl_load innocuous_shl_load /* System header to define __stub macros and hopefully few prototypes, which can conflict with char shl_load (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef shl_load /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_shl_load || defined __stub___shl_load choke me #endif int main () { return shl_load (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_func_shl_load=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_shl_load=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 echo "${ECHO_T}$ac_cv_func_shl_load" >&6; } if test $ac_cv_func_shl_load = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_SHL_LOAD 1 _ACEOF LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}shl_load.la" else { echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6; } if test "${ac_cv_lib_dld_shl_load+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_dld_shl_load=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6; } if test $ac_cv_lib_dld_shl_load = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_SHL_LOAD 1 _ACEOF LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}shl_load.la" LIBADD_SHL_LOAD="-ldld" fi fi case $host_os in darwin[1567].*) # We only want this for pre-Mac OS X 10.4. { echo "$as_me:$LINENO: checking for _dyld_func_lookup" >&5 echo $ECHO_N "checking for _dyld_func_lookup... $ECHO_C" >&6; } if test "${ac_cv_func__dyld_func_lookup+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define _dyld_func_lookup to an innocuous variant, in case declares _dyld_func_lookup. For example, HP-UX 11i declares gettimeofday. */ #define _dyld_func_lookup innocuous__dyld_func_lookup /* System header to define __stub macros and hopefully few prototypes, which can conflict with char _dyld_func_lookup (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef _dyld_func_lookup /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char _dyld_func_lookup (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub__dyld_func_lookup || defined __stub____dyld_func_lookup choke me #endif int main () { return _dyld_func_lookup (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_func__dyld_func_lookup=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func__dyld_func_lookup=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func__dyld_func_lookup" >&5 echo "${ECHO_T}$ac_cv_func__dyld_func_lookup" >&6; } if test $ac_cv_func__dyld_func_lookup = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_DYLD 1 _ACEOF LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dyld.la" fi ;; beos*) LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}load_add_on.la" ;; cygwin* | mingw* | os2* | pw32*) { echo "$as_me:$LINENO: checking whether cygwin_conv_path is declared" >&5 echo $ECHO_N "checking whether cygwin_conv_path is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_cygwin_conv_path+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { #ifndef cygwin_conv_path (void) cygwin_conv_path; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_cygwin_conv_path=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_cygwin_conv_path=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_cygwin_conv_path" >&5 echo "${ECHO_T}$ac_cv_have_decl_cygwin_conv_path" >&6; } if test $ac_cv_have_decl_cygwin_conv_path = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_CYGWIN_CONV_PATH 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_CYGWIN_CONV_PATH 0 _ACEOF fi LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}loadlibrary.la" ;; esac { echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6; } if test "${ac_cv_lib_dld_dld_link+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_dld_dld_link=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6; } if test $ac_cv_lib_dld_dld_link = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_DLD 1 _ACEOF LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dld_link.la" fi LT_DLPREOPEN= if test -n "$LT_DLLOADERS" then for lt_loader in $LT_DLLOADERS; do LT_DLPREOPEN="$LT_DLPREOPEN-dlpreopen $lt_loader " done cat >>confdefs.h <<\_ACEOF #define HAVE_LIBDLLOADER 1 _ACEOF fi LIBADD_DL="$LIBADD_DLOPEN $LIBADD_SHL_LOAD" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { echo "$as_me:$LINENO: checking for _ prefix in compiled symbols" >&5 echo $ECHO_N "checking for _ prefix in compiled symbols... $ECHO_C" >&6; } if test "${lt_cv_sys_symbol_underscore+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_cv_sys_symbol_underscore=no cat > conftest.$ac_ext <<_LT_EOF void nm_test_func(){} int main(){nm_test_func;return 0;} _LT_EOF if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Now try to grab the symbols. ac_nlist=conftest.nm if { (eval echo "$as_me:$LINENO: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $ac_nlist\"") >&5 (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $ac_nlist) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && test -s "$ac_nlist"; then # See whether the symbols have a leading underscore. if grep '^. _nm_test_func' "$ac_nlist" >/dev/null; then lt_cv_sys_symbol_underscore=yes else if grep '^. nm_test_func ' "$ac_nlist" >/dev/null; then : else echo "configure: cannot find nm_test_func in $ac_nlist" >&5 fi fi else echo "configure: cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "configure: failed program was:" >&5 cat conftest.c >&5 fi rm -rf conftest* fi { echo "$as_me:$LINENO: result: $lt_cv_sys_symbol_underscore" >&5 echo "${ECHO_T}$lt_cv_sys_symbol_underscore" >&6; } sys_symbol_underscore=$lt_cv_sys_symbol_underscore if test x"$lt_cv_sys_symbol_underscore" = xyes; then if test x"$libltdl_cv_func_dlopen" = xyes || test x"$libltdl_cv_lib_dl_dlopen" = xyes ; then { echo "$as_me:$LINENO: checking whether we have to add an underscore for dlsym" >&5 echo $ECHO_N "checking whether we have to add an underscore for dlsym... $ECHO_C" >&6; } if test "${libltdl_cv_need_uscore+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else libltdl_cv_need_uscore=unknown save_LIBS="$LIBS" LIBS="$LIBS $LIBADD_DLOPEN" if test "$cross_compiling" = yes; then : libltdl_cv_need_uscore=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line 12158 "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif void fnord() { int i=42;} int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) libltdl_cv_need_uscore=no ;; x$lt_dlneed_uscore) libltdl_cv_need_uscore=yes ;; x$lt_dlunknown|x*) ;; esac else : # compilation failed fi fi rm -fr conftest* LIBS="$save_LIBS" fi { echo "$as_me:$LINENO: result: $libltdl_cv_need_uscore" >&5 echo "${ECHO_T}$libltdl_cv_need_uscore" >&6; } fi fi if test x"$libltdl_cv_need_uscore" = xyes; then cat >>confdefs.h <<\_ACEOF #define NEED_USCORE 1 _ACEOF fi { echo "$as_me:$LINENO: checking whether deplibs are loaded by dlopen" >&5 echo $ECHO_N "checking whether deplibs are loaded by dlopen... $ECHO_C" >&6; } if test "${lt_cv_sys_dlopen_deplibs+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # PORTME does your system automatically load deplibs for dlopen? # or its logical equivalent (e.g. shl_load for HP-UX < 11) # For now, we just catch OSes we know something about -- in the # future, we'll try test this programmatically. lt_cv_sys_dlopen_deplibs=unknown case $host_os in aix3*|aix4.1.*|aix4.2.*) # Unknown whether this is true for these versions of AIX, but # we want this `case' here to explicitly catch those versions. lt_cv_sys_dlopen_deplibs=unknown ;; aix[4-9]*) lt_cv_sys_dlopen_deplibs=yes ;; amigaos*) case $host_cpu in powerpc) lt_cv_sys_dlopen_deplibs=no ;; esac ;; darwin*) # Assuming the user has installed a libdl from somewhere, this is true # If you are looking for one http://www.opendarwin.org/projects/dlcompat lt_cv_sys_dlopen_deplibs=yes ;; freebsd* | dragonfly*) lt_cv_sys_dlopen_deplibs=yes ;; gnu* | linux* | k*bsd*-gnu) # GNU and its variants, using gnu ld.so (Glibc) lt_cv_sys_dlopen_deplibs=yes ;; hpux10*|hpux11*) lt_cv_sys_dlopen_deplibs=yes ;; interix*) lt_cv_sys_dlopen_deplibs=yes ;; irix[12345]*|irix6.[01]*) # Catch all versions of IRIX before 6.2, and indicate that we don't # know how it worked for any of those versions. lt_cv_sys_dlopen_deplibs=unknown ;; irix*) # The case above catches anything before 6.2, and it's known that # at 6.2 and later dlopen does load deplibs. lt_cv_sys_dlopen_deplibs=yes ;; netbsd* | netbsdelf*-gnu) lt_cv_sys_dlopen_deplibs=yes ;; openbsd*) lt_cv_sys_dlopen_deplibs=yes ;; osf[1234]*) # dlopen did load deplibs (at least at 4.x), but until the 5.x series, # it did *not* use an RPATH in a shared library to find objects the # library depends on, so we explicitly say `no'. lt_cv_sys_dlopen_deplibs=no ;; osf5.0|osf5.0a|osf5.1) # dlopen *does* load deplibs and with the right loader patch applied # it even uses RPATH in a shared library to search for shared objects # that the library depends on, but there's no easy way to know if that # patch is installed. Since this is the case, all we can really # say is unknown -- it depends on the patch being installed. If # it is, this changes to `yes'. Without it, it would be `no'. lt_cv_sys_dlopen_deplibs=unknown ;; osf*) # the two cases above should catch all versions of osf <= 5.1. Read # the comments above for what we know about them. # At > 5.1, deplibs are loaded *and* any RPATH in a shared library # is used to find them so we can finally say `yes'. lt_cv_sys_dlopen_deplibs=yes ;; qnx*) lt_cv_sys_dlopen_deplibs=yes ;; solaris*) lt_cv_sys_dlopen_deplibs=yes ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) libltdl_cv_sys_dlopen_deplibs=yes ;; esac fi { echo "$as_me:$LINENO: result: $lt_cv_sys_dlopen_deplibs" >&5 echo "${ECHO_T}$lt_cv_sys_dlopen_deplibs" >&6; } if test "$lt_cv_sys_dlopen_deplibs" != yes; then cat >>confdefs.h <<\_ACEOF #define LTDL_DLOPEN_DEPLIBS 1 _ACEOF fi : for ac_header in argz.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { echo "$as_me:$LINENO: checking for error_t" >&5 echo $ECHO_N "checking for error_t... $ECHO_C" >&6; } if test "${ac_cv_type_error_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #if defined(HAVE_ARGZ_H) # include #endif typedef error_t ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_error_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_error_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_error_t" >&5 echo "${ECHO_T}$ac_cv_type_error_t" >&6; } if test $ac_cv_type_error_t = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_ERROR_T 1 _ACEOF else cat >>confdefs.h <<\_ACEOF #define error_t int _ACEOF cat >>confdefs.h <<\_ACEOF #define __error_t_defined 1 _ACEOF fi ARGZ_H= for ac_func in argz_add argz_append argz_count argz_create_sep argz_insert \ argz_next argz_stringify do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF else ARGZ_H=argz.h; case " $LIBOBJS " in *" argz.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS argz.$ac_objext" ;; esac fi done if test -z "$ARGZ_H"; then { echo "$as_me:$LINENO: checking if argz actually works" >&5 echo $ECHO_N "checking if argz actually works... $ECHO_C" >&6; } if test "${lt_cv_sys_argz_works+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $host_os in #( *cygwin*) lt_cv_sys_argz_works=no if test "$cross_compiling" != no; then lt_cv_sys_argz_works="guessing no" else lt_sed_extract_leading_digits='s/^\([0-9\.]*\).*/\1/' save_IFS=$IFS IFS=-. set x `uname -r | sed -e "$lt_sed_extract_leading_digits"` IFS=$save_IFS lt_os_major=${2-0} lt_os_minor=${3-0} lt_os_micro=${4-0} if test "$lt_os_major" -gt 1 \ || { test "$lt_os_major" -eq 1 \ && { test "$lt_os_minor" -gt 5 \ || { test "$lt_os_minor" -eq 5 \ && test "$lt_os_micro" -gt 24; }; }; }; then lt_cv_sys_argz_works=yes fi fi ;; #( *) lt_cv_sys_argz_works=yes ;; esac fi { echo "$as_me:$LINENO: result: $lt_cv_sys_argz_works" >&5 echo "${ECHO_T}$lt_cv_sys_argz_works" >&6; } if test $lt_cv_sys_argz_works = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_WORKING_ARGZ 1 _ACEOF else ARGZ_H=argz.h case " $LIBOBJS " in *" argz.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS argz.$ac_objext" ;; esac fi fi { echo "$as_me:$LINENO: checking whether libtool supports -dlopen/-dlpreopen" >&5 echo $ECHO_N "checking whether libtool supports -dlopen/-dlpreopen... $ECHO_C" >&6; } if test "${libltdl_cv_preloaded_symbols+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$lt_cv_sys_global_symbol_pipe"; then libltdl_cv_preloaded_symbols=yes else libltdl_cv_preloaded_symbols=no fi fi { echo "$as_me:$LINENO: result: $libltdl_cv_preloaded_symbols" >&5 echo "${ECHO_T}$libltdl_cv_preloaded_symbols" >&6; } if test x"$libltdl_cv_preloaded_symbols" = xyes; then cat >>confdefs.h <<\_ACEOF #define HAVE_PRELOADED_SYMBOLS 1 _ACEOF fi # Check whether --enable-ltdl-install was given. if test "${enable_ltdl_install+set}" = set; then enableval=$enable_ltdl_install; fi case ,${enable_ltdl_install},${enable_ltdl_convenience} in *yes*) ;; *) enable_ltdl_convenience=yes ;; esac if test x"${enable_ltdl_install-no}" != xno; then INSTALL_LTDL_TRUE= INSTALL_LTDL_FALSE='#' else INSTALL_LTDL_TRUE='#' INSTALL_LTDL_FALSE= fi if test x"${enable_ltdl_convenience-no}" != xno; then CONVENIENCE_LTDL_TRUE= CONVENIENCE_LTDL_FALSE='#' else CONVENIENCE_LTDL_TRUE='#' CONVENIENCE_LTDL_FALSE= fi # In order that ltdl.c can compile, find out the first AC_CONFIG_HEADERS # the user used. This is so that ltdl.h can pick up the parent projects # config.h file, The first file in AC_CONFIG_HEADERS must contain the # definitions required by ltdl.c. # FIXME: Remove use of undocumented AC_LIST_HEADERS (2.59 compatibility). for ac_header in unistd.h dl.h sys/dl.h dld.h mach-o/dyld.h dirent.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in closedir opendir readdir do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF else case " $LIBOBJS " in *" lt__dirent.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS lt__dirent.$ac_objext" ;; esac fi done for ac_func in strlcat strlcpy do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF else case " $LIBOBJS " in *" lt__strl.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS lt__strl.$ac_objext" ;; esac fi done cat >>confdefs.h <<_ACEOF #define LT_LIBEXT "$libext" _ACEOF name=ltdl LTDLOPEN=`eval "\\$ECHO \"$libname_spec\""` ## -------- ## ## Outputs. ## ## -------- ## ac_config_files="$ac_config_files Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( *) $as_unset $ac_var ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then test "x$cache_file" != "x/dev/null" && { echo "$as_me:$LINENO: updating cache $cache_file" >&5 echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${INSTALL_LTDL_TRUE}" && test -z "${INSTALL_LTDL_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"INSTALL_LTDL\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"INSTALL_LTDL\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${CONVENIENCE_LTDL_TRUE}" && test -z "${CONVENIENCE_LTDL_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"CONVENIENCE_LTDL\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"CONVENIENCE_LTDL\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi LT_CONFIG_H=config.h : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) as_nl=' ' IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir fi echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 # Save the log message, to keep $[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by libltdl $as_me 2.2.6, which was generated by GNU Autoconf 2.61. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ libltdl config.status 2.2.6 configured by $0, generated by GNU Autoconf 2.61, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2006 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) echo "$ac_cs_version"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift CONFIG_FILES="$CONFIG_FILES $ac_optarg" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header { echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; };; --help | --hel | -h ) echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF if \$ac_cs_recheck; then echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 CONFIG_SHELL=$SHELL export CONFIG_SHELL exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' macro_version='`$ECHO "X$macro_version" | $Xsed -e "$delay_single_quote_subst"`' macro_revision='`$ECHO "X$macro_revision" | $Xsed -e "$delay_single_quote_subst"`' AS='`$ECHO "X$AS" | $Xsed -e "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "X$DLLTOOL" | $Xsed -e "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "X$OBJDUMP" | $Xsed -e "$delay_single_quote_subst"`' enable_shared='`$ECHO "X$enable_shared" | $Xsed -e "$delay_single_quote_subst"`' enable_static='`$ECHO "X$enable_static" | $Xsed -e "$delay_single_quote_subst"`' pic_mode='`$ECHO "X$pic_mode" | $Xsed -e "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "X$enable_fast_install" | $Xsed -e "$delay_single_quote_subst"`' host_alias='`$ECHO "X$host_alias" | $Xsed -e "$delay_single_quote_subst"`' host='`$ECHO "X$host" | $Xsed -e "$delay_single_quote_subst"`' host_os='`$ECHO "X$host_os" | $Xsed -e "$delay_single_quote_subst"`' build_alias='`$ECHO "X$build_alias" | $Xsed -e "$delay_single_quote_subst"`' build='`$ECHO "X$build" | $Xsed -e "$delay_single_quote_subst"`' build_os='`$ECHO "X$build_os" | $Xsed -e "$delay_single_quote_subst"`' SED='`$ECHO "X$SED" | $Xsed -e "$delay_single_quote_subst"`' Xsed='`$ECHO "X$Xsed" | $Xsed -e "$delay_single_quote_subst"`' GREP='`$ECHO "X$GREP" | $Xsed -e "$delay_single_quote_subst"`' EGREP='`$ECHO "X$EGREP" | $Xsed -e "$delay_single_quote_subst"`' FGREP='`$ECHO "X$FGREP" | $Xsed -e "$delay_single_quote_subst"`' LD='`$ECHO "X$LD" | $Xsed -e "$delay_single_quote_subst"`' NM='`$ECHO "X$NM" | $Xsed -e "$delay_single_quote_subst"`' LN_S='`$ECHO "X$LN_S" | $Xsed -e "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "X$max_cmd_len" | $Xsed -e "$delay_single_quote_subst"`' ac_objext='`$ECHO "X$ac_objext" | $Xsed -e "$delay_single_quote_subst"`' exeext='`$ECHO "X$exeext" | $Xsed -e "$delay_single_quote_subst"`' lt_unset='`$ECHO "X$lt_unset" | $Xsed -e "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "X$lt_SP2NL" | $Xsed -e "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`' reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`' reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`' AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "X$AR_FLAGS" | $Xsed -e "$delay_single_quote_subst"`' STRIP='`$ECHO "X$STRIP" | $Xsed -e "$delay_single_quote_subst"`' RANLIB='`$ECHO "X$RANLIB" | $Xsed -e "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "X$old_postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "X$old_postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "X$old_archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' CC='`$ECHO "X$CC" | $Xsed -e "$delay_single_quote_subst"`' CFLAGS='`$ECHO "X$CFLAGS" | $Xsed -e "$delay_single_quote_subst"`' compiler='`$ECHO "X$compiler" | $Xsed -e "$delay_single_quote_subst"`' GCC='`$ECHO "X$GCC" | $Xsed -e "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "X$lt_cv_sys_global_symbol_pipe" | $Xsed -e "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "X$lt_cv_sys_global_symbol_to_cdecl" | $Xsed -e "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address" | $Xsed -e "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' objdir='`$ECHO "X$objdir" | $Xsed -e "$delay_single_quote_subst"`' SHELL='`$ECHO "X$SHELL" | $Xsed -e "$delay_single_quote_subst"`' ECHO='`$ECHO "X$ECHO" | $Xsed -e "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "X$MAGIC_CMD" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "X$lt_prog_compiler_no_builtin_flag" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "X$lt_prog_compiler_wl" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "X$lt_prog_compiler_pic" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "X$lt_prog_compiler_static" | $Xsed -e "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "X$lt_cv_prog_compiler_c_o" | $Xsed -e "$delay_single_quote_subst"`' need_locks='`$ECHO "X$need_locks" | $Xsed -e "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "X$DSYMUTIL" | $Xsed -e "$delay_single_quote_subst"`' NMEDIT='`$ECHO "X$NMEDIT" | $Xsed -e "$delay_single_quote_subst"`' LIPO='`$ECHO "X$LIPO" | $Xsed -e "$delay_single_quote_subst"`' OTOOL='`$ECHO "X$OTOOL" | $Xsed -e "$delay_single_quote_subst"`' OTOOL64='`$ECHO "X$OTOOL64" | $Xsed -e "$delay_single_quote_subst"`' libext='`$ECHO "X$libext" | $Xsed -e "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "X$shrext_cmds" | $Xsed -e "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "X$extract_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "X$archive_cmds_need_lc" | $Xsed -e "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "X$enable_shared_with_static_runtimes" | $Xsed -e "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "X$export_dynamic_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "X$whole_archive_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "X$compiler_needs_object" | $Xsed -e "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "X$old_archive_from_new_cmds" | $Xsed -e "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "X$old_archive_from_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' archive_cmds='`$ECHO "X$archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "X$archive_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' module_cmds='`$ECHO "X$module_cmds" | $Xsed -e "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "X$module_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "X$with_gnu_ld" | $Xsed -e "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "X$allow_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "X$no_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "X$hardcode_libdir_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' hardcode_libdir_flag_spec_ld='`$ECHO "X$hardcode_libdir_flag_spec_ld" | $Xsed -e "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "X$hardcode_libdir_separator" | $Xsed -e "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "X$hardcode_direct" | $Xsed -e "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "X$hardcode_direct_absolute" | $Xsed -e "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "X$hardcode_minus_L" | $Xsed -e "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "X$hardcode_shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "X$hardcode_automatic" | $Xsed -e "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "X$inherit_rpath" | $Xsed -e "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "X$link_all_deplibs" | $Xsed -e "$delay_single_quote_subst"`' fix_srcfile_path='`$ECHO "X$fix_srcfile_path" | $Xsed -e "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "X$always_export_symbols" | $Xsed -e "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "X$export_symbols_cmds" | $Xsed -e "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "X$exclude_expsyms" | $Xsed -e "$delay_single_quote_subst"`' include_expsyms='`$ECHO "X$include_expsyms" | $Xsed -e "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "X$prelink_cmds" | $Xsed -e "$delay_single_quote_subst"`' file_list_spec='`$ECHO "X$file_list_spec" | $Xsed -e "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "X$variables_saved_for_relink" | $Xsed -e "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "X$need_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' need_version='`$ECHO "X$need_version" | $Xsed -e "$delay_single_quote_subst"`' version_type='`$ECHO "X$version_type" | $Xsed -e "$delay_single_quote_subst"`' runpath_var='`$ECHO "X$runpath_var" | $Xsed -e "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "X$shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "X$shlibpath_overrides_runpath" | $Xsed -e "$delay_single_quote_subst"`' libname_spec='`$ECHO "X$libname_spec" | $Xsed -e "$delay_single_quote_subst"`' library_names_spec='`$ECHO "X$library_names_spec" | $Xsed -e "$delay_single_quote_subst"`' soname_spec='`$ECHO "X$soname_spec" | $Xsed -e "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "X$postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "X$postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' finish_cmds='`$ECHO "X$finish_cmds" | $Xsed -e "$delay_single_quote_subst"`' finish_eval='`$ECHO "X$finish_eval" | $Xsed -e "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "X$hardcode_into_libs" | $Xsed -e "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "X$sys_lib_search_path_spec" | $Xsed -e "$delay_single_quote_subst"`' sys_lib_dlsearch_path_spec='`$ECHO "X$sys_lib_dlsearch_path_spec" | $Xsed -e "$delay_single_quote_subst"`' hardcode_action='`$ECHO "X$hardcode_action" | $Xsed -e "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "X$enable_dlopen" | $Xsed -e "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "X$enable_dlopen_self" | $Xsed -e "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "X$enable_dlopen_self_static" | $Xsed -e "$delay_single_quote_subst"`' old_striplib='`$ECHO "X$old_striplib" | $Xsed -e "$delay_single_quote_subst"`' striplib='`$ECHO "X$striplib" | $Xsed -e "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # Quote evaled strings. for var in SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ deplibs_check_method \ file_magic_cmd \ AR \ AR_FLAGS \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ SHELL \ ECHO \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_wl \ lt_prog_compiler_pic \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_flag_spec_ld \ hardcode_libdir_separator \ fix_srcfile_path \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ finish_eval \ old_striplib \ striplib; do case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ sys_lib_dlsearch_path_spec; do case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Fix-up fallback echo if it was mangled by the above quoting rules. case \$lt_ECHO in *'\\\$0 --fallback-echo"') lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\$0 --fallback-echo"\$/\$0 --fallback-echo"/'\` ;; esac ac_aux_dir='$ac_aux_dir' xsi_shell='$xsi_shell' lt_shell_append='$lt_shell_append' # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h:config-h.in" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= trap 'exit_status=$? { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } # # Set up the sed scripts for CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h if test -n "$CONFIG_FILES"; then _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF SHELL!$SHELL$ac_delim PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim PACKAGE_NAME!$PACKAGE_NAME$ac_delim PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim PACKAGE_STRING!$PACKAGE_STRING$ac_delim PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim exec_prefix!$exec_prefix$ac_delim prefix!$prefix$ac_delim program_transform_name!$program_transform_name$ac_delim bindir!$bindir$ac_delim sbindir!$sbindir$ac_delim libexecdir!$libexecdir$ac_delim datarootdir!$datarootdir$ac_delim datadir!$datadir$ac_delim sysconfdir!$sysconfdir$ac_delim sharedstatedir!$sharedstatedir$ac_delim localstatedir!$localstatedir$ac_delim includedir!$includedir$ac_delim oldincludedir!$oldincludedir$ac_delim docdir!$docdir$ac_delim infodir!$infodir$ac_delim htmldir!$htmldir$ac_delim dvidir!$dvidir$ac_delim pdfdir!$pdfdir$ac_delim psdir!$psdir$ac_delim libdir!$libdir$ac_delim localedir!$localedir$ac_delim mandir!$mandir$ac_delim DEFS!$DEFS$ac_delim ECHO_C!$ECHO_C$ac_delim ECHO_N!$ECHO_N$ac_delim ECHO_T!$ECHO_T$ac_delim LIBS!$LIBS$ac_delim build_alias!$build_alias$ac_delim host_alias!$host_alias$ac_delim target_alias!$target_alias$ac_delim INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim INSTALL_DATA!$INSTALL_DATA$ac_delim am__isrc!$am__isrc$ac_delim CYGPATH_W!$CYGPATH_W$ac_delim PACKAGE!$PACKAGE$ac_delim VERSION!$VERSION$ac_delim ACLOCAL!$ACLOCAL$ac_delim AUTOCONF!$AUTOCONF$ac_delim AUTOMAKE!$AUTOMAKE$ac_delim AUTOHEADER!$AUTOHEADER$ac_delim MAKEINFO!$MAKEINFO$ac_delim install_sh!$install_sh$ac_delim STRIP!$STRIP$ac_delim INSTALL_STRIP_PROGRAM!$INSTALL_STRIP_PROGRAM$ac_delim mkdir_p!$mkdir_p$ac_delim AWK!$AWK$ac_delim SET_MAKE!$SET_MAKE$ac_delim am__leading_dot!$am__leading_dot$ac_delim AMTAR!$AMTAR$ac_delim am__tar!$am__tar$ac_delim am__untar!$am__untar$ac_delim AS!$AS$ac_delim DLLTOOL!$DLLTOOL$ac_delim OBJDUMP!$OBJDUMP$ac_delim LIBTOOL!$LIBTOOL$ac_delim build!$build$ac_delim build_cpu!$build_cpu$ac_delim build_vendor!$build_vendor$ac_delim build_os!$build_os$ac_delim host!$host$ac_delim host_cpu!$host_cpu$ac_delim host_vendor!$host_vendor$ac_delim host_os!$host_os$ac_delim CC!$CC$ac_delim CFLAGS!$CFLAGS$ac_delim LDFLAGS!$LDFLAGS$ac_delim CPPFLAGS!$CPPFLAGS$ac_delim ac_ct_CC!$ac_ct_CC$ac_delim EXEEXT!$EXEEXT$ac_delim OBJEXT!$OBJEXT$ac_delim DEPDIR!$DEPDIR$ac_delim am__include!$am__include$ac_delim am__quote!$am__quote$ac_delim AMDEP_TRUE!$AMDEP_TRUE$ac_delim AMDEP_FALSE!$AMDEP_FALSE$ac_delim AMDEPBACKSLASH!$AMDEPBACKSLASH$ac_delim CCDEPMODE!$CCDEPMODE$ac_delim am__fastdepCC_TRUE!$am__fastdepCC_TRUE$ac_delim am__fastdepCC_FALSE!$am__fastdepCC_FALSE$ac_delim SED!$SED$ac_delim GREP!$GREP$ac_delim EGREP!$EGREP$ac_delim FGREP!$FGREP$ac_delim LD!$LD$ac_delim DUMPBIN!$DUMPBIN$ac_delim ac_ct_DUMPBIN!$ac_ct_DUMPBIN$ac_delim NM!$NM$ac_delim LN_S!$LN_S$ac_delim AR!$AR$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` if test -n "$ac_eof"; then ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` ac_eof=`expr $ac_eof + 1` fi cat >>$CONFIG_STATUS <<_ACEOF cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof /@[a-zA-Z_][a-zA-Z_0-9]*@/!b _ACEOF sed ' s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g s/^/s,@/; s/!/@,|#_!!_#|/ :n t n s/'"$ac_delim"'$/,g/; t s/$/\\/; p N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n ' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF CEOF$ac_eof _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF RANLIB!$RANLIB$ac_delim lt_ECHO!$lt_ECHO$ac_delim DSYMUTIL!$DSYMUTIL$ac_delim NMEDIT!$NMEDIT$ac_delim LIPO!$LIPO$ac_delim OTOOL!$OTOOL$ac_delim OTOOL64!$OTOOL64$ac_delim CPP!$CPP$ac_delim LT_DLLOADERS!$LT_DLLOADERS$ac_delim LIBADD_DLOPEN!$LIBADD_DLOPEN$ac_delim LIBADD_SHL_LOAD!$LIBADD_SHL_LOAD$ac_delim LIBADD_DLD_LINK!$LIBADD_DLD_LINK$ac_delim LT_DLPREOPEN!$LT_DLPREOPEN$ac_delim LIBADD_DL!$LIBADD_DL$ac_delim sys_symbol_underscore!$sys_symbol_underscore$ac_delim LIBOBJS!$LIBOBJS$ac_delim ARGZ_H!$ARGZ_H$ac_delim INSTALL_LTDL_TRUE!$INSTALL_LTDL_TRUE$ac_delim INSTALL_LTDL_FALSE!$INSTALL_LTDL_FALSE$ac_delim CONVENIENCE_LTDL_TRUE!$CONVENIENCE_LTDL_TRUE$ac_delim CONVENIENCE_LTDL_FALSE!$CONVENIENCE_LTDL_FALSE$ac_delim LT_CONFIG_H!$LT_CONFIG_H$ac_delim LTDLOPEN!$LTDLOPEN$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 24; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` if test -n "$ac_eof"; then ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` ac_eof=`expr $ac_eof + 1` fi cat >>$CONFIG_STATUS <<_ACEOF cat >"\$tmp/subs-2.sed" <<\CEOF$ac_eof /@[a-zA-Z_][a-zA-Z_0-9]*@/!b end _ACEOF sed ' s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g s/^/s,@/; s/!/@,|#_!!_#|/ :n t n s/'"$ac_delim"'$/,g/; t s/$/\\/; p N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n ' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF :end s/|#_!!_#|//g CEOF$ac_eof _ACEOF # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/ s/:*\${srcdir}:*/:/ s/:*@srcdir@:*/:/ s/^\([^=]*=[ ]*\):*/\1/ s/:*$// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF fi # test -n "$CONFIG_FILES" for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 echo "$as_me: error: Invalid tag $ac_tag." >&2;} { (exit 1); exit 1; }; };; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 echo "$as_me: error: cannot find input file: $ac_f" >&2;} { (exit 1); exit 1; }; };; esac ac_file_inputs="$ac_file_inputs $ac_f" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input="Generated from "`IFS=: echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} fi case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin";; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` { as_dir="$ac_dir" case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= case `sed -n '/datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p ' $ac_file_inputs` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s&@configure_input@&$configure_input&;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" >$tmp/out test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&5 echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&2;} rm -f "$tmp/stdin" case $ac_file in -) cat "$tmp/out"; rm -f "$tmp/out";; *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; esac ;; :H) # # CONFIG_HEADER # _ACEOF # Transform confdefs.h into a sed script `conftest.defines', that # substitutes the proper values into config.h.in to produce config.h. rm -f conftest.defines conftest.tail # First, append a space to every undef/define line, to ease matching. echo 's/$/ /' >conftest.defines # Then, protect against being on the right side of a sed subst, or in # an unquoted here document, in config.status. If some macros were # called several times there might be several #defines for the same # symbol, which is useless. But do not sort them, since the last # AC_DEFINE must be honored. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* # These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where # NAME is the cpp macro being defined, VALUE is the value it is being given. # PARAMS is the parameter list in the macro definition--in most cases, it's # just an empty string. ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' ac_dB='\\)[ (].*,\\1define\\2' ac_dC=' ' ac_dD=' ,' uniq confdefs.h | sed -n ' t rset :rset s/^[ ]*#[ ]*define[ ][ ]*// t ok d :ok s/[\\&,]/\\&/g s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p ' >>conftest.defines # Remove the space that was appended to ease matching. # Then replace #undef with comments. This is necessary, for # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. # (The regexp can be short, since the line contains either #define or #undef.) echo 's/ $// s,^[ #]*u.*,/* & */,' >>conftest.defines # Break up conftest.defines: ac_max_sed_lines=50 # First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" # Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" # Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" # et cetera. ac_in='$ac_file_inputs' ac_out='"$tmp/out1"' ac_nxt='"$tmp/out2"' while : do # Write a here document: cat >>$CONFIG_STATUS <<_ACEOF # First, check the format of the line: cat >"\$tmp/defines.sed" <<\\CEOF /^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def /^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def b :def _ACEOF sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS echo 'CEOF sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail grep . conftest.tail >/dev/null || break rm -f conftest.defines mv conftest.tail conftest.defines done rm -f conftest.defines conftest.tail echo "ac_result=$ac_in" >>$CONFIG_STATUS cat >>$CONFIG_STATUS <<\_ACEOF if test x"$ac_file" != x-; then echo "/* $configure_input */" >"$tmp/config.h" cat "$ac_result" >>"$tmp/config.h" if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 echo "$as_me: $ac_file is unchanged" >&6;} else rm -f $ac_file mv "$tmp/config.h" $ac_file fi else echo "/* $configure_input */" cat "$ac_result" fi rm -f "$tmp/out12" # Compute $ac_file's index in $config_headers. _am_arg=$ac_file _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { echo "$as_me:$LINENO: executing $ac_file commands" >&5 echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` { as_dir=$dirpart/$fdir case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ;; "libtool":C) # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # The names of the tagged configurations supported by this script. available_tags="" # ### BEGIN LIBTOOL CONFIG # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Assembler program. AS=$AS # DLL creation program. DLLTOOL=$DLLTOOL # Object dumper program. OBJDUMP=$OBJDUMP # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method == "file_magic". file_magic_cmd=$lt_file_magic_cmd # The archiver. AR=$lt_AR AR_FLAGS=$lt_AR_FLAGS # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # The name of the directory that contains temporary libtool files. objdir=$objdir # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that does not interpret backslashes. ECHO=$lt_ECHO # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # If ld is used when linking, flag to hardcode \$libdir into a binary # during linking. This must work even if \$libdir does not exist. hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \${shlibpath_var} if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Fix the shell variable \$srcfile for the compiler. fix_srcfile_path=$lt_fix_srcfile_path # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain="$ac_aux_dir/ltmain.sh" # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) case $xsi_shell in yes) cat << \_LT_EOF >> "$cfgfile" # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac } # func_basename file func_basename () { func_basename_result="${1##*/}" } # func_dirname_and_basename file append nondir_replacement # perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac func_basename_result="${1##*/}" } # func_stripname prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). func_stripname () { # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary parameter first. func_stripname_result=${3} func_stripname_result=${func_stripname_result#"${1}"} func_stripname_result=${func_stripname_result%"${2}"} } # func_opt_split func_opt_split () { func_opt_split_opt=${1%%=*} func_opt_split_arg=${1#*=} } # func_lo2o object func_lo2o () { case ${1} in *.lo) func_lo2o_result=${1%.lo}.${objext} ;; *) func_lo2o_result=${1} ;; esac } # func_xform libobj-or-source func_xform () { func_xform_result=${1%.*}.lo } # func_arith arithmetic-term... func_arith () { func_arith_result=$(( $* )) } # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=${#1} } _LT_EOF ;; *) # Bourne compatible functions. cat << \_LT_EOF >> "$cfgfile" # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi } # func_basename file func_basename () { func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` } # func_stripname prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # func_strip_suffix prefix name func_stripname () { case ${2} in .*) func_stripname_result=`$ECHO "X${3}" \ | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "X${3}" \ | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; esac } # sed scripts: my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q' my_sed_long_arg='1s/^-[^=]*=//' # func_opt_split func_opt_split () { func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` } # func_lo2o object func_lo2o () { func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` } # func_xform libobj-or-source func_xform () { func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'` } # func_arith arithmetic-term... func_arith () { func_arith_result=`expr "$@"` } # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` } _LT_EOF esac case $lt_shell_append in yes) cat << \_LT_EOF >> "$cfgfile" # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "$1+=\$2" } _LT_EOF ;; *) cat << \_LT_EOF >> "$cfgfile" # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "$1=\$$1\$2" } _LT_EOF ;; esac sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ;; esac done # for ac_tag { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi proftpd-dfsg-1.3.5~rc3/lib/libltdl/lt__dirent.c0000644000175000017500000000573211300565264021241 0ustar frankiefrankie/* lt__dirent.c -- internal directory entry scanning interface Copyright (C) 2001, 2004 Free Software Foundation, Inc. Written by Bob Friesenhahn, 2001 NOTE: The canonical source of this file is maintained with the GNU Libtool package. Report bugs to bug-libtool@gnu.org. GNU Libltdl is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exception to the GNU Lesser General Public License, if you distribute this file as part of a program or library that is built using GNU Libtool, you may include this file under the same distribution terms that you use for the rest of that program. GNU Libltdl is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with GNU Libltdl; see the file COPYING.LIB. If not, a copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, or obtained by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "lt__private.h" #include #include #include "lt__dirent.h" #if defined(__WINDOWS__) void closedir (DIR *entry) { assert (entry != (DIR *) NULL); FindClose (entry->hSearch); free ((void *) entry); } DIR * opendir (const char *path) { char file_spec[LT_FILENAME_MAX]; DIR *entry; assert (path != (char *) 0); if (lt_strlcpy (file_spec, path, sizeof file_spec) >= sizeof file_spec || lt_strlcat (file_spec, "\\", sizeof file_spec) >= sizeof file_spec) return (DIR *) 0; entry = (DIR *) malloc (sizeof(DIR)); if (entry != (DIR *) 0) { entry->firsttime = TRUE; entry->hSearch = FindFirstFile (file_spec, &entry->Win32FindData); if (entry->hSearch == INVALID_HANDLE_VALUE) { if (lt_strlcat (file_spec, "\\*.*", sizeof file_spec) < sizeof file_spec) { entry->hSearch = FindFirstFile (file_spec, &entry->Win32FindData); } if (entry->hSearch == INVALID_HANDLE_VALUE) { entry = (free (entry), (DIR *) 0); } } } return entry; } struct dirent * readdir (DIR *entry) { int status; if (entry == (DIR *) 0) return (struct dirent *) 0; if (!entry->firsttime) { status = FindNextFile (entry->hSearch, &entry->Win32FindData); if (status == 0) return (struct dirent *) 0; } entry->firsttime = FALSE; if (lt_strlcpy (entry->file_info.d_name, entry->Win32FindData.cFileName, sizeof entry->file_info.d_name) >= sizeof entry->file_info.d_name) return (struct dirent *) 0; entry->file_info.d_namlen = strlen (entry->file_info.d_name); return &entry->file_info; } #endif /*defined(__WINDOWS__)*/ proftpd-dfsg-1.3.5~rc3/lib/libltdl/libltdl/0000755000175000017500000000000012156653653020403 5ustar frankiefrankieproftpd-dfsg-1.3.5~rc3/lib/libltdl/libltdl/lt__private.h0000644000175000017500000001065011300565264023054 0ustar frankiefrankie/* lt__private.h -- internal apis for libltdl Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. Written by Gary V. Vaughan, 2004 NOTE: The canonical source of this file is maintained with the GNU Libtool package. Report bugs to bug-libtool@gnu.org. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exception to the GNU Lesser General Public License, if you distribute this file as part of a program or library that is built using GNU libtool, you may include this file under the same distribution terms that you use for the rest of that program. GNU Libltdl is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with GNU Libltdl; see the file COPYING.LIB. If not, a copy con be downloaded from http://www.gnu.org/licenses/lgpl.html, or obtained by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if !defined(LT__PRIVATE_H) #define LT__PRIVATE_H 1 #if defined(LT_CONFIG_H) # include LT_CONFIG_H #else # include #endif #include #include #include #include #include #if defined(HAVE_UNISTD_H) # include #endif /* Import internal interfaces... */ #include "lt__alloc.h" #include "lt__dirent.h" #include "lt__strl.h" #include "lt__glibc.h" /* ...and all exported interfaces. */ #include "ltdl.h" #if defined(WITH_DMALLOC) # include #endif /* DLL building support on win32 hosts; mostly to workaround their ridiculous implementation of data symbol exporting. */ #ifndef LT_GLOBAL_DATA # if defined(__WINDOWS__) || defined(__CYGWIN__) # if defined(DLL_EXPORT) /* defined by libtool (if required) */ # define LT_GLOBAL_DATA __declspec(dllexport) # endif # endif # ifndef LT_GLOBAL_DATA # define LT_GLOBAL_DATA /* static linking or !__WINDOWS__ */ # endif #endif #ifndef __attribute__ # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ # define __attribute__(x) # endif #endif #ifndef LT__UNUSED # define LT__UNUSED __attribute__ ((__unused__)) #endif LT_BEGIN_C_DECLS #if !defined(errno) extern int errno; #endif LT_SCOPE void lt__alloc_die_callback (void); /* For readability: */ #define strneq(s1, s2) (strcmp((s1), (s2)) != 0) #define streq(s1, s2) (!strcmp((s1), (s2))) /* --- OPAQUE STRUCTURES DECLARED IN LTDL.H --- */ /* This type is used for the array of interface data sets in each handler. */ typedef struct { lt_dlinterface_id key; void * data; } lt_interface_data; struct lt__handle { lt_dlhandle next; const lt_dlvtable * vtable; /* dlopening interface */ lt_dlinfo info; /* user visible fields */ int depcount; /* number of dependencies */ lt_dlhandle * deplibs; /* dependencies */ lt_module module; /* system module handle */ void * system; /* system specific data */ lt_interface_data * interface_data; /* per caller associated data */ int flags; /* various boolean stats */ }; struct lt__advise { unsigned int try_ext:1; /* try system library extensions. */ unsigned int is_resident:1; /* module can't be unloaded. */ unsigned int is_symglobal:1; /* module symbols can satisfy subsequently loaded modules. */ unsigned int is_symlocal:1; /* module symbols are only available locally. */ unsigned int try_preload_only:1;/* only preloaded modules will be tried. */ }; /* --- ERROR HANDLING --- */ /* Extract the diagnostic strings from the error table macro in the same order as the enumerated indices in lt_error.h. */ #define LT__STRERROR(name) lt__error_string(LT_CONC(LT_ERROR_,name)) #define LT__GETERROR(lvalue) (lvalue) = lt__get_last_error() #define LT__SETERRORSTR(errormsg) lt__set_last_error(errormsg) #define LT__SETERROR(errorcode) LT__SETERRORSTR(LT__STRERROR(errorcode)) LT_SCOPE const char *lt__error_string (int errorcode); LT_SCOPE const char *lt__get_last_error (void); LT_SCOPE const char *lt__set_last_error (const char *errormsg); LT_END_C_DECLS #endif /*!defined(LT__PRIVATE_H)*/ proftpd-dfsg-1.3.5~rc3/lib/libltdl/libltdl/lt__dirent.h0000644000175000017500000000472411300565264022674 0ustar frankiefrankie/* lt__dirent.h -- internal directory entry scanning interface Copyright (C) 2001, 2004, 2006 Free Software Foundation, Inc. Written by Bob Friesenhahn, 2001 NOTE: The canonical source of this file is maintained with the GNU Libtool package. Report bugs to bug-libtool@gnu.org. GNU Libltdl is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exception to the GNU Lesser General Public License, if you distribute this file as part of a program or library that is built using GNU Libtool, you may include this file under the same distribution terms that you use for the rest of that program. GNU Libltdl is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with GNU Libltdl; see the file COPYING.LIB. If not, a copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, or obtained by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if !defined(LT__DIRENT_H) #define LT__DIRENT_H 1 #if defined(LT_CONFIG_H) # include LT_CONFIG_H #else # include #endif #include "lt_system.h" #ifdef HAVE_DIRENT_H /* We have a fully operational dirent subsystem. */ # include # define D_NAMLEN(dirent) (strlen((dirent)->d_name)) #elif defined __WINDOWS__ /* Use some wrapper code to emulate dirent on windows.. */ # define WINDOWS_DIRENT_EMULATION 1 # include # define D_NAMLEN(dirent) (strlen((dirent)->d_name)) # define dirent lt__dirent # define DIR lt__DIR # define opendir lt__opendir # define readdir lt__readdir # define closedir lt__closedir LT_BEGIN_C_DECLS struct dirent { char d_name[LT_FILENAME_MAX]; int d_namlen; }; typedef struct { HANDLE hSearch; WIN32_FIND_DATA Win32FindData; BOOL firsttime; struct dirent file_info; } DIR; LT_SCOPE DIR * opendir (const char *path); LT_SCOPE struct dirent *readdir (DIR *entry); LT_SCOPE void closedir (DIR *entry); LT_END_C_DECLS #else /* !defined(__WINDOWS__)*/ ERROR - cannot find dirent #endif /*!defined(__WINDOWS__)*/ #endif /*!defined(LT__DIRENT_H)*/ proftpd-dfsg-1.3.5~rc3/lib/libltdl/libltdl/slist.h0000644000175000017500000000617611300565264021712 0ustar frankiefrankie/* slist.h -- generalised singly linked lists Copyright (C) 2000, 2004 Free Software Foundation, Inc. Written by Gary V. Vaughan, 2000 NOTE: The canonical source of this file is maintained with the GNU Libtool package. Report bugs to bug-libtool@gnu.org. GNU Libltdl is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exception to the GNU Lesser General Public License, if you distribute this file as part of a program or library that is built using GNU Libtool, you may include this file under the same distribution terms that you use for the rest of that program. GNU Libltdl is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with GNU Libltdl; see the file COPYING.LIB. If not, a copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, or obtained by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* A generalised list. This is deliberately transparent so that you can make the NEXT field of all your chained data structures first, and then cast them to `(SList *)' so that they can be manipulated by this API. Alternatively, you can generate raw SList elements using slist_new(), and put the element data in the USERDATA field. Either way you get to manage the memory involved by yourself. */ #if !defined(SLIST_H) #define SLIST_H 1 #if defined(LTDL) # include # include #else # define LT_SCOPE #endif #if defined(__cplusplus) extern "C" { #endif typedef struct slist { struct slist *next; /* chain forward pointer*/ const void *userdata; /* for boxed `SList' item */ } SList; typedef void * SListCallback (SList *item, void *userdata); typedef int SListCompare (const SList *item1, const SList *item2, void *userdata); LT_SCOPE SList *slist_concat (SList *head, SList *tail); LT_SCOPE SList *slist_cons (SList *item, SList *slist); LT_SCOPE SList *slist_delete (SList *slist, void (*delete_fct) (void *item)); LT_SCOPE void * slist_remove (SList **phead, SListCallback *find, void *matchdata); LT_SCOPE SList *slist_reverse (SList *slist); LT_SCOPE SList *slist_sort (SList *slist, SListCompare *compare, void *userdata); LT_SCOPE SList *slist_tail (SList *slist); LT_SCOPE SList *slist_nth (SList *slist, size_t n); LT_SCOPE void * slist_find (SList *slist, SListCallback *find, void *matchdata); LT_SCOPE size_t slist_length (SList *slist); LT_SCOPE void * slist_foreach (SList *slist, SListCallback *foreach, void *userdata); LT_SCOPE SList *slist_box (const void *userdata); LT_SCOPE void * slist_unbox (SList *item); #if defined(__cplusplus) } #endif #if !defined(LTDL) # undef LT_SCOPE #endif #endif /*!defined(SLIST_H)*/ proftpd-dfsg-1.3.5~rc3/lib/libltdl/libltdl/lt_system.h0000644000175000017500000001143011300565264022564 0ustar frankiefrankie/* lt_system.h -- system portability abstraction layer Copyright (C) 2004, 2007 Free Software Foundation, Inc. Written by Gary V. Vaughan, 2004 NOTE: The canonical source of this file is maintained with the GNU Libtool package. Report bugs to bug-libtool@gnu.org. GNU Libltdl is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exception to the GNU Lesser General Public License, if you distribute this file as part of a program or library that is built using GNU Libtool, you may include this file under the same distribution terms that you use for the rest of that program. GNU Libltdl is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with GNU Libltdl; see the file COPYING.LIB. If not, a copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, or obtained by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #if !defined(LT_SYSTEM_H) #define LT_SYSTEM_H 1 #include #include #include /* Some systems do not define EXIT_*, even with STDC_HEADERS. */ #if !defined(EXIT_SUCCESS) # define EXIT_SUCCESS 0 #endif #if !defined(EXIT_FAILURE) # define EXIT_FAILURE 1 #endif /* Just pick a big number... */ #define LT_FILENAME_MAX 2048 /* Saves on those hard to debug '\0' typos.... */ #define LT_EOS_CHAR '\0' /* LTDL_BEGIN_C_DECLS should be used at the beginning of your declarations, so that C++ compilers don't mangle their names. Use LTDL_END_C_DECLS at the end of C declarations. */ #if defined(__cplusplus) # define LT_BEGIN_C_DECLS extern "C" { # define LT_END_C_DECLS } #else # define LT_BEGIN_C_DECLS /* empty */ # define LT_END_C_DECLS /* empty */ #endif /* LT_STMT_START/END are used to create macros which expand to a a single compound statement in a portable way. */ #if defined (__GNUC__) && !defined (__STRICT_ANSI__) && !defined (__cplusplus) # define LT_STMT_START (void)( # define LT_STMT_END ) #else # if (defined (sun) || defined (__sun__)) # define LT_STMT_START if (1) # define LT_STMT_END else (void)0 # else # define LT_STMT_START do # define LT_STMT_END while (0) # endif #endif /* Canonicalise Windows and Cygwin recognition macros. To match the values set by recent Cygwin compilers, make sure that if __CYGWIN__ is defined (after canonicalisation), __WINDOWS__ is NOT! */ #if defined(__CYGWIN32__) && !defined(__CYGWIN__) # define __CYGWIN__ __CYGWIN32__ #endif #if defined(__CYGWIN__) # if defined(__WINDOWS__) # undef __WINDOWS__ # endif #elif defined(_WIN32) # define __WINDOWS__ _WIN32 #elif defined(WIN32) # define __WINDOWS__ WIN32 #endif #if defined(__CYGWIN__) && defined(__WINDOWS__) # undef __WINDOWS__ #endif /* DLL building support on win32 hosts; mostly to workaround their ridiculous implementation of data symbol exporting. */ #if !defined(LT_SCOPE) # if defined(__WINDOWS__) || defined(__CYGWIN__) # if defined(DLL_EXPORT) /* defined by libtool (if required) */ # define LT_SCOPE extern __declspec(dllexport) # endif # if defined(LIBLTDL_DLL_IMPORT) /* define if linking with this dll */ /* note: cygwin/mingw compilers can rely instead on auto-import */ # define LT_SCOPE extern __declspec(dllimport) # endif # endif # if !defined(LT_SCOPE) /* static linking or !__WINDOWS__ */ # define LT_SCOPE extern # endif #endif #if defined(__WINDOWS__) /* LT_DIRSEP_CHAR is accepted *in addition* to '/' as a directory separator when it is set. */ # define LT_DIRSEP_CHAR '\\' # define LT_PATHSEP_CHAR ';' #else # define LT_PATHSEP_CHAR ':' #endif #if defined(_MSC_VER) /* Visual Studio */ # define R_OK 4 #endif /* fopen() mode flags for reading a text file */ #undef LT_READTEXT_MODE #if defined(__WINDOWS__) || defined(__CYGWIN__) # define LT_READTEXT_MODE "rt" #else # define LT_READTEXT_MODE "r" #endif /* The extra indirection to the LT__STR and LT__CONC macros is required so that if the arguments to LT_STR() (or LT_CONC()) are themselves macros, they will be expanded before being quoted. */ #ifndef LT_STR # define LT__STR(arg) #arg # define LT_STR(arg) LT__STR(arg) #endif #ifndef LT_CONC # define LT__CONC(a, b) a##b # define LT_CONC(a, b) LT__CONC(a, b) #endif #ifndef LT_CONC3 # define LT__CONC3(a, b, c) a##b##c # define LT_CONC3(a, b, c) LT__CONC3(a, b, c) #endif #endif /*!defined(LT_SYSTEM_H)*/ proftpd-dfsg-1.3.5~rc3/lib/libltdl/libltdl/lt__glibc.h0000644000175000017500000000524011300565264022461 0ustar frankiefrankie/* lt__glibc.h -- support for non glibc environments Copyright (C) 2004, 2006, 2007 Free Software Foundation, Inc. Written by Gary V. Vaughan, 2004 NOTE: The canonical source of this file is maintained with the GNU Libtool package. Report bugs to bug-libtool@gnu.org. GNU Libltdl is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exception to the GNU Lesser General Public License, if you distribute this file as part of a program or library that is built using GNU Libtool, you may include this file under the same distribution terms that you use for the rest of that program. GNU Libltdl is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with GNU Libltdl; see the file COPYING.LIB. If not, a copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, or obtained by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if !defined(LT__GLIBC_H) #define LT__GLIBC_H 1 #if defined(LT_CONFIG_H) # include LT_CONFIG_H #else # include #endif #if !defined(HAVE_ARGZ_H) || !defined(HAVE_WORKING_ARGZ) /* Redefine any glibc symbols we reimplement to import the implementations into our lt__ namespace so we don't ever clash with the system library if our clients use argz_* from there in addition to libltdl. */ # undef argz_append # define argz_append lt__argz_append # undef argz_create_sep # define argz_create_sep lt__argz_create_sep # undef argz_insert # define argz_insert lt__argz_insert # undef argz_next # define argz_next lt__argz_next # undef argz_stringify # define argz_stringify lt__argz_stringify #endif #ifdef __cplusplus extern "C" { #endif #include #ifdef __cplusplus } #endif # define slist_concat lt__slist_concat # define slist_cons lt__slist_cons # define slist_delete lt__slist_delete # define slist_remove lt__slist_remove # define slist_reverse lt__slist_reverse # define slist_sort lt__slist_sort # define slist_tail lt__slist_tail # define slist_nth lt__slist_nth # define slist_find lt__slist_find # define slist_length lt__slist_length # define slist_foreach lt__slist_foreach # define slist_box lt__slist_box # define slist_unbox lt__slist_unbox #include #endif /*!defined(LT__GLIBC_H)*/ proftpd-dfsg-1.3.5~rc3/lib/libltdl/libltdl/lt_error.h0000644000175000017500000000707211300565264022400 0ustar frankiefrankie/* lt_error.h -- error propogation interface Copyright (C) 1999, 2000, 2001, 2004, 2007 Free Software Foundation, Inc. Written by Thomas Tanner, 1999 NOTE: The canonical source of this file is maintained with the GNU Libtool package. Report bugs to bug-libtool@gnu.org. GNU Libltdl is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exception to the GNU Lesser General Public License, if you distribute this file as part of a program or library that is built using GNU Libtool, you may include this file under the same distribution terms that you use for the rest of that program. GNU Libltdl is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with GNU Libltdl; see the file COPYING.LIB. If not, a copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, or obtained by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Only include this header file once. */ #if !defined(LT_ERROR_H) #define LT_ERROR_H 1 #include LT_BEGIN_C_DECLS /* Defining error strings alongside their symbolic names in a macro in this way allows us to expand the macro in different contexts with confidence that the enumeration of symbolic names will map correctly onto the table of error strings. \0 is appended to the strings to expilicitely initialize the string terminator. */ #define lt_dlerror_table \ LT_ERROR(UNKNOWN, "unknown error\0") \ LT_ERROR(DLOPEN_NOT_SUPPORTED, "dlopen support not available\0") \ LT_ERROR(INVALID_LOADER, "invalid loader\0") \ LT_ERROR(INIT_LOADER, "loader initialization failed\0") \ LT_ERROR(REMOVE_LOADER, "loader removal failed\0") \ LT_ERROR(FILE_NOT_FOUND, "file not found\0") \ LT_ERROR(DEPLIB_NOT_FOUND, "dependency library not found\0") \ LT_ERROR(NO_SYMBOLS, "no symbols defined\0") \ LT_ERROR(CANNOT_OPEN, "can't open the module\0") \ LT_ERROR(CANNOT_CLOSE, "can't close the module\0") \ LT_ERROR(SYMBOL_NOT_FOUND, "symbol not found\0") \ LT_ERROR(NO_MEMORY, "not enough memory\0") \ LT_ERROR(INVALID_HANDLE, "invalid module handle\0") \ LT_ERROR(BUFFER_OVERFLOW, "internal buffer overflow\0") \ LT_ERROR(INVALID_ERRORCODE, "invalid errorcode\0") \ LT_ERROR(SHUTDOWN, "library already shutdown\0") \ LT_ERROR(CLOSE_RESIDENT_MODULE, "can't close resident module\0") \ LT_ERROR(INVALID_MUTEX_ARGS, "internal error (code withdrawn)\0")\ LT_ERROR(INVALID_POSITION, "invalid search path insert position\0")\ LT_ERROR(CONFLICTING_FLAGS, "symbol visibility can be global or local\0") /* Enumerate the symbolic error names. */ enum { #define LT_ERROR(name, diagnostic) LT_CONC(LT_ERROR_, name), lt_dlerror_table #undef LT_ERROR LT_ERROR_MAX }; /* Should be max of the error string lengths above (plus one for C++) */ #define LT_ERROR_LEN_MAX (41) /* These functions are only useful from inside custom module loaders. */ LT_SCOPE int lt_dladderror (const char *diagnostic); LT_SCOPE int lt_dlseterror (int errorcode); LT_END_C_DECLS #endif /*!defined(LT_ERROR_H)*/ proftpd-dfsg-1.3.5~rc3/lib/libltdl/libltdl/lt__alloc.h0000644000175000017500000000422311300565264022473 0ustar frankiefrankie/* lt__alloc.h -- internal memory management interface Copyright (C) 2004 Free Software Foundation, Inc. Written by Gary V. Vaughan, 2004 NOTE: The canonical source of this file is maintained with the GNU Libtool package. Report bugs to bug-libtool@gnu.org. GNU Libltdl is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exception to the GNU Lesser General Public License, if you distribute this file as part of a program or library that is built using GNU Libtool, you may include this file under the same distribution terms that you use for the rest of that program. GNU Libltdl is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with GNU Libltdl; see the file COPYING.LIB. If not, a copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, or obtained by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if !defined(LT__ALLOC_H) #define LT__ALLOC_H 1 #include "lt_system.h" LT_BEGIN_C_DECLS #define MALLOC(tp, n) (tp*) lt__malloc((n) * sizeof(tp)) #define REALLOC(tp, mem, n) (tp*) lt__realloc((mem), (n) * sizeof(tp)) #define FREE(mem) LT_STMT_START { \ if (mem) { free ((void *)mem); mem = NULL; } } LT_STMT_END #define MEMREASSIGN(p, q) LT_STMT_START { \ if ((p) != (q)) { if (p) free (p); (p) = (q); (q) = 0; } \ } LT_STMT_END /* If set, this function is called when memory allocation has failed. */ LT_SCOPE void (*lt__alloc_die) (void); LT_SCOPE void *lt__malloc (size_t n); LT_SCOPE void *lt__zalloc (size_t n); LT_SCOPE void *lt__realloc (void *mem, size_t n); LT_SCOPE void *lt__memdup (void const *mem, size_t n); LT_SCOPE char *lt__strdup (const char *string); LT_END_C_DECLS #endif /*!defined(LT__ALLOC_H)*/ proftpd-dfsg-1.3.5~rc3/lib/libltdl/libltdl/lt__strl.h0000644000175000017500000000370011300565264022364 0ustar frankiefrankie/* lt__strl.h -- size-bounded string copying and concatenation Copyright (C) 2004, 2006 Free Software Foundation, Inc. Written by Bob Friesenhahn, 2004 NOTE: The canonical source of this file is maintained with the GNU Libtool package. Report bugs to bug-libtool@gnu.org. GNU Libltdl is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exception to the GNU Lesser General Public License, if you distribute this file as part of a program or library that is built using GNU Libtool, you may include this file under the same distribution terms that you use for the rest of that program. GNU Libltdl is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with GNU Libltdl; see the file COPYING.LIB. If not, a copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, or obtained by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #if !defined(LT__STRL_H) #define LT__STRL_H 1 #if defined(LT_CONFIG_H) # include LT_CONFIG_H #else # include #endif #include #include "lt_system.h" #if !defined(HAVE_STRLCAT) # define strlcat(dst,src,dstsize) lt_strlcat(dst,src,dstsize) LT_SCOPE size_t lt_strlcat(char *dst, const char *src, const size_t dstsize); #endif /* !defined(HAVE_STRLCAT) */ #if !defined(HAVE_STRLCPY) # define strlcpy(dst,src,dstsize) lt_strlcpy(dst,src,dstsize) LT_SCOPE size_t lt_strlcpy(char *dst, const char *src, const size_t dstsize); #endif /* !defined(HAVE_STRLCPY) */ #endif /*!defined(LT__STRL_H)*/ proftpd-dfsg-1.3.5~rc3/lib/libltdl/libltdl/lt_dlloader.h0000644000175000017500000000616411300565264023036 0ustar frankiefrankie/* lt_dlloader.h -- dynamic library loader interface Copyright (C) 2004, 2007, 2008 Free Software Foundation, Inc. Written by Gary V. Vaughan, 2004 NOTE: The canonical source of this file is maintained with the GNU Libtool package. Report bugs to bug-libtool@gnu.org. GNU Libltdl is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exception to the GNU Lesser General Public License, if you distribute this file as part of a program or library that is built using GNU Libtool, you may include this file under the same distribution terms that you use for the rest of that program. GNU Libltdl is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with GNU Libltdl; see the file COPYING.LIB. If not, a copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, or obtained by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #if !defined(LT_DLLOADER_H) #define LT_DLLOADER_H 1 #include LT_BEGIN_C_DECLS typedef void * lt_dlloader; typedef void * lt_module; typedef void * lt_user_data; typedef struct lt__advise * lt_dladvise; /* Function pointer types for module loader vtable entries: */ typedef lt_module lt_module_open (lt_user_data data, const char *filename, lt_dladvise advise); typedef int lt_module_close (lt_user_data data, lt_module module); typedef void * lt_find_sym (lt_user_data data, lt_module module, const char *symbolname); typedef int lt_dlloader_init (lt_user_data data); typedef int lt_dlloader_exit (lt_user_data data); /* Default priority is LT_DLLOADER_PREPEND if none is explicitly given. */ typedef enum { LT_DLLOADER_PREPEND = 0, LT_DLLOADER_APPEND } lt_dlloader_priority; /* This structure defines a module loader, as populated by the get_vtable entry point of each loader. */ typedef struct { const char * name; const char * sym_prefix; lt_module_open * module_open; lt_module_close * module_close; lt_find_sym * find_sym; lt_dlloader_init * dlloader_init; lt_dlloader_exit * dlloader_exit; lt_user_data dlloader_data; lt_dlloader_priority priority; } lt_dlvtable; LT_SCOPE int lt_dlloader_add (const lt_dlvtable *vtable); LT_SCOPE lt_dlloader lt_dlloader_next (const lt_dlloader loader); LT_SCOPE lt_dlvtable * lt_dlloader_remove (char *name); LT_SCOPE const lt_dlvtable *lt_dlloader_find (char *name); LT_SCOPE const lt_dlvtable *lt_dlloader_get (lt_dlloader loader); /* Type of a function to get a loader's vtable: */ typedef const lt_dlvtable *lt_get_vtable (lt_user_data data); #ifdef LT_DEBUG_LOADERS LT_SCOPE void lt_dlloader_dump (void); #endif LT_END_C_DECLS #endif /*!defined(LT_DLLOADER_H)*/ proftpd-dfsg-1.3.5~rc3/lib/libltdl/configure.ac0000644000175000017500000000501011300565264021225 0ustar frankiefrankie# Process this file with autoconf to create configure. -*- autoconf -*- # # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # NOTE: The canonical source of this file is maintained with the # GNU Libtool package. Report bugs to bug-libtool@gnu.org. # # GNU Libltdl is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # As a special exception to the GNU Lesser General Public License, # if you distribute this file as part of a program or library that # is built using GNU libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libltdl is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU LesserGeneral Public # License along with GNU Libltdl; see the file COPYING.LIB. If not, a # copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, # or obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #### # This configure.ac is not used at all by the libtool bootstrap, but # is copied to the ltdl subdirectory if you libtoolize --ltdl your own # project. Adding LT_WITH_LTDL to your project configure.ac will then # configure this directory if your user doesn't want to use the installed # libltdl. AC_PREREQ(2.59)dnl We use AS_HELP_STRING ## ------------------------ ## ## Autoconf initialisation. ## ## ------------------------ ## AC_INIT([libltdl], [2.2.6], [bug-libtool@gnu.org]) AC_CONFIG_HEADERS([config.h:config-h.in]) AC_CONFIG_SRCDIR([ltdl.c]) AC_CONFIG_AUX_DIR([config]) AC_CONFIG_MACRO_DIR([m4]) LT_CONFIG_LTDL_DIR([.]) # I am me! ## ------------------------ ## ## Automake Initialisation. ## ## ------------------------ ## AM_INIT_AUTOMAKE([gnu]) ## ------------------------------- ## ## Libtool specific configuration. ## ## ------------------------------- ## pkgdatadir='${datadir}'"/${PACKAGE}" ## ----------------------- ## ## Libtool initialisation. ## ## ----------------------- ## LT_INIT([dlopen win32-dll]) _LTDL_SETUP ## -------- ## ## Outputs. ## ## -------- ## AC_CONFIG_FILES([Makefile]) AC_OUTPUT proftpd-dfsg-1.3.5~rc3/lib/libltdl/slist.c0000644000175000017500000002305711300565264020254 0ustar frankiefrankie/* slist.c -- generalised singly linked lists Copyright (C) 2000, 2004, 2007, 2008 Free Software Foundation, Inc. Written by Gary V. Vaughan, 2000 NOTE: The canonical source of this file is maintained with the GNU Libtool package. Report bugs to bug-libtool@gnu.org. GNU Libltdl is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exception to the GNU Lesser General Public License, if you distribute this file as part of a program or library that is built using GNU Libtool, you may include this file under the same distribution terms that you use for the rest of that program. GNU Libltdl is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with GNU Libltdl; see the file COPYING.LIB. If not, a copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, or obtained by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "slist.h" #include static SList * slist_sort_merge (SList *left, SList *right, SListCompare *compare, void *userdata); /* Call DELETE repeatedly on each element of HEAD. CAVEAT: If you call this when HEAD is the start of a list of boxed items, you must remember that each item passed back to your DELETE function will be a boxed item that must be slist_unbox()ed before operating on its contents. e.g. void boxed_delete (void *item) { item_free (slist_unbox (item)); } ... slist = slist_delete (slist, boxed_delete); ... */ SList * slist_delete (SList *head, void (*delete_fct) (void *item)) { assert (delete_fct); while (head) { SList *next = head->next; (*delete_fct) (head); head = next; } return 0; } /* Call FIND repeatedly with MATCHDATA and each item of *PHEAD, until FIND returns non-NULL, or the list is exhausted. If a match is found the matching item is destructively removed from *PHEAD, and the value returned by the matching call to FIND is returned. CAVEAT: To avoid memory leaks, unless you already have the address of the stale item, you should probably return that from FIND if it makes a successful match. Don't forget to slist_unbox() every item in a boxed list before operating on its contents. */ void * slist_remove (SList **phead, SListCallback *find, void *matchdata) { SList *stale = 0; void *result = 0; assert (find); if (!phead || !*phead) return 0; /* Does the head of the passed list match? */ result = (*find) (*phead, matchdata); if (result) { stale = *phead; *phead = stale->next; } /* what about the rest of the elements? */ else { SList *head; for (head = *phead; head->next; head = head->next) { result = (*find) (head->next, matchdata); if (result) { stale = head->next; head->next = stale->next; break; } } } return result; } /* Call FIND repeatedly with each element of SLIST and MATCHDATA, until FIND returns non-NULL, or the list is exhausted. If a match is found the value returned by the matching call to FIND is returned. */ void * slist_find (SList *slist, SListCallback *find, void *matchdata) { void *result = 0; assert (find); for (; slist; slist = slist->next) { result = (*find) (slist, matchdata); if (result) break; } return result; } /* Return a single list, composed by destructively concatenating the items in HEAD and TAIL. The values of HEAD and TAIL are undefined after calling this function. CAVEAT: Don't mix boxed and unboxed items in a single list. e.g. slist1 = slist_concat (slist1, slist2); */ SList * slist_concat (SList *head, SList *tail) { SList *last; if (!head) { return tail; } last = head; while (last->next) last = last->next; last->next = tail; return head; } /* Return a single list, composed by destructively appending all of the items in SLIST to ITEM. The values of ITEM and SLIST are undefined after calling this function. CAVEAT: Don't mix boxed and unboxed items in a single list. e.g. slist1 = slist_cons (slist_box (data), slist1); */ SList * slist_cons (SList *item, SList *slist) { if (!item) { return slist; } assert (!item->next); item->next = slist; return item; } /* Return a list starting at the second item of SLIST. */ SList * slist_tail (SList *slist) { return slist ? slist->next : NULL; } /* Return a list starting at the Nth item of SLIST. If SLIST is less than N items long, NULL is returned. Just to be confusing, list items are counted from 1, to get the 2nd element of slist: e.g. shared_list = slist_nth (slist, 2); */ SList * slist_nth (SList *slist, size_t n) { for (;n > 1 && slist; n--) slist = slist->next; return slist; } /* Return the number of items in SLIST. We start counting from 1, so the length of a list with no items is 0, and so on. */ size_t slist_length (SList *slist) { size_t n; for (n = 0; slist; ++n) slist = slist->next; return n; } /* Destructively reverse the order of items in SLIST. The value of SLIST is undefined after calling this function. CAVEAT: You must store the result of this function, or you might not be able to get all the items except the first one back again. e.g. slist = slist_reverse (slist); */ SList * slist_reverse (SList *slist) { SList *result = 0; SList *next; while (slist) { next = slist->next; slist->next = result; result = slist; slist = next; } return result; } /* Call FOREACH once for each item in SLIST, passing both the item and USERDATA on each call. */ void * slist_foreach (SList *slist, SListCallback *foreach, void *userdata) { void *result = 0; assert (foreach); while (slist) { SList *next = slist->next; result = (*foreach) (slist, userdata); if (result) break; slist = next; } return result; } /* Destructively merge the items of two ordered lists LEFT and RIGHT, returning a single sorted list containing the items of both -- Part of the quicksort algorithm. The values of LEFT and RIGHT are undefined after calling this function. At each iteration, add another item to the merged list by taking the lowest valued item from the head of either LEFT or RIGHT, determined by passing those items and USERDATA to COMPARE. COMPARE should return less than 0 if the head of LEFT has the lower value, greater than 0 if the head of RIGHT has the lower value, otherwise 0. */ static SList * slist_sort_merge (SList *left, SList *right, SListCompare *compare, void *userdata) { SList merged, *insert; insert = &merged; while (left && right) { if ((*compare) (left, right, userdata) <= 0) { insert = insert->next = left; left = left->next; } else { insert = insert->next = right; right = right->next; } } insert->next = left ? left : right; return merged.next; } /* Perform a destructive quicksort on the items in SLIST, by repeatedly calling COMPARE with a pair of items from SLIST along with USERDATA at every iteration. COMPARE is a function as defined above for slist_sort_merge(). The value of SLIST is undefined after calling this function. e.g. slist = slist_sort (slist, compare, 0); */ SList * slist_sort (SList *slist, SListCompare *compare, void *userdata) { SList *left, *right; if (!slist) return slist; /* Be sure that LEFT and RIGHT never contain the same item. */ left = slist; right = slist->next; /* Skip two items with RIGHT and one with SLIST, until RIGHT falls off the end. SLIST must be about half way along. */ while (right && (right = right->next)) { if (!right || !(right = right->next)) break; slist = slist->next; } right = slist->next; slist->next = 0; /* Sort LEFT and RIGHT, then merge the two. */ return slist_sort_merge (slist_sort (left, compare, userdata), slist_sort (right, compare, userdata), compare, userdata); } /* Aside from using the functions above to manage chained structures of any type that has a NEXT pointer as its first field, SLISTs can be comprised of boxed items. The boxes are chained together in that case, so there is no need for a NEXT field in the item proper. Some care must be taken to slist_box and slist_unbox each item in a boxed list at the appropriate points to avoid leaking the memory used for the boxes. It us usually a very bad idea to mix boxed and non-boxed items in a single list. */ /* Return a `boxed' freshly mallocated 1 element list containing USERDATA. */ SList * slist_box (const void *userdata) { SList *item = (SList *) malloc (sizeof *item); if (item) { item->next = 0; item->userdata = userdata; } return item; } /* Return the contents of a `boxed' ITEM, recycling the box itself. */ void * slist_unbox (SList *item) { void *userdata = 0; if (item) { /* Strip the const, because responsibility for this memory passes to the caller on return. */ userdata = (void *) item->userdata; free (item); } return userdata; } proftpd-dfsg-1.3.5~rc3/lib/libltdl/loaders/0000755000175000017500000000000012156653653020406 5ustar frankiefrankieproftpd-dfsg-1.3.5~rc3/lib/libltdl/loaders/dld_link.c0000644000175000017500000001074111300565264022323 0ustar frankiefrankie/* loader-dld_link.c -- dynamic linking with dld Copyright (C) 1998, 1999, 2000, 2004, 2006, 2007, 2008 Free Software Foundation, Inc. Written by Thomas Tanner, 1998 NOTE: The canonical source of this file is maintained with the GNU Libtool package. Report bugs to bug-libtool@gnu.org. GNU Libltdl is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exception to the GNU Lesser General Public License, if you distribute this file as part of a program or library that is built using GNU Libtool, you may include this file under the same distribution terms that you use for the rest of that program. GNU Libltdl is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with GNU Libltdl; see the file COPYING.LIB. If not, a copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, or obtained by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "lt__private.h" #include "lt_dlloader.h" /* Use the preprocessor to rename non-static symbols to avoid namespace collisions when the loader code is statically linked into libltdl. Use the "_LTX_" prefix so that the symbol addresses can be fetched from the preloaded symbol list by lt_dlsym(): */ #define get_vtable dld_link_LTX_get_vtable LT_BEGIN_C_DECLS LT_SCOPE lt_dlvtable *get_vtable (lt_user_data loader_data); LT_END_C_DECLS /* Boilerplate code to set up the vtable for hooking this loader into libltdl's loader list: */ static int vl_exit (lt_user_data loader_data); static lt_module vm_open (lt_user_data loader_data, const char *filename, lt_dladvise advise); static int vm_close (lt_user_data loader_data, lt_module module); static void * vm_sym (lt_user_data loader_data, lt_module module, const char *symbolname); static lt_dlvtable *vtable = 0; /* Return the vtable for this loader, only the name and sym_prefix attributes (plus the virtual function implementations, obviously) change between loaders. */ lt_dlvtable * get_vtable (lt_user_data loader_data) { if (!vtable) { vtable = lt__zalloc (sizeof *vtable); } if (vtable && !vtable->name) { vtable->name = "lt_dld_link"; vtable->module_open = vm_open; vtable->module_close = vm_close; vtable->find_sym = vm_sym; vtable->dlloader_exit = vl_exit; vtable->dlloader_data = loader_data; vtable->priority = LT_DLLOADER_APPEND; } if (vtable && (vtable->dlloader_data != loader_data)) { LT__SETERROR (INIT_LOADER); return 0; } return vtable; } /* --- IMPLEMENTATION --- */ #if defined(HAVE_DLD_H) # include #endif /* A function called through the vtable when this loader is no longer needed by the application. */ static int vl_exit (lt_user_data LT__UNUSED loader_data) { vtable = NULL; return 0; } /* A function called through the vtable to open a module with this loader. Returns an opaque representation of the newly opened module for processing with this loader's other vtable functions. */ static lt_module vm_open (lt_user_data LT__UNUSED loader_data, const char *filename, lt_dladvise LT__UNUSED advise) { lt_module module = lt__strdup (filename); if (dld_link (filename) != 0) { LT__SETERROR (CANNOT_OPEN); FREE (module); } return module; } /* A function called through the vtable when a particular module should be unloaded. */ static int vm_close (lt_user_data LT__UNUSED loader_data, lt_module module) { int errors = 0; if (dld_unlink_by_file ((char*)(module), 1) != 0) { LT__SETERROR (CANNOT_CLOSE); ++errors; } else { FREE (module); } return errors; } /* A function called through the vtable to get the address of a symbol loaded from a particular module. */ static void * vm_sym (lt_user_data LT__UNUSED loader_data, lt_module LT__UNUSED module, const char *name) { void *address = dld_get_func (name); if (!address) { LT__SETERROR (SYMBOL_NOT_FOUND); } return address; } proftpd-dfsg-1.3.5~rc3/lib/libltdl/loaders/shl_load.c0000644000175000017500000001507611300565264022336 0ustar frankiefrankie/* loader-shl_load.c -- dynamic linking with shl_load (HP-UX) Copyright (C) 1998, 1999, 2000, 2004, 2006, 2007, 2008 Free Software Foundation, Inc. Written by Thomas Tanner, 1998 NOTE: The canonical source of this file is maintained with the GNU Libtool package. Report bugs to bug-libtool@gnu.org. GNU Libltdl is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exception to the GNU Lesser General Public License, if you distribute this file as part of a program or library that is built using GNU Libtool, you may include this file under the same distribution terms that you use for the rest of that program. GNU Libltdl is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with GNU Libltdl; see the file COPYING.LIB. If not, a copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, or obtained by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "lt__private.h" #include "lt_dlloader.h" /* Use the preprocessor to rename non-static symbols to avoid namespace collisions when the loader code is statically linked into libltdl. Use the "_LTX_" prefix so that the symbol addresses can be fetched from the preloaded symbol list by lt_dlsym(): */ #define get_vtable shl_load_LTX_get_vtable LT_BEGIN_C_DECLS LT_SCOPE lt_dlvtable *get_vtable (lt_user_data loader_data); LT_END_C_DECLS /* Boilerplate code to set up the vtable for hooking this loader into libltdl's loader list: */ static int vl_exit (lt_user_data loader_data); static lt_module vm_open (lt_user_data loader_data, const char *filename, lt_dladvise advise); static int vm_close (lt_user_data loader_data, lt_module module); static void * vm_sym (lt_user_data loader_data, lt_module module, const char *symbolname); static lt_dlvtable *vtable = 0; /* Return the vtable for this loader, only the name and sym_prefix attributes (plus the virtual function implementations, obviously) change between loaders. */ lt_dlvtable * get_vtable (lt_user_data loader_data) { if (!vtable) { vtable = lt__zalloc (sizeof *vtable); } if (vtable && !vtable->name) { vtable->name = "lt_shl_load"; vtable->module_open = vm_open; vtable->module_close = vm_close; vtable->find_sym = vm_sym; vtable->dlloader_exit = vl_exit; vtable->dlloader_data = loader_data; vtable->priority = LT_DLLOADER_APPEND; } if (vtable && (vtable->dlloader_data != loader_data)) { LT__SETERROR (INIT_LOADER); return 0; } return vtable; } /* --- IMPLEMENTATION --- */ #if defined(HAVE_DL_H) # include #endif /* some flags are missing on some systems, so we provide * harmless defaults. * * Mandatory: * BIND_IMMEDIATE - Resolve symbol references when the library is loaded. * BIND_DEFERRED - Delay code symbol resolution until actual reference. * * Optionally: * BIND_FIRST - Place the library at the head of the symbol search * order. * BIND_NONFATAL - The default BIND_IMMEDIATE behavior is to treat all * unsatisfied symbols as fatal. This flag allows * binding of unsatisfied code symbols to be deferred * until use. * [Perl: For certain libraries, like DCE, deferred * binding often causes run time problems. Adding * BIND_NONFATAL to BIND_IMMEDIATE still allows * unresolved references in situations like this.] * BIND_NOSTART - Do not call the initializer for the shared library * when the library is loaded, nor on a future call to * shl_unload(). * BIND_VERBOSE - Print verbose messages concerning possible * unsatisfied symbols. * * hp9000s700/hp9000s800: * BIND_RESTRICTED - Restrict symbols visible by the library to those * present at library load time. * DYNAMIC_PATH - Allow the loader to dynamically search for the * library specified by the path argument. */ #if !defined(DYNAMIC_PATH) # define DYNAMIC_PATH 0 #endif #if !defined(BIND_RESTRICTED) # define BIND_RESTRICTED 0 #endif #define LT_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH) /* A function called through the vtable when this loader is no longer needed by the application. */ static int vl_exit (lt_user_data LT__UNUSED loader_data) { vtable = NULL; return 0; } /* A function called through the vtable to open a module with this loader. Returns an opaque representation of the newly opened module for processing with this loader's other vtable functions. */ static lt_module vm_open (lt_user_data LT__UNUSED loader_data, const char *filename, lt_dladvise LT__UNUSED advise) { static shl_t self = (shl_t) 0; lt_module module = shl_load (filename, LT_BIND_FLAGS, 0L); /* Since searching for a symbol against a NULL module handle will also look in everything else that was already loaded and exported with the -E compiler flag, we always cache a handle saved before any modules are loaded. */ if (!self) { void *address; shl_findsym (&self, "main", TYPE_UNDEFINED, &address); } if (!filename) { module = self; } else { module = shl_load (filename, LT_BIND_FLAGS, 0L); if (!module) { LT__SETERROR (CANNOT_OPEN); } } return module; } /* A function called through the vtable when a particular module should be unloaded. */ static int vm_close (lt_user_data LT__UNUSED loader_data, lt_module module) { int errors = 0; if (module && (shl_unload ((shl_t) (module)) != 0)) { LT__SETERROR (CANNOT_CLOSE); ++errors; } return errors; } /* A function called through the vtable to get the address of a symbol loaded from a particular module. */ static void * vm_sym (lt_user_data LT__UNUSED loader_data, lt_module module, const char *name) { void *address = 0; /* sys_shl_open should never return a NULL module handle */ if (module == (lt_module) 0) { LT__SETERROR (INVALID_HANDLE); } else if (!shl_findsym((shl_t*) &module, name, TYPE_UNDEFINED, &address)) { if (!address) { LT__SETERROR (SYMBOL_NOT_FOUND); } } return address; } proftpd-dfsg-1.3.5~rc3/lib/libltdl/loaders/preopen.c0000644000175000017500000002245511300565264022220 0ustar frankiefrankie/* loader-preopen.c -- emulate dynamic linking using preloaded_symbols Copyright (C) 1998, 1999, 2000, 2004, 2006, 2007, 2008 Free Software Foundation, Inc. Written by Thomas Tanner, 1998 NOTE: The canonical source of this file is maintained with the GNU Libtool package. Report bugs to bug-libtool@gnu.org. GNU Libltdl is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exception to the GNU Lesser General Public License, if you distribute this file as part of a program or library that is built using GNU Libtool, you may include this file under the same distribution terms that you use for the rest of that program. GNU Libltdl is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with GNU Libltdl; see the file COPYING.LIB. If not, a copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, or obtained by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "lt__private.h" #include "lt_dlloader.h" /* Use the preprocessor to rename non-static symbols to avoid namespace collisions when the loader code is statically linked into libltdl. Use the "_LTX_" prefix so that the symbol addresses can be fetched from the preloaded symbol list by lt_dlsym(): */ #define get_vtable preopen_LTX_get_vtable LT_BEGIN_C_DECLS LT_SCOPE lt_dlvtable *get_vtable (lt_user_data loader_data); LT_END_C_DECLS /* Boilerplate code to set up the vtable for hooking this loader into libltdl's loader list: */ static int vl_init (lt_user_data loader_data); static int vl_exit (lt_user_data loader_data); static lt_module vm_open (lt_user_data loader_data, const char *filename, lt_dladvise advise); static int vm_close (lt_user_data loader_data, lt_module module); static void * vm_sym (lt_user_data loader_data, lt_module module, const char *symbolname); static lt_dlvtable *vtable = 0; /* Return the vtable for this loader, only the name and sym_prefix attributes (plus the virtual function implementations, obviously) change between loaders. */ lt_dlvtable * get_vtable (lt_user_data loader_data) { if (!vtable) { vtable = (lt_dlvtable *) lt__zalloc (sizeof *vtable); } if (vtable && !vtable->name) { vtable->name = "lt_preopen"; vtable->sym_prefix = 0; vtable->module_open = vm_open; vtable->module_close = vm_close; vtable->find_sym = vm_sym; vtable->dlloader_init = vl_init; vtable->dlloader_exit = vl_exit; vtable->dlloader_data = loader_data; vtable->priority = LT_DLLOADER_PREPEND; } if (vtable && (vtable->dlloader_data != loader_data)) { LT__SETERROR (INIT_LOADER); return 0; } return vtable; } /* --- IMPLEMENTATION --- */ /* Wrapper type to chain together symbol lists of various origins. */ typedef struct symlist_chain { struct symlist_chain *next; const lt_dlsymlist *symlist; } symlist_chain; static int add_symlist (const lt_dlsymlist *symlist); static int free_symlists (void); /* The start of the symbol lists chain. */ static symlist_chain *preloaded_symlists = 0; /* A symbol list preloaded before lt_init() was called. */ static const lt_dlsymlist *default_preloaded_symbols = 0; /* A function called through the vtable to initialise this loader. */ static int vl_init (lt_user_data LT__UNUSED loader_data) { int errors = 0; preloaded_symlists = 0; if (default_preloaded_symbols) { errors = lt_dlpreload (default_preloaded_symbols); } return errors; } /* A function called through the vtable when this loader is no longer needed by the application. */ static int vl_exit (lt_user_data LT__UNUSED loader_data) { vtable = NULL; free_symlists (); return 0; } /* A function called through the vtable to open a module with this loader. Returns an opaque representation of the newly opened module for processing with this loader's other vtable functions. */ static lt_module vm_open (lt_user_data LT__UNUSED loader_data, const char *filename, lt_dladvise LT__UNUSED advise) { symlist_chain *lists; lt_module module = 0; if (!preloaded_symlists) { LT__SETERROR (NO_SYMBOLS); goto done; } /* Can't use NULL as the reflective symbol header, as NULL is used to mark the end of the entire symbol list. Self-dlpreopened symbols follow this magic number, chosen to be an unlikely clash with a real module name. */ if (!filename) { filename = "@PROGRAM@"; } for (lists = preloaded_symlists; lists; lists = lists->next) { const lt_dlsymlist *symbol; for (symbol= lists->symlist; symbol->name; ++symbol) { if (!symbol->address && streq (symbol->name, filename)) { /* If the next symbol's name and address is 0, it means the module just contains the originator and no symbols. In this case we pretend that we never saw the module and hope that some other loader will be able to load the module and have access to its symbols */ const lt_dlsymlist *next_symbol = symbol +1; if (next_symbol->address && next_symbol->name) { module = (lt_module) lists->symlist; goto done; } } } } LT__SETERROR (FILE_NOT_FOUND); done: return module; } /* A function called through the vtable when a particular module should be unloaded. */ static int vm_close (lt_user_data LT__UNUSED loader_data, lt_module LT__UNUSED module) { /* Just to silence gcc -Wall */ module = 0; return 0; } /* A function called through the vtable to get the address of a symbol loaded from a particular module. */ static void * vm_sym (lt_user_data LT__UNUSED loader_data, lt_module module, const char *name) { lt_dlsymlist *symbol = (lt_dlsymlist*) module; symbol +=2; /* Skip header (originator then libname). */ while (symbol->name) { if (streq (symbol->name, name)) { return symbol->address; } ++symbol; } LT__SETERROR (SYMBOL_NOT_FOUND); return 0; } /* --- HELPER FUNCTIONS --- */ /* The symbol lists themselves are not allocated from the heap, but we can unhook them and free up the chain of links between them. */ static int free_symlists (void) { symlist_chain *lists; lists = preloaded_symlists; while (lists) { symlist_chain *next = lists->next; FREE (lists); lists = next; } preloaded_symlists = 0; return 0; } /* Add a new symbol list to the global chain. */ static int add_symlist (const lt_dlsymlist *symlist) { symlist_chain *lists; int errors = 0; /* Search for duplicate entries: */ for (lists = preloaded_symlists; lists && lists->symlist != symlist; lists = lists->next) /*NOWORK*/; /* Don't add the same list twice: */ if (!lists) { symlist_chain *tmp = (symlist_chain *) lt__zalloc (sizeof *tmp); if (tmp) { tmp->symlist = symlist; tmp->next = preloaded_symlists; preloaded_symlists = tmp; } else { ++errors; } } return errors; } /* --- PRELOADING API CALL IMPLEMENTATIONS --- */ /* Save a default symbol list for later. */ int lt_dlpreload_default (const lt_dlsymlist *preloaded) { default_preloaded_symbols = preloaded; return 0; } /* Add a symbol list to the global chain, or with a NULL argument, revert to just the default list. */ int lt_dlpreload (const lt_dlsymlist *preloaded) { int errors = 0; if (preloaded) { errors = add_symlist (preloaded); } else { free_symlists(); if (default_preloaded_symbols) { errors = lt_dlpreload (default_preloaded_symbols); } } return errors; } /* Open all the preloaded modules from the named originator, executing a callback for each one. If ORIGINATOR is NULL, then call FUNC for each preloaded module from the program itself. */ int lt_dlpreload_open (const char *originator, lt_dlpreload_callback_func *func) { symlist_chain *list; int errors = 0; int found = 0; /* For each symlist in the chain... */ for (list = preloaded_symlists; list; list = list->next) { /* ...that was preloaded by the requesting ORIGINATOR... */ if ((originator && streq (list->symlist->name, originator)) || (!originator && streq (list->symlist->name, "@PROGRAM@"))) { const lt_dlsymlist *symbol; unsigned int idx = 0; ++found; /* ...load the symbols per source compilation unit: (we preincrement the index to skip over the originator entry) */ while ((symbol = &list->symlist[++idx])->name != 0) { if ((symbol->address == 0) && (strneq (symbol->name, "@PROGRAM@"))) { lt_dlhandle handle = lt_dlopen (symbol->name); if (handle == 0) { ++errors; } else { errors += (*func) (handle); } } } } } if (!found) { LT__SETERROR(CANNOT_OPEN); ++errors; } return errors; } proftpd-dfsg-1.3.5~rc3/lib/libltdl/loaders/dyld.c0000644000175000017500000003253611300565264021505 0ustar frankiefrankie/* loader-dyld.c -- dynamic linking on darwin and OS X Copyright (C) 1998, 1999, 2000, 2004, 2006, 2007, 2008 Free Software Foundation, Inc. Written by Peter O'Gorman, 1998 NOTE: The canonical source of this file is maintained with the GNU Libtool package. Report bugs to bug-libtool@gnu.org. GNU Libltdl is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exception to the GNU Lesser General Public License, if you distribute this file as part of a program or library that is built using GNU Libtool, you may include this file under the same distribution terms that you use for the rest of that program. GNU Libltdl is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with GNU Libltdl; see the file COPYING.LIB. If not, a copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, or obtained by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "lt__private.h" #include "lt_dlloader.h" /* Use the preprocessor to rename non-static symbols to avoid namespace collisions when the loader code is statically linked into libltdl. Use the "_LTX_" prefix so that the symbol addresses can be fetched from the preloaded symbol list by lt_dlsym(): */ #define get_vtable dyld_LTX_get_vtable LT_BEGIN_C_DECLS LT_SCOPE lt_dlvtable *get_vtable (lt_user_data loader_data); LT_END_C_DECLS /* Boilerplate code to set up the vtable for hooking this loader into libltdl's loader list: */ static int vl_init (lt_user_data loader_data); static int vl_exit (lt_user_data loader_data); static lt_module vm_open (lt_user_data loader_data, const char *filename, lt_dladvise advise); static int vm_close (lt_user_data loader_data, lt_module module); static void * vm_sym (lt_user_data loader_data, lt_module module, const char *symbolname); static lt_dlvtable *vtable = 0; /* Return the vtable for this loader, only the name and sym_prefix attributes (plus the virtual function implementations, obviously) change between loaders. */ lt_dlvtable * get_vtable (lt_user_data loader_data) { if (!vtable) { vtable = lt__zalloc (sizeof *vtable); } if (vtable && !vtable->name) { vtable->name = "lt_dyld"; vtable->sym_prefix = "_"; vtable->dlloader_init = vl_init; vtable->module_open = vm_open; vtable->module_close = vm_close; vtable->find_sym = vm_sym; vtable->dlloader_exit = vl_exit; vtable->dlloader_data = loader_data; vtable->priority = LT_DLLOADER_APPEND; } if (vtable && (vtable->dlloader_data != loader_data)) { LT__SETERROR (INIT_LOADER); return 0; } return vtable; } /* --- IMPLEMENTATION --- */ #if defined(HAVE_MACH_O_DYLD_H) # if !defined(__APPLE_CC__) && !defined(__MWERKS__) && !defined(__private_extern__) /* Is this correct? Does it still function properly? */ # define __private_extern__ extern # endif # include #endif #include /* We have to put some stuff here that isn't in older dyld.h files */ #if !defined(ENUM_DYLD_BOOL) # define ENUM_DYLD_BOOL # undef FALSE # undef TRUE enum DYLD_BOOL { FALSE, TRUE }; #endif #if !defined(LC_REQ_DYLD) # define LC_REQ_DYLD 0x80000000 #endif #if !defined(LC_LOAD_WEAK_DYLIB) # define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD) #endif #if !defined(NSADDIMAGE_OPTION_NONE) # define NSADDIMAGE_OPTION_NONE 0x0 #endif #if !defined(NSADDIMAGE_OPTION_RETURN_ON_ERROR) # define NSADDIMAGE_OPTION_RETURN_ON_ERROR 0x1 #endif #if !defined(NSADDIMAGE_OPTION_WITH_SEARCHING) # define NSADDIMAGE_OPTION_WITH_SEARCHING 0x2 #endif #if !defined(NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED) # define NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED 0x4 #endif #if !defined(NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME) # define NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME 0x8 #endif #if !defined(NSLOOKUPSYMBOLINIMAGE_OPTION_BIND) # define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND 0x0 #endif #if !defined(NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW) # define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW 0x1 #endif #if !defined(NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY) # define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY 0x2 #endif #if !defined(NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR) # define NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR 0x4 #endif #define LT__SYMLOOKUP_OPTS (NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW \ | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR) #if defined(__BIG_ENDIAN__) # define LT__MAGIC MH_MAGIC #else # define LT__MAGIC MH_CIGAM #endif #define DYLD__SETMYERROR(errmsg) LT__SETERRORSTR (dylderror (errmsg)) #define DYLD__SETERROR(errcode) DYLD__SETMYERROR (LT__STRERROR (errcode)) typedef struct mach_header mach_header; typedef struct dylib_command dylib_command; static const char *dylderror (const char *errmsg); static const mach_header *lt__nsmodule_get_header (NSModule module); static const char *lt__header_get_instnam (const mach_header *mh); static const mach_header *lt__match_loadedlib (const char *name); static NSSymbol lt__linkedlib_symbol (const char *symname, const mach_header *mh); static const mach_header *(*lt__addimage) (const char *image_name, unsigned long options) = 0; static NSSymbol (*lt__image_symbol) (const mach_header *image, const char *symbolName, unsigned long options) = 0; static enum DYLD_BOOL (*lt__image_symbol_p) (const mach_header *image, const char *symbolName) = 0; static enum DYLD_BOOL (*lt__module_export) (NSModule module) = 0; static int dyld_cannot_close = 0; /* A function called through the vtable when this loader is no longer needed by the application. */ static int vl_exit (lt_user_data LT__UNUSED loader_data) { vtable = NULL; return 0; } /* A function called through the vtable to initialise this loader. */ static int vl_init (lt_user_data loader_data) { int errors = 0; if (! dyld_cannot_close) { if (!_dyld_present ()) { ++errors; } else { (void) _dyld_func_lookup ("__dyld_NSAddImage", (unsigned long*) <__addimage); (void) _dyld_func_lookup ("__dyld_NSLookupSymbolInImage", (unsigned long*)<__image_symbol); (void) _dyld_func_lookup ("__dyld_NSIsSymbolNameDefinedInImage", (unsigned long*) <__image_symbol_p); (void) _dyld_func_lookup ("__dyld_NSMakePrivateModulePublic", (unsigned long*) <__module_export); dyld_cannot_close = lt_dladderror ("can't close a dylib"); } } return errors; } /* A function called through the vtable to open a module with this loader. Returns an opaque representation of the newly opened module for processing with this loader's other vtable functions. */ static lt_module vm_open (lt_user_data loader_data, const char *filename, lt_dladvise LT__UNUSED advise) { lt_module module = 0; NSObjectFileImage ofi = 0; if (!filename) { return (lt_module) -1; } switch (NSCreateObjectFileImageFromFile (filename, &ofi)) { case NSObjectFileImageSuccess: module = NSLinkModule (ofi, filename, NSLINKMODULE_OPTION_RETURN_ON_ERROR | NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_BINDNOW); NSDestroyObjectFileImage (ofi); if (module) { lt__module_export (module); } break; case NSObjectFileImageInappropriateFile: if (lt__image_symbol_p && lt__image_symbol) { module = (lt_module) lt__addimage(filename, NSADDIMAGE_OPTION_RETURN_ON_ERROR); } break; case NSObjectFileImageFailure: case NSObjectFileImageArch: case NSObjectFileImageFormat: case NSObjectFileImageAccess: /*NOWORK*/ break; } if (!module) { DYLD__SETERROR (CANNOT_OPEN); } return module; } /* A function called through the vtable when a particular module should be unloaded. */ static int vm_close (lt_user_data loader_data, lt_module module) { int errors = 0; if (module != (lt_module) -1) { const mach_header *mh = (const mach_header *) module; int flags = 0; if (mh->magic == LT__MAGIC) { lt_dlseterror (dyld_cannot_close); ++errors; } else { /* Currently, if a module contains c++ static destructors and it is unloaded, we get a segfault in atexit(), due to compiler and dynamic loader differences of opinion, this works around that. */ if ((const struct section *) NULL != getsectbynamefromheader (lt__nsmodule_get_header (module), "__DATA", "__mod_term_func")) { flags |= NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED; } #if defined(__ppc__) flags |= NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES; #endif if (!NSUnLinkModule (module, flags)) { DYLD__SETERROR (CANNOT_CLOSE); ++errors; } } } return errors; } /* A function called through the vtable to get the address of a symbol loaded from a particular module. */ static void * vm_sym (lt_user_data loader_data, lt_module module, const char *name) { NSSymbol *nssym = 0; const mach_header *mh = (const mach_header *) module; char saveError[256] = "Symbol not found"; if (module == (lt_module) -1) { void *address, *unused; _dyld_lookup_and_bind (name, (unsigned long*) &address, &unused); return address; } if (mh->magic == LT__MAGIC) { if (lt__image_symbol_p && lt__image_symbol) { if (lt__image_symbol_p (mh, name)) { nssym = lt__image_symbol (mh, name, LT__SYMLOOKUP_OPTS); } } } else { nssym = NSLookupSymbolInModule (module, name); } if (!nssym) { strncpy (saveError, dylderror (LT__STRERROR (SYMBOL_NOT_FOUND)), 255); saveError[255] = 0; if (!mh) { mh = (mach_header *)lt__nsmodule_get_header (module); } nssym = lt__linkedlib_symbol (name, mh); } if (!nssym) { LT__SETERRORSTR (saveError); } return nssym ? NSAddressOfSymbol (nssym) : 0; } /* --- HELPER FUNCTIONS --- */ /* Return the dyld error string, or the passed in error string if none. */ static const char * dylderror (const char *errmsg) { NSLinkEditErrors ler; int lerno; const char *file; const char *errstr; NSLinkEditError (&ler, &lerno, &file, &errstr); if (! (errstr && *errstr)) { errstr = errmsg; } return errstr; } /* There should probably be an apple dyld api for this. */ static const mach_header * lt__nsmodule_get_header (NSModule module) { int i = _dyld_image_count(); const char *modname = NSNameOfModule (module); const mach_header *mh = 0; if (!modname) return NULL; while (i > 0) { --i; if (strneq (_dyld_get_image_name (i), modname)) { mh = _dyld_get_image_header (i); break; } } return mh; } /* NSAddImage is also used to get the loaded image, but it only works if the lib is installed, for uninstalled libs we need to check the install_names against each other. Note that this is still broken if DYLD_IMAGE_SUFFIX is set and a different lib was loaded as a result. */ static const char * lt__header_get_instnam (const mach_header *mh) { unsigned long offset = sizeof(mach_header); const char* result = 0; int j; for (j = 0; j < mh->ncmds; j++) { struct load_command *lc; lc = (struct load_command*) (((unsigned long) mh) + offset); if (LC_ID_DYLIB == lc->cmd) { result=(char*)(((dylib_command*) lc)->dylib.name.offset + (unsigned long) lc); } offset += lc->cmdsize; } return result; } static const mach_header * lt__match_loadedlib (const char *name) { const mach_header *mh = 0; int i = _dyld_image_count(); while (i > 0) { const char *id; --i; id = lt__header_get_instnam (_dyld_get_image_header (i)); if (id && strneq (id, name)) { mh = _dyld_get_image_header (i); break; } } return mh; } /* Safe to assume our mh is good. */ static NSSymbol lt__linkedlib_symbol (const char *symname, const mach_header *mh) { NSSymbol symbol = 0; if (lt__image_symbol && NSIsSymbolNameDefined (symname)) { unsigned long offset = sizeof(mach_header); struct load_command *lc; int j; for (j = 0; j < mh->ncmds; j++) { lc = (struct load_command*) (((unsigned long) mh) + offset); if ((LC_LOAD_DYLIB == lc->cmd) || (LC_LOAD_WEAK_DYLIB == lc->cmd)) { unsigned long base = ((dylib_command *) lc)->dylib.name.offset; char *name = (char *) (base + (unsigned long) lc); const mach_header *mh1 = lt__match_loadedlib (name); if (!mh1) { /* Maybe NSAddImage can find it */ mh1 = lt__addimage (name, NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED | NSADDIMAGE_OPTION_WITH_SEARCHING | NSADDIMAGE_OPTION_RETURN_ON_ERROR); } if (mh1) { symbol = lt__image_symbol (mh1, symname, LT__SYMLOOKUP_OPTS); if (symbol) break; } } offset += lc->cmdsize; } } return symbol; } proftpd-dfsg-1.3.5~rc3/lib/libltdl/loaders/load_add_on.c0000644000175000017500000001130411300565264022762 0ustar frankiefrankie/* loader-load_add_on.c -- dynamic linking for BeOS Copyright (C) 1998, 1999, 2000, 2004, 2006, 2007, 2008 Free Software Foundation, Inc. Written by Thomas Tanner, 1998 NOTE: The canonical source of this file is maintained with the GNU Libtool package. Report bugs to bug-libtool@gnu.org. GNU Libltdl is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exception to the GNU Lesser General Public License, if you distribute this file as part of a program or library that is built using GNU Libtool, you may include this file under the same distribution terms that you use for the rest of that program. GNU Libltdl is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with GNU Libltdl; see the file COPYING.LIB. If not, a copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, or obtained by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "lt__private.h" #include "lt_dlloader.h" /* Use the preprocessor to rename non-static symbols to avoid namespace collisions when the loader code is statically linked into libltdl. Use the "_LTX_" prefix so that the symbol addresses can be fetched from the preloaded symbol list by lt_dlsym(): */ #define get_vtable load_add_on_LTX_get_vtable LT_BEGIN_C_DECLS LT_SCOPE lt_dlvtable *get_vtable (lt_user_data loader_data); LT_END_C_DECLS /* Boilerplate code to set up the vtable for hooking this loader into libltdl's loader list: */ static int vl_exit (lt_user_data loader_data); static lt_module vm_open (lt_user_data loader_data, const char *filename, lt_dladvise advise); static int vm_close (lt_user_data loader_data, lt_module module); static void * vm_sym (lt_user_data loader_data, lt_module module, const char *symbolname); static lt_dlvtable *vtable = 0; /* Return the vtable for this loader, only the name and sym_prefix attributes (plus the virtual function implementations, obviously) change between loaders. */ lt_dlvtable * get_vtable (lt_user_data loader_data) { if (!vtable) { vtable = lt__zalloc (sizeof *vtable); } if (vtable && !vtable->name) { vtable->name = "lt_load_add_on"; vtable->module_open = vm_open; vtable->module_close = vm_close; vtable->find_sym = vm_sym; vtable->dlloader_exit = vl_exit; vtable->dlloader_data = loader_data; vtable->priority = LT_DLLOADER_APPEND; } if (vtable && (vtable->dlloader_data != loader_data)) { LT__SETERROR (INIT_LOADER); return 0; } return vtable; } /* --- IMPLEMENTATION --- */ #include /* A function called through the vtable when this loader is no longer needed by the application. */ static int vl_exit (lt_user_data LT__UNUSED loader_data) { vtable = NULL; return 0; } /* A function called through the vtable to open a module with this loader. Returns an opaque representation of the newly opened module for processing with this loader's other vtable functions. */ static lt_module vm_open (lt_user_data LT__UNUSED loader_data, const char *filename, lt_dladvise LT__UNUSED advise) { image_id image = 0; if (filename) { image = load_add_on (filename); } else { image_info info; int32 cookie = 0; if (get_next_image_info (0, &cookie, &info) == B_OK) image = load_add_on (info.name); } if (image <= 0) { LT__SETERROR (CANNOT_OPEN); image = 0; } return (lt_module) image; } /* A function called through the vtable when a particular module should be unloaded. */ static int vm_close (lt_user_data LT__UNUSED loader_data, lt_module module) { int errors = 0; if (unload_add_on ((image_id) module) != B_OK) { LT__SETERROR (CANNOT_CLOSE); ++errors; } return errors; } /* A function called through the vtable to get the address of a symbol loaded from a particular module. */ static void * vm_sym (lt_user_data LT__UNUSED loader_data, lt_module module, const char *name) { void *address = 0; image_id image = (image_id) module; if (get_image_symbol (image, name, B_SYMBOL_TYPE_ANY, address) != B_OK) { LT__SETERROR (SYMBOL_NOT_FOUND); address = 0; } return address; } proftpd-dfsg-1.3.5~rc3/lib/libltdl/loaders/dlopen.c0000644000175000017500000001434111300565264022024 0ustar frankiefrankie/* loader-dlopen.c -- dynamic linking with dlopen/dlsym Copyright (C) 1998, 1999, 2000, 2004, 2006, 2007, 2008 Free Software Foundation, Inc. Written by Thomas Tanner, 1998 NOTE: The canonical source of this file is maintained with the GNU Libtool package. Report bugs to bug-libtool@gnu.org. GNU Libltdl is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exception to the GNU Lesser General Public License, if you distribute this file as part of a program or library that is built using GNU Libtool, you may include this file under the same distribution terms that you use for the rest of that program. GNU Libltdl is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with GNU Libltdl; see the file COPYING.LIB. If not, a copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, or obtained by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "lt__private.h" #include "lt_dlloader.h" /* Use the preprocessor to rename non-static symbols to avoid namespace collisions when the loader code is statically linked into libltdl. Use the "_LTX_" prefix so that the symbol addresses can be fetched from the preloaded symbol list by lt_dlsym(): */ #define get_vtable dlopen_LTX_get_vtable LT_BEGIN_C_DECLS LT_SCOPE lt_dlvtable *get_vtable (lt_user_data loader_data); LT_END_C_DECLS /* Boilerplate code to set up the vtable for hooking this loader into libltdl's loader list: */ static int vl_exit (lt_user_data loader_data); static lt_module vm_open (lt_user_data loader_data, const char *filename, lt_dladvise advise); static int vm_close (lt_user_data loader_data, lt_module module); static void * vm_sym (lt_user_data loader_data, lt_module module, const char *symbolname); static lt_dlvtable *vtable = 0; /* Return the vtable for this loader, only the name and sym_prefix attributes (plus the virtual function implementations, obviously) change between loaders. */ lt_dlvtable * get_vtable (lt_user_data loader_data) { if (!vtable) { vtable = (lt_dlvtable *) lt__zalloc (sizeof *vtable); } if (vtable && !vtable->name) { vtable->name = "lt_dlopen"; #if defined(DLSYM_USCORE) vtable->sym_prefix = "_"; #endif vtable->module_open = vm_open; vtable->module_close = vm_close; vtable->find_sym = vm_sym; vtable->dlloader_exit = vl_exit; vtable->dlloader_data = loader_data; vtable->priority = LT_DLLOADER_PREPEND; } if (vtable && (vtable->dlloader_data != loader_data)) { LT__SETERROR (INIT_LOADER); return 0; } return vtable; } /* --- IMPLEMENTATION --- */ #if defined(HAVE_DLFCN_H) # include #endif #if defined(HAVE_SYS_DL_H) # include #endif /* We may have to define LT_LAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #if !defined(LT_LAZY_OR_NOW) # if defined(RTLD_LAZY) # define LT_LAZY_OR_NOW RTLD_LAZY # else # if defined(DL_LAZY) # define LT_LAZY_OR_NOW DL_LAZY # endif # endif /* !RTLD_LAZY */ #endif #if !defined(LT_LAZY_OR_NOW) # if defined(RTLD_NOW) # define LT_LAZY_OR_NOW RTLD_NOW # else # if defined(DL_NOW) # define LT_LAZY_OR_NOW DL_NOW # endif # endif /* !RTLD_NOW */ #endif #if !defined(LT_LAZY_OR_NOW) # define LT_LAZY_OR_NOW 0 #endif /* !LT_LAZY_OR_NOW */ /* We only support local and global symbols from modules for loaders that provide such a thing, otherwise the system default is used. */ #if !defined(RTLD_GLOBAL) # if defined(DL_GLOBAL) # define RTLD_GLOBAL DL_GLOBAL # endif #endif /* !RTLD_GLOBAL */ #if !defined(RTLD_LOCAL) # if defined(DL_LOCAL) # define RTLD_LOCAL DL_LOCAL # endif #endif /* !RTLD_LOCAL */ #if defined(HAVE_DLERROR) # define DLERROR(arg) dlerror () #else # define DLERROR(arg) LT__STRERROR (arg) #endif #define DL__SETERROR(errorcode) \ LT__SETERRORSTR (DLERROR (errorcode)) /* A function called through the vtable when this loader is no longer needed by the application. */ static int vl_exit (lt_user_data LT__UNUSED loader_data) { vtable = NULL; return 0; } /* A function called through the vtable to open a module with this loader. Returns an opaque representation of the newly opened module for processing with this loader's other vtable functions. */ static lt_module vm_open (lt_user_data LT__UNUSED loader_data, const char *filename, lt_dladvise advise) { int module_flags = LT_LAZY_OR_NOW; lt_module module; if (advise) { #ifdef RTLD_GLOBAL /* If there is some means of asking for global symbol resolution, do so. */ if (advise->is_symglobal) module_flags |= RTLD_GLOBAL; #else /* Otherwise, reset that bit so the caller can tell it wasn't acted on. */ advise->is_symglobal = 0; #endif /* And similarly for local only symbol resolution. */ #ifdef RTLD_LOCAL if (advise->is_symlocal) module_flags |= RTLD_LOCAL; #else advise->is_symlocal = 0; #endif } module = dlopen (filename, module_flags); if (!module) { DL__SETERROR (CANNOT_OPEN); } return module; } /* A function called through the vtable when a particular module should be unloaded. */ static int vm_close (lt_user_data LT__UNUSED loader_data, lt_module module) { int errors = 0; if (dlclose (module) != 0) { DL__SETERROR (CANNOT_CLOSE); ++errors; } return errors; } /* A function called through the vtable to get the address of a symbol loaded from a particular module. */ static void * vm_sym (lt_user_data LT__UNUSED loader_data, lt_module module, const char *name) { void *address = dlsym (module, name); if (!address) { DL__SETERROR (SYMBOL_NOT_FOUND); } return address; } proftpd-dfsg-1.3.5~rc3/lib/libltdl/loaders/loadlibrary.c0000644000175000017500000001507711300565264023056 0ustar frankiefrankie/* loader-loadlibrary.c -- dynamic linking for Win32 Copyright (C) 1998, 1999, 2000, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. Written by Thomas Tanner, 1998 NOTE: The canonical source of this file is maintained with the GNU Libtool package. Report bugs to bug-libtool@gnu.org. GNU Libltdl is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exception to the GNU Lesser General Public License, if you distribute this file as part of a program or library that is built using GNU Libtool, you may include this file under the same distribution terms that you use for the rest of that program. GNU Libltdl is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with GNU Libltdl; see the file COPYING.LIB. If not, a copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, or obtained by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "lt__private.h" #include "lt_dlloader.h" #if defined(__CYGWIN__) # include #endif /* Use the preprocessor to rename non-static symbols to avoid namespace collisions when the loader code is statically linked into libltdl. Use the "_LTX_" prefix so that the symbol addresses can be fetched from the preloaded symbol list by lt_dlsym(): */ #define get_vtable loadlibrary_LTX_get_vtable LT_BEGIN_C_DECLS LT_SCOPE lt_dlvtable *get_vtable (lt_user_data loader_data); LT_END_C_DECLS /* Boilerplate code to set up the vtable for hooking this loader into libltdl's loader list: */ static int vl_exit (lt_user_data loader_data); static lt_module vm_open (lt_user_data loader_data, const char *filename, lt_dladvise advise); static int vm_close (lt_user_data loader_data, lt_module module); static void * vm_sym (lt_user_data loader_data, lt_module module, const char *symbolname); static lt_dlinterface_id iface_id = 0; static lt_dlvtable *vtable = 0; /* Return the vtable for this loader, only the name and sym_prefix attributes (plus the virtual function implementations, obviously) change between loaders. */ lt_dlvtable * get_vtable (lt_user_data loader_data) { if (!vtable) { vtable = (lt_dlvtable *) lt__zalloc (sizeof *vtable); iface_id = lt_dlinterface_register ("ltdl loadlibrary", NULL); } if (vtable && !vtable->name) { vtable->name = "lt_loadlibrary"; vtable->module_open = vm_open; vtable->module_close = vm_close; vtable->find_sym = vm_sym; vtable->dlloader_exit = vl_exit; vtable->dlloader_data = loader_data; vtable->priority = LT_DLLOADER_APPEND; } if (vtable && (vtable->dlloader_data != loader_data)) { LT__SETERROR (INIT_LOADER); return 0; } return vtable; } /* --- IMPLEMENTATION --- */ #include /* A function called through the vtable when this loader is no longer needed by the application. */ static int vl_exit (lt_user_data LT__UNUSED loader_data) { vtable = NULL; return 0; } /* A function called through the vtable to open a module with this loader. Returns an opaque representation of the newly opened module for processing with this loader's other vtable functions. */ static lt_module vm_open (lt_user_data LT__UNUSED loader_data, const char *filename, lt_dladvise LT__UNUSED advise) { lt_module module = 0; char *ext; char wpath[MAX_PATH]; size_t len; if (!filename) { /* Get the name of main module */ *wpath = 0; GetModuleFileName (NULL, wpath, sizeof (wpath)); filename = wpath; } else { len = LT_STRLEN (filename); if (len >= MAX_PATH) { LT__SETERROR (CANNOT_OPEN); return 0; } #if HAVE_DECL_CYGWIN_CONV_PATH if (cygwin_conv_path (CCP_POSIX_TO_WIN_A, filename, wpath, MAX_PATH)) { LT__SETERROR (CANNOT_OPEN); return 0; } len = 0; #elif defined(__CYGWIN__) cygwin_conv_to_full_win32_path (filename, wpath); len = 0; #else strcpy(wpath, filename); #endif ext = strrchr (wpath, '.'); if (!ext) { /* Append a `.' to stop Windows from adding an implicit `.dll' extension. */ if (!len) len = LT_STRLEN (wpath); if (len + 1 >= MAX_PATH) { LT__SETERROR (CANNOT_OPEN); return 0; } wpath[len] = '.'; wpath[len+1] = '\0'; } } { /* Silence dialog from LoadLibrary on some failures. No way to get the error mode, but to set it, so set it twice to preserve any previous flags. */ UINT errormode = SetErrorMode(SEM_FAILCRITICALERRORS); SetErrorMode(errormode | SEM_FAILCRITICALERRORS); module = LoadLibrary (wpath); /* Restore the error mode. */ SetErrorMode(errormode); } /* libltdl expects this function to fail if it is unable to physically load the library. Sadly, LoadLibrary will search the loaded libraries for a match and return one of them if the path search load fails. We check whether LoadLibrary is returning a handle to an already loaded module, and simulate failure if we find one. */ { lt_dlhandle cur = 0; while ((cur = lt_dlhandle_iterate (iface_id, cur))) { if (!cur->module) { cur = 0; break; } if (cur->module == module) { break; } } if (cur || !module) { LT__SETERROR (CANNOT_OPEN); module = 0; } } return module; } /* A function called through the vtable when a particular module should be unloaded. */ static int vm_close (lt_user_data LT__UNUSED loader_data, lt_module module) { int errors = 0; if (FreeLibrary((HMODULE) module) == 0) { LT__SETERROR (CANNOT_CLOSE); ++errors; } return errors; } /* A function called through the vtable to get the address of a symbol loaded from a particular module. */ static void * vm_sym (lt_user_data LT__UNUSED loader_data, lt_module module, const char *name) { void *address = (void *) GetProcAddress ((HMODULE) module, name); if (!address) { LT__SETERROR (SYMBOL_NOT_FOUND); } return address; } proftpd-dfsg-1.3.5~rc3/lib/libltdl/argz.c0000644000175000017500000001341711300567412020055 0ustar frankiefrankie/* argz.c -- argz implementation for non-glibc systems Copyright (C) 2004, 2006, 2007, 2008 Free Software Foundation, Inc. Written by Gary V. Vaughan, 2004 NOTE: The canonical source of this file is maintained with the GNU Libtool package. Report bugs to bug-libtool@gnu.org. GNU Libltdl is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exception to the GNU Lesser General Public License, if you distribute this file as part of a program or library that is built using GNU Libtool, you may include this file under the same distribution terms that you use for the rest of that program. GNU Libltdl is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with GNU Libltdl; see the file COPYING.LIB. If not, a copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, or obtained by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #if defined(LTDL) && defined LT_CONFIG_H # include LT_CONFIG_H #else # include #endif #include #include #include #include #include #include #include #define EOS_CHAR '\0' error_t argz_append (char **pargz, size_t *pargz_len, const char *buf, size_t buf_len) { size_t argz_len; char *argz; assert (pargz); assert (pargz_len); assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len)); /* If nothing needs to be appended, no more work is required. */ if (buf_len == 0) return 0; /* Ensure there is enough room to append BUF_LEN. */ argz_len = *pargz_len + buf_len; argz = (char *) realloc (*pargz, argz_len); if (!argz) return ENOMEM; /* Copy characters from BUF after terminating '\0' in ARGZ. */ memcpy (argz + *pargz_len, buf, buf_len); /* Assign new values. */ *pargz = argz; *pargz_len = argz_len; return 0; } error_t argz_create_sep (const char *str, int delim, char **pargz, size_t *pargz_len) { size_t argz_len; char *argz = 0; assert (str); assert (pargz); assert (pargz_len); /* Make a copy of STR, but replacing each occurrence of DELIM with '\0'. */ argz_len = 1+ strlen (str); if (argz_len) { const char *p; char *q; argz = (char *) malloc (argz_len); if (!argz) return ENOMEM; for (p = str, q = argz; *p != EOS_CHAR; ++p) { if (*p == delim) { /* Ignore leading delimiters, and fold consecutive delimiters in STR into a single '\0' in ARGZ. */ if ((q > argz) && (q[-1] != EOS_CHAR)) *q++ = EOS_CHAR; else --argz_len; } else *q++ = *p; } /* Copy terminating EOS_CHAR. */ *q = *p; } /* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory. */ if (!argz_len) argz = (free (argz), (char *) 0); /* Assign new values. */ *pargz = argz; *pargz_len = argz_len; return 0; } error_t argz_insert (char **pargz, size_t *pargz_len, char *before, const char *entry) { assert (pargz); assert (pargz_len); assert (entry && *entry); /* No BEFORE address indicates ENTRY should be inserted after the current last element. */ if (!before) return argz_append (pargz, pargz_len, entry, 1+ strlen (entry)); /* This probably indicates a programmer error, but to preserve semantics, scan back to the start of an entry if BEFORE points into the middle of it. */ while ((before > *pargz) && (before[-1] != EOS_CHAR)) --before; { size_t entry_len = 1+ strlen (entry); size_t argz_len = *pargz_len + entry_len; size_t offset = before - *pargz; char *argz = (char *) realloc (*pargz, argz_len); if (!argz) return ENOMEM; /* Make BEFORE point to the equivalent offset in ARGZ that it used to have in *PARGZ incase realloc() moved the block. */ before = argz + offset; /* Move the ARGZ entries starting at BEFORE up into the new space at the end -- making room to copy ENTRY into the resulting gap. */ memmove (before + entry_len, before, *pargz_len - offset); memcpy (before, entry, entry_len); /* Assign new values. */ *pargz = argz; *pargz_len = argz_len; } return 0; } char * argz_next (char *argz, size_t argz_len, const char *entry) { assert ((argz && argz_len) || (!argz && !argz_len)); if (entry) { /* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address within the ARGZ vector. */ assert ((!argz && !argz_len) || ((argz <= entry) && (entry < (argz + argz_len)))); /* Move to the char immediately after the terminating '\0' of ENTRY. */ entry = 1+ strchr (entry, EOS_CHAR); /* Return either the new ENTRY, or else NULL if ARGZ is exhausted. */ return (entry >= argz + argz_len) ? 0 : (char *) entry; } else { /* This should probably be flagged as a programmer error, since starting an argz_next loop with the iterator set to ARGZ is safer. To preserve semantics, handle the NULL case by returning the start of ARGZ (if any). */ if (argz_len > 0) return argz; else return 0; } } void argz_stringify (char *argz, size_t argz_len, int sep) { assert ((argz && argz_len) || (!argz && !argz_len)); if (sep) { --argz_len; /* don't stringify the terminating EOS */ while (--argz_len > 0) { if (argz[argz_len] == EOS_CHAR) argz[argz_len] = sep; } } } proftpd-dfsg-1.3.5~rc3/lib/libltdl/config/0000755000175000017500000000000012156653653020222 5ustar frankiefrankieproftpd-dfsg-1.3.5~rc3/lib/libltdl/config/compile0000755000175000017500000000717311300565264021576 0ustar frankiefrankie#! /bin/sh # Wrapper for compilers which do not understand `-c -o'. scriptversion=2005-05-14.22 # Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . case $1 in '') echo "$0: No command. Try \`$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand `-c -o'. Remove `-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file `INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; esac ofile= cfile= eat= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as `compile cc -o foo foo.c'. # So we strip `-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no `-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # `.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'` # Create the lock directory. # Note: use `[/.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: proftpd-dfsg-1.3.5~rc3/lib/libltdl/config/depcomp0000755000175000017500000004271311300565264021574 0ustar frankiefrankie#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2007-03-29.01 # Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007 Free Software # Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try \`$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by `PROGRAMS ARGS'. object Object file output by `PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputing dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the `deleted header file' problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. tr ' ' ' ' < "$tmpdepfile" | ## Some versions of gcc put a space before the `:'. On the theory ## that the space means something, we add a space to the output as ## well. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like `#:fec' to the end of the # dependency line. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr ' ' ' ' >> $depfile echo >> $depfile # The second pass generates a dummy entry for each header file. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> $depfile else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts `$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a tab and a space in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; icc) # Intel's C compiler understands `-MD -MF file'. However on # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c # ICC 7.0 will fill foo.d with something like # foo.o: sub/foo.c # foo.o: sub/foo.h # which is wrong. We want: # sub/foo.o: sub/foo.c # sub/foo.o: sub/foo.h # sub/foo.c: # sub/foo.h: # ICC 7.1 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using \ : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" # Add `dependent.h:' lines. sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in `foo.d' instead, so we check for that too. # Subdirectories are respected. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then # With Tru64 cc, shared objects can also be used to make a # static library. This mechanism is used in libtool 1.4 series to # handle both shared and static libraries in a single compilation. # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. # # With libtool 1.5 this exception was removed, and libtool now # generates 2 separate objects for the 2 libraries. These two # compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 tmpdepfile2=$dir$base.o.d # libtool 1.5 tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.o.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d tmpdepfile4=$dir$base.d "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a tab and a space in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for `:' # in the target name. This is to cope with DOS-style filenames: # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. "$@" $dashmflag | sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' ' ' < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # X makedepend shift cleared=no for arg in "$@"; do case $cleared in no) set ""; shift cleared=yes ;; esac case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix="`echo $object | sed 's/^.*\././'`" touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" sed '1,2d' "$tmpdepfile" | tr ' ' ' ' | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o, # because we must use -o when running libtool. "$@" || exit $? IFS=" " for arg do case "$arg" in "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" echo " " >> "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: proftpd-dfsg-1.3.5~rc3/lib/libltdl/config/ltmain.sh0000755000175000017500000073337611300565264022056 0ustar frankiefrankie# Generated from ltmain.m4sh. # ltmain.sh (GNU libtool) 2.2.6 # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 2008 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, # or obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Usage: $progname [OPTION]... [MODE-ARG]... # # Provide generalized library-building support services. # # --config show all configuration variables # --debug enable verbose shell tracing # -n, --dry-run display commands without modifying any files # --features display basic configuration information and exit # --mode=MODE use operation mode MODE # --preserve-dup-deps don't remove duplicate dependency libraries # --quiet, --silent don't print informational messages # --tag=TAG use configuration variables from tag TAG # -v, --verbose print informational messages (default) # --version print version information # -h, --help print short or long help message # # MODE must be one of the following: # # clean remove files from the build directory # compile compile a source file into a libtool object # execute automatically set library path, then run a program # finish complete the installation of libtool libraries # install install libraries or executables # link create a library or an executable # uninstall remove libraries from an installed directory # # MODE-ARGS vary depending on the MODE. # Try `$progname --help --mode=MODE' for a more detailed description of MODE. # # When reporting a bug, please describe a test case to reproduce it and # include the following information: # # host-triplet: $host # shell: $SHELL # compiler: $LTCC # compiler flags: $LTCFLAGS # linker: $LD (gnu? $with_gnu_ld) # $progname: (GNU libtool) 2.2.6 Debian-2.2.6a-1ubuntu1 # automake: $automake_version # autoconf: $autoconf_version # # Report bugs to . PROGRAM=ltmain.sh PACKAGE=libtool VERSION="2.2.6 Debian-2.2.6a-1ubuntu1" TIMESTAMP="" package_revision=1.3012 # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # NLS nuisances: We save the old values to restore during execute mode. # Only set LANG and LC_ALL to C if already set. # These must not be set unconditionally because not all systems understand # e.g. LANG=C (notably SCO). lt_user_locale= lt_safe_locale= for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${$lt_var+set}\" = set; then save_$lt_var=\$$lt_var $lt_var=C export $lt_var lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" fi" done $lt_unset CDPATH : ${CP="cp -f"} : ${ECHO="echo"} : ${EGREP="/bin/grep -E"} : ${FGREP="/bin/grep -F"} : ${GREP="/bin/grep"} : ${LN_S="ln -s"} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SED="/bin/sed"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} : ${Xsed="$SED -e 1s/^X//"} # Global variables: EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. exit_status=$EXIT_SUCCESS # Make sure IFS has a sensible default lt_nl=' ' IFS=" $lt_nl" dirname="s,/[^/]*$,," basename="s,^.*/,," # func_dirname_and_basename file append nondir_replacement # perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` } # Generated shell functions inserted here. # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath="$0" # The name of this program: # In the unlikely event $progname began with a '-', it would play havoc with # func_echo (imagine progname=-n), so we prepend ./ in that case: func_dirname_and_basename "$progpath" progname=$func_basename_result case $progname in -*) progname=./$progname ;; esac # Make sure we have an absolute path for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=$func_dirname_result progdir=`cd "$progdir" && pwd` progpath="$progdir/$progname" ;; *) save_IFS="$IFS" IFS=: for progdir in $PATH; do IFS="$save_IFS" test -x "$progdir/$progname" && break done IFS="$save_IFS" test -n "$progdir" || progdir=`pwd` progpath="$progdir/$progname" ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed="${SED}"' -e 1s/^X//' sed_quote_subst='s/\([`"$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Re-`\' parameter expansions in output of double_quote_subst that were # `\'-ed in input to the same. If an odd number of `\' preceded a '$' # in input to double_quote_subst, that '$' was protected from expansion. # Since each input `\' is now two `\'s, look for any number of runs of # four `\'s followed by two `\'s and then a '$'. `\' that '$'. bs='\\' bs2='\\\\' bs4='\\\\\\\\' dollar='\$' sed_double_backslash="\ s/$bs4/&\\ /g s/^$bs2$dollar/$bs&/ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g s/\n//g" # Standard options: opt_dry_run=false opt_help=false opt_quiet=false opt_verbose=false opt_warning=: # func_echo arg... # Echo program name prefixed message, along with the current mode # name if it has been set yet. func_echo () { $ECHO "$progname${mode+: }$mode: $*" } # func_verbose arg... # Echo program name prefixed message in verbose mode only. func_verbose () { $opt_verbose && func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_error arg... # Echo program name prefixed message to standard error. func_error () { $ECHO "$progname${mode+: }$mode: "${1+"$@"} 1>&2 } # func_warning arg... # Echo program name prefixed warning message to standard error. func_warning () { $opt_warning && $ECHO "$progname${mode+: }$mode: warning: "${1+"$@"} 1>&2 # bash bug again: : } # func_fatal_error arg... # Echo program name prefixed message to standard error, and exit. func_fatal_error () { func_error ${1+"$@"} exit $EXIT_FAILURE } # func_fatal_help arg... # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { func_error ${1+"$@"} func_fatal_error "$help" } help="Try \`$progname --help' for more information." ## default # func_grep expression filename # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $GREP "$1" "$2" >/dev/null 2>&1 } # func_mkdir_p directory-path # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { my_directory_path="$1" my_dir_list= if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then # Protect directory names starting with `-' case $my_directory_path in -*) my_directory_path="./$my_directory_path" ;; esac # While some portion of DIR does not yet exist... while test ! -d "$my_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. my_dir_list="$my_directory_path:$my_dir_list" # If the last portion added has no slash in it, the list is done case $my_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop my_directory_path=`$ECHO "X$my_directory_path" | $Xsed -e "$dirname"` done my_dir_list=`$ECHO "X$my_dir_list" | $Xsed -e 's,:*$,,'` save_mkdir_p_IFS="$IFS"; IFS=':' for my_dir in $my_dir_list; do IFS="$save_mkdir_p_IFS" # mkdir can fail with a `File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$my_dir" 2>/dev/null || : done IFS="$save_mkdir_p_IFS" # Bail out if we (or some other process) failed to create a directory. test -d "$my_directory_path" || \ func_fatal_error "Failed to create \`$1'" fi } # func_mktempdir [string] # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, STRING is the basename for that directory. func_mktempdir () { my_template="${TMPDIR-/tmp}/${1-$progname}" if test "$opt_dry_run" = ":"; then # Return a directory name, but don't create it in dry-run mode my_tmpdir="${my_template}-$$" else # If mktemp works, use that first and foremost my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` if test ! -d "$my_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race my_tmpdir="${my_template}-${RANDOM-0}$$" save_mktempdir_umask=`umask` umask 0077 $MKDIR "$my_tmpdir" umask $save_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$my_tmpdir" || \ func_fatal_error "cannot create temporary directory \`$my_tmpdir'" fi $ECHO "X$my_tmpdir" | $Xsed } # func_quote_for_eval arg # Aesthetically quote ARG to be evaled later. # This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT # is double-quoted, suitable for a subsequent eval, whereas # FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters # which are still active within double quotes backslashified. func_quote_for_eval () { case $1 in *[\\\`\"\$]*) func_quote_for_eval_unquoted_result=`$ECHO "X$1" | $Xsed -e "$sed_quote_subst"` ;; *) func_quote_for_eval_unquoted_result="$1" ;; esac case $func_quote_for_eval_unquoted_result in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and and variable # expansion for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" ;; *) func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" esac } # func_quote_for_expand arg # Aesthetically quote ARG to be evaled later; same as above, # but do not quote variable references. func_quote_for_expand () { case $1 in *[\\\`\"]*) my_arg=`$ECHO "X$1" | $Xsed \ -e "$double_quote_subst" -e "$sed_double_backslash"` ;; *) my_arg="$1" ;; esac case $my_arg in # Double-quote args containing shell metacharacters to delay # word splitting and command substitution for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") my_arg="\"$my_arg\"" ;; esac func_quote_for_expand_result="$my_arg" } # func_show_eval cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$my_cmd" my_status=$? if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_show_eval_locale cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$lt_user_locale $my_cmd" my_status=$? eval "$lt_safe_locale" if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_version # Echo version message to standard output and exit. func_version () { $SED -n '/^# '$PROGRAM' (GNU /,/# warranty; / { s/^# // s/^# *$// s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ p }' < "$progpath" exit $? } # func_usage # Echo short help message to standard output and exit. func_usage () { $SED -n '/^# Usage:/,/# -h/ { s/^# // s/^# *$// s/\$progname/'$progname'/ p }' < "$progpath" $ECHO $ECHO "run \`$progname --help | more' for full usage" exit $? } # func_help # Echo long help message to standard output and exit. func_help () { $SED -n '/^# Usage:/,/# Report bugs to/ { s/^# // s/^# *$// s*\$progname*'$progname'* s*\$host*'"$host"'* s*\$SHELL*'"$SHELL"'* s*\$LTCC*'"$LTCC"'* s*\$LTCFLAGS*'"$LTCFLAGS"'* s*\$LD*'"$LD"'* s/\$with_gnu_ld/'"$with_gnu_ld"'/ s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/ s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/ p }' < "$progpath" exit $? } # func_missing_arg argname # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { func_error "missing argument for $1" exit_cmd=exit } exit_cmd=: # Check that we have a working $ECHO. if test "X$1" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test "X$1" = X--fallback-echo; then # Avoid inline document here, it may be left over : elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t'; then # Yippee, $ECHO works! : else # Restart under the correct shell, and then maybe $ECHO will work. exec $SHELL "$progpath" --no-reexec ${1+"$@"} fi if test "X$1" = X--fallback-echo; then # used as fallback echo shift cat </dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # Parse options once, thoroughly. This comes as soon as possible in # the script to make things like `libtool --version' happen quickly. { # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; esac # Parse non-mode specific arguments: while test "$#" -gt 0; do opt="$1" shift case $opt in --config) func_config ;; --debug) preserve_args="$preserve_args $opt" func_echo "enabling shell trace mode" opt_debug='set -x' $opt_debug ;; -dlopen) test "$#" -eq 0 && func_missing_arg "$opt" && break execute_dlfiles="$execute_dlfiles $1" shift ;; --dry-run | -n) opt_dry_run=: ;; --features) func_features ;; --finish) mode="finish" ;; --mode) test "$#" -eq 0 && func_missing_arg "$opt" && break case $1 in # Valid mode arguments: clean) ;; compile) ;; execute) ;; finish) ;; install) ;; link) ;; relink) ;; uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $opt" exit_cmd=exit break ;; esac mode="$1" shift ;; --preserve-dup-deps) opt_duplicate_deps=: ;; --quiet|--silent) preserve_args="$preserve_args $opt" opt_silent=: ;; --verbose| -v) preserve_args="$preserve_args $opt" opt_silent=false ;; --tag) test "$#" -eq 0 && func_missing_arg "$opt" && break preserve_args="$preserve_args $opt $1" func_enable_tag "$1" # tagname is set here shift ;; # Separate optargs to long options: -dlopen=*|--mode=*|--tag=*) func_opt_split "$opt" set dummy "$func_opt_split_opt" "$func_opt_split_arg" ${1+"$@"} shift ;; -\?|-h) func_usage ;; --help) opt_help=: ;; --version) func_version ;; -*) func_fatal_help "unrecognized option \`$opt'" ;; *) nonopt="$opt" break ;; esac done case $host in *cygwin* | *mingw* | *pw32* | *cegcc*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_duplicate_deps ;; esac # Having warned about all mis-specified options, bail out if # anything was wrong. $exit_cmd $EXIT_FAILURE } # func_check_version_match # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } ## ----------- ## ## Main. ## ## ----------- ## $opt_help || { # Sanity checks first: func_check_version_match if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then func_fatal_configuration "not configured to build any kind of library" fi test -z "$mode" && func_fatal_error "error: you must specify a MODE." # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$execute_dlfiles" && test "$mode" != execute; then func_error "unrecognized option \`-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help="$help" help="Try \`$progname --help --mode=$mode' for more information." } # func_lalib_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null \ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_unsafe_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if `file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case "$lalib_p_line" in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test "$lalib_p" = yes } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { func_lalib_p "$1" } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_ltwrapper_scriptname_result="" if func_ltwrapper_executable_p "$1"; then func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" fi } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $opt_debug save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$save_ifs eval cmd=\"$cmd\" func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # `FILE.' does not work on cygwin managed mounts. func_source () { $opt_debug case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $opt_debug if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_quote_for_eval "$arg" CC_quoted="$CC_quoted $func_quote_for_eval_result" done case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_quote_for_eval "$arg" CC_quoted="$CC_quoted $func_quote_for_eval_result" done case "$@ " in " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with \`--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=${1} if test "$build_libtool_libs" = yes; then write_lobj=\'${2}\' else write_lobj=none fi if test "$build_old_libs" = yes; then write_oldobj=\'${3}\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T <?"'"'"' &()|`$[]' \ && func_warning "libobj name \`$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname="$func_basename_result" xdir="$func_dirname_result" lobj=${xdir}$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test "$build_old_libs" = yes; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test "$compiler_c_o" = no; then output_obj=`$ECHO "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} lockfile="$output_obj.lock" else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test "$need_locks" = yes; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test "$need_locks" = warn; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi removelist="$removelist $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist removelist="$removelist $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 if test -n "$fix_srcfile_path"; then eval srcfile=\"$fix_srcfile_path\" fi func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. if test "$build_libtool_libs" = yes; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test "$pic_mode" != no; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir command="$command -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test "$suppress_opt" = yes; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test "$build_old_libs" = yes; then if test "$pic_mode" != yes; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test "$compiler_c_o" = yes; then command="$command -o $obj" fi # Suppress compiler output if we already did a PIC compilation. command="$command$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test "$need_locks" != no; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test "$mode" = compile && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to building PIC objects only -prefer-non-pic try to building non-PIC objects only -shared do not build a \`.o' file suitable for static linking -static only build a \`.o' file suitable for static linking COMPILE-COMMAND is a command to be used in creating a \`standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix \`.c' with the library object suffix, \`.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to \`-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the \`--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the \`install' or \`cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE Use a list of object files found in FILE to specify objects -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface All other options (arguments beginning with \`-') are ignored. Every other argument is treated as a filename. Files ending in \`.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only library objects (\`.lo' files) may be specified, and \`-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created using \`ar' and \`ranlib', or on Windows using \`lib'. If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode \`$mode'" ;; esac $ECHO $ECHO "Try \`$progname --help' for more information about other modes." exit $? } # Now that we've collected a possible --mode arg, show help if necessary $opt_help && func_mode_help # func_mode_execute arg... func_mode_execute () { $opt_debug # The first argument is the command name. cmd="$nonopt" test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $execute_dlfiles; do test -f "$file" \ || func_fatal_help "\`$file' is not a file" dir= case $file in *.la) # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "\`$file' was not linked with \`-export-dynamic'" continue fi func_dirname "$file" "" "." dir="$func_dirname_result" if test -f "$dir/$objdir/$dlname"; then dir="$dir/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir="$func_dirname_result" ;; *) func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir="$absdir" # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic="$magic" # Check if any of the arguments is a wrapper script. args= for file do case $file in -*) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file="$progdir/$program" elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file="$progdir/$program" fi ;; esac # Quote arguments (to preserve shell metacharacters). func_quote_for_eval "$file" args="$args $func_quote_for_eval_result" done if test "X$opt_dry_run" = Xfalse; then if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd="\$cmd$args" else # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" $ECHO "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS fi } test "$mode" = execute && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $opt_debug libdirs="$nonopt" admincmds= if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for dir do libdirs="$libdirs $dir" done for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || admincmds="$admincmds $cmds" fi done fi # Exit here if they wanted silent mode. $opt_silent && exit $EXIT_SUCCESS $ECHO "X----------------------------------------------------------------------" | $Xsed $ECHO "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done $ECHO $ECHO "If you ever happen to want to link against installed libraries" $ECHO "in a given directory, LIBDIR, you must either use libtool, and" $ECHO "specify the full pathname of the library, or use the \`-LLIBDIR'" $ECHO "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then $ECHO " - add LIBDIR to the \`$shlibpath_var' environment variable" $ECHO " during execution" fi if test -n "$runpath_var"; then $ECHO " - add LIBDIR to the \`$runpath_var' environment variable" $ECHO " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the \`$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then $ECHO " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" fi $ECHO $ECHO "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) $ECHO "more information, such as the ld(1), crle(1) and ld.so(8) manual" $ECHO "pages." ;; *) $ECHO "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac $ECHO "X----------------------------------------------------------------------" | $Xsed exit $EXIT_SUCCESS } test "$mode" = finish && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $opt_debug # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || # Allow the use of GNU shtool's install command. $ECHO "X$nonopt" | $GREP shtool >/dev/null; then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_for_eval "$arg" install_prog="$install_prog$func_quote_for_eval_result" # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=no stripme= for arg do if test -n "$dest"; then files="$files $dest" dest=$arg continue fi case $arg in -d) isdir=yes ;; -f) case " $install_prog " in *[\\\ /]cp\ *) ;; *) prev=$arg ;; esac ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_for_eval "$arg" install_prog="$install_prog $func_quote_for_eval_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the \`$prev' option requires an argument" if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=yes if test "$isdir" = yes; then destdir="$dest" destname= else func_dirname_and_basename "$dest" "" "." destdir="$func_dirname_result" destname="$func_basename_result" # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "\`$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "\`$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. staticlibs="$staticlibs $file" ;; *.la) # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) current_libdirs="$current_libdirs $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) future_libdirs="$future_libdirs $libdir" ;; esac fi func_dirname "$file" "/" "" dir="$func_dirname_result" dir="$dir$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "X$destdir" | $Xsed -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%%"` fi func_warning "relinking \`$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname="$1" shift srcname="$realname" test -n "$relink_command" && srcname="$realname"T # Install the shared library and build the symlinks. func_show_eval "$install_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme="$stripme" case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme="" ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try `ln -sf' first, because the `ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib="$destdir/$realname" func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name="$func_basename_result" instname="$dir/$name"i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest="$destfile" destfile= ;; *) func_fatal_help "cannot copy a libtool object to \`$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test "$build_old_libs" = yes; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext="" case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=".exe" fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script \`$wrapper'" finalize=yes for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile="$libdir/"`$ECHO "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test if test -n "$libdir" && test ! -f "$libfile"; then func_warning "\`$lib' has not been installed in \`$libdir'" finalize=no fi done relink_command= func_source "$wrapper" outputname= if test "$fast_install" = no && test -n "$relink_command"; then $opt_dry_run || { if test "$finalize" = yes; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file="$func_basename_result" outputname="$tmpdir/$file" # Replace the output file specification. relink_command=`$ECHO "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` $opt_silent || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else func_error "error: relink \`$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file="$outputname" else func_warning "cannot relink \`$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name="$func_basename_result" # Set up the ranlib parameters. oldlib="$destdir/$name" func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run \`$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test "$mode" = install && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $opt_debug my_outputname="$1" my_originator="$2" my_pic_p="${3-no}" my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms="${my_outputname}S.c" else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist="$output_objdir/${my_outputname}.nm" func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif /* External symbol declarations for the compiler. */\ " if test "$dlself" = yes; then func_verbose "generating symbol list for \`$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` for progfile in $progfiles; do func_verbose "extracting global C symbols from \`$progfile'" $opt_dry_run || eval "$NM $progfile | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols="$output_objdir/$outputname.exp" $opt_dry_run || { $RM $export_symbols eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from \`$dlprefile'" func_basename "$dlprefile" name="$func_basename_result" $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'" } done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else $ECHO '/* NONE */' >> "$output_objdir/$my_dlsyms" fi $ECHO >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; " case $host in *cygwin* | *mingw* | *cegcc* ) $ECHO >> "$output_objdir/$my_dlsyms" "\ /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */" lt_dlsym_const= ;; *osf5*) echo >> "$output_objdir/$my_dlsyms" "\ /* This system does not cope well with relocations in const data */" lt_dlsym_const= ;; *) lt_dlsym_const=const ;; esac $ECHO >> "$output_objdir/$my_dlsyms" "\ extern $lt_dlsym_const lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[]; $lt_dlsym_const lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = {\ { \"$my_originator\", (void *) 0 }," case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac $ECHO >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) if test "X$my_pic_p" != Xno; then pic_flag_for_symtable=" $pic_flag" fi ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) symtab_cflags="$symtab_cflags $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' # Transform the symbol file into the correct name. symfileobj="$output_objdir/${my_outputname}S.$objext" case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for \`$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` fi } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. func_win32_libid () { $opt_debug win32_libid_type="unknown" win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then win32_nmres=`eval $NM -f posix -A $1 | $SED -n -e ' 1,100{ / I /{ s,.*,import, p q } }'` case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_extract_an_archive dir oldlib func_extract_an_archive () { $opt_debug f_ex_an_ar_dir="$1"; shift f_ex_an_ar_oldlib="$1" func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" 'exit $?' if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $opt_debug my_gentop="$1"; shift my_oldlibs=${1+"$@"} my_oldobjs="" my_xlib="" my_xabs="" my_xdir="" for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib="$func_basename_result" my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir="$my_gentop/$my_xlib_u" func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` darwin_base_archive=`basename "$darwin_archive"` darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches ; do func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" func_extract_an_archive "`pwd`" "${darwin_base_archive}" cd "$darwin_curdir" $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` done func_extract_archives_result="$my_oldobjs" } # func_emit_wrapper_part1 [arg=no] # # Emit the first part of a libtool wrapper script on stdout. # For more information, see the description associated with # func_emit_wrapper(), below. func_emit_wrapper_part1 () { func_emit_wrapper_part1_arg1=no if test -n "$1" ; then func_emit_wrapper_part1_arg1=$1 fi $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed='${SED} -e 1s/^X//' sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then ECHO=\"$qecho\" file=\"\$0\" # Make sure echo works. if test \"X\$1\" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test \"X\`{ \$ECHO '\t'; } 2>/dev/null\`\" = 'X\t'; then # Yippee, \$ECHO works! : else # Restart under the correct shell, and then maybe \$ECHO will work. exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} fi fi\ " $ECHO "\ # Find the directory that this script lives in. thisdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"X\$file\" | \$Xsed -e 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` done " } # end: func_emit_wrapper_part1 # func_emit_wrapper_part2 [arg=no] # # Emit the second part of a libtool wrapper script on stdout. # For more information, see the description associated with # func_emit_wrapper(), below. func_emit_wrapper_part2 () { func_emit_wrapper_part2_arg1=no if test -n "$1" ; then func_emit_wrapper_part2_arg1=$1 fi $ECHO "\ # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_part2_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"X\$thisdir\" | \$Xsed -e 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test "$fast_install" = yes; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else $ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # Export our shlibpath_var if we have one. if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` export $shlibpath_var " fi # fixup the dll searchpath if we need to. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 fi else # The program doesn't exist. \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 $ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # end: func_emit_wrapper_part2 # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory in which it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=no if test -n "$1" ; then func_emit_wrapper_arg1=$1 fi # split this up so that func_emit_cwrapperexe_src # can call each part independently. func_emit_wrapper_part1 "${func_emit_wrapper_arg1}" func_emit_wrapper_part2 "${func_emit_wrapper_arg1}" } # func_to_host_path arg # # Convert paths to host format when used with build tools. # Intended for use with "native" mingw (where libtool itself # is running under the msys shell), or in the following cross- # build environments: # $build $host # mingw (msys) mingw [e.g. native] # cygwin mingw # *nix + wine mingw # where wine is equipped with the `winepath' executable. # In the native mingw case, the (msys) shell automatically # converts paths for any non-msys applications it launches, # but that facility isn't available from inside the cwrapper. # Similar accommodations are necessary for $host mingw and # $build cygwin. Calling this function does no harm for other # $host/$build combinations not listed above. # # ARG is the path (on $build) that should be converted to # the proper representation for $host. The result is stored # in $func_to_host_path_result. func_to_host_path () { func_to_host_path_result="$1" if test -n "$1" ; then case $host in *mingw* ) lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' case $build in *mingw* ) # actually, msys # awkward: cmd appends spaces to result lt_sed_strip_trailing_spaces="s/[ ]*\$//" func_to_host_path_tmp1=`( cmd //c echo "$1" |\ $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""` func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ $SED -e "$lt_sed_naive_backslashify"` ;; *cygwin* ) func_to_host_path_tmp1=`cygpath -w "$1"` func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ $SED -e "$lt_sed_naive_backslashify"` ;; * ) # Unfortunately, winepath does not exit with a non-zero # error code, so we are forced to check the contents of # stdout. On the other hand, if the command is not # found, the shell will set an exit code of 127 and print # *an error message* to stdout. So we must check for both # error code of zero AND non-empty stdout, which explains # the odd construction: func_to_host_path_tmp1=`winepath -w "$1" 2>/dev/null` if test "$?" -eq 0 && test -n "${func_to_host_path_tmp1}"; then func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ $SED -e "$lt_sed_naive_backslashify"` else # Allow warning below. func_to_host_path_result="" fi ;; esac if test -z "$func_to_host_path_result" ; then func_error "Could not determine host path corresponding to" func_error " '$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_path_result="$1" fi ;; esac fi } # end: func_to_host_path # func_to_host_pathlist arg # # Convert pathlists to host format when used with build tools. # See func_to_host_path(), above. This function supports the # following $build/$host combinations (but does no harm for # combinations not listed here): # $build $host # mingw (msys) mingw [e.g. native] # cygwin mingw # *nix + wine mingw # # Path separators are also converted from $build format to # $host format. If ARG begins or ends with a path separator # character, it is preserved (but converted to $host format) # on output. # # ARG is a pathlist (on $build) that should be converted to # the proper representation on $host. The result is stored # in $func_to_host_pathlist_result. func_to_host_pathlist () { func_to_host_pathlist_result="$1" if test -n "$1" ; then case $host in *mingw* ) lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_to_host_pathlist_tmp2="$1" # Once set for this call, this variable should not be # reassigned. It is used in tha fallback case. func_to_host_pathlist_tmp1=`echo "$func_to_host_pathlist_tmp2" |\ $SED -e 's|^:*||' -e 's|:*$||'` case $build in *mingw* ) # Actually, msys. # Awkward: cmd appends spaces to result. lt_sed_strip_trailing_spaces="s/[ ]*\$//" func_to_host_pathlist_tmp2=`( cmd //c echo "$func_to_host_pathlist_tmp1" |\ $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""` func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\ $SED -e "$lt_sed_naive_backslashify"` ;; *cygwin* ) func_to_host_pathlist_tmp2=`cygpath -w -p "$func_to_host_pathlist_tmp1"` func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\ $SED -e "$lt_sed_naive_backslashify"` ;; * ) # unfortunately, winepath doesn't convert pathlists func_to_host_pathlist_result="" func_to_host_pathlist_oldIFS=$IFS IFS=: for func_to_host_pathlist_f in $func_to_host_pathlist_tmp1 ; do IFS=$func_to_host_pathlist_oldIFS if test -n "$func_to_host_pathlist_f" ; then func_to_host_path "$func_to_host_pathlist_f" if test -n "$func_to_host_path_result" ; then if test -z "$func_to_host_pathlist_result" ; then func_to_host_pathlist_result="$func_to_host_path_result" else func_to_host_pathlist_result="$func_to_host_pathlist_result;$func_to_host_path_result" fi fi fi IFS=: done IFS=$func_to_host_pathlist_oldIFS ;; esac if test -z "$func_to_host_pathlist_result" ; then func_error "Could not determine the host path(s) corresponding to" func_error " '$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This may break if $1 contains DOS-style drive # specifications. The fix is not to complicate the expression # below, but for the user to provide a working wine installation # with winepath so that path translation in the cross-to-mingw # case works properly. lt_replace_pathsep_nix_to_dos="s|:|;|g" func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp1" |\ $SED -e "$lt_replace_pathsep_nix_to_dos"` fi # Now, add the leading and trailing path separators back case "$1" in :* ) func_to_host_pathlist_result=";$func_to_host_pathlist_result" ;; esac case "$1" in *: ) func_to_host_pathlist_result="$func_to_host_pathlist_result;" ;; esac ;; esac fi } # end: func_to_host_pathlist # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #ifdef _MSC_VER # include # include # include # define setmode _setmode #else # include # include # ifdef __CYGWIN__ # include # define HAVE_SETENV # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif # endif #endif #include #include #include #include #include #include #include #include #if defined(PATH_MAX) # define LT_PATHMAX PATH_MAX #elif defined(MAXPATHLEN) # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif #ifdef _MSC_VER # define S_IXUSR _S_IEXEC # define stat _stat # ifndef _INTPTR_T_DEFINED # define intptr_t int # endif #endif #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ defined (__OS2__) # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifdef __CYGWIN__ # define FOPEN_WB "wb" #endif #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free ((void *) stale); stale = 0; } \ } while (0) #undef LTWRAPPER_DEBUGPRINTF #if defined DEBUGWRAPPER # define LTWRAPPER_DEBUGPRINTF(args) ltwrapper_debugprintf args static void ltwrapper_debugprintf (const char *fmt, ...) { va_list args; va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } #else # define LTWRAPPER_DEBUGPRINTF(args) #endif const char *program_name = NULL; void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_fatal (const char *message, ...); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_opt_process_env_set (const char *arg); void lt_opt_process_env_prepend (const char *arg); void lt_opt_process_env_append (const char *arg); int lt_split_name_value (const char *arg, char** name, char** value); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); static const char *script_text_part1 = EOF func_emit_wrapper_part1 yes | $SED -e 's/\([\\"]\)/\\\1/g' \ -e 's/^/ "/' -e 's/$/\\n"/' echo ";" cat <"))); for (i = 0; i < newargc; i++) { LTWRAPPER_DEBUGPRINTF (("(main) newargz[%d] : %s\n", i, (newargz[i] ? newargz[i] : ""))); } EOF case $host_os in mingw*) cat <<"EOF" /* execv doesn't actually work on mingw as expected on unix */ rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz); if (rval == -1) { /* failed to start process */ LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target \"%s\": errno = %d\n", lt_argv_zero, errno)); return 127; } return rval; EOF ;; *) cat <<"EOF" execv (lt_argv_zero, newargz); return rval; /* =127, but avoids unused variable warning */ EOF ;; esac cat <<"EOF" } void * xmalloc (size_t num) { void *p = (void *) malloc (num); if (!p) lt_fatal ("Memory exhausted"); return p; } char * xstrdup (const char *string) { return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL; } const char * base_name (const char *name) { const char *base; #if defined (HAVE_DOS_BASED_FILE_SYSTEM) /* Skip over the disk name in MSDOS pathnames. */ if (isalpha ((unsigned char) name[0]) && name[1] == ':') name += 2; #endif for (base = name; *name; name++) if (IS_DIR_SEPARATOR (*name)) base = name + 1; return base; } int check_executable (const char *path) { struct stat st; LTWRAPPER_DEBUGPRINTF (("(check_executable) : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!")); if ((!path) || (!*path)) return 0; if ((stat (path, &st) >= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; LTWRAPPER_DEBUGPRINTF (("(make_executable) : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!")); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; int tmp_len; char *concat_name; LTWRAPPER_DEBUGPRINTF (("(find_executable) : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!")); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined (HAVE_DOS_BASED_FILE_SYSTEM) if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined (HAVE_DOS_BASED_FILE_SYSTEM) } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = q - p; p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal ("getcwd failed"); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal ("getcwd failed"); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { LTWRAPPER_DEBUGPRINTF (("checking path component for symlinks: %s\n", tmp_pathspec)); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { char *errstr = strerror (errno); lt_fatal ("Error accessing file %s (%s)", tmp_pathspec, errstr); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal ("Could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (strcmp (str, pat) == 0) *str = '\0'; } return str; } static void lt_error_core (int exit_status, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s: %s: ", program_name, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, "FATAL", message, ap); va_end (ap); } void lt_setenv (const char *name, const char *value) { LTWRAPPER_DEBUGPRINTF (("(lt_setenv) setting '%s' to '%s'\n", (name ? name : ""), (value ? value : ""))); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else int len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { int orig_value_len = strlen (orig_value); int add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } int lt_split_name_value (const char *arg, char** name, char** value) { const char *p; int len; if (!arg || !*arg) return 1; p = strchr (arg, (int)'='); if (!p) return 1; *value = xstrdup (++p); len = strlen (arg) - strlen (*value); *name = XMALLOC (char, len); strncpy (*name, arg, len-1); (*name)[len - 1] = '\0'; return 0; } void lt_opt_process_env_set (const char *arg) { char *name = NULL; char *value = NULL; if (lt_split_name_value (arg, &name, &value) != 0) { XFREE (name); XFREE (value); lt_fatal ("bad argument for %s: '%s'", env_set_opt, arg); } lt_setenv (name, value); XFREE (name); XFREE (value); } void lt_opt_process_env_prepend (const char *arg) { char *name = NULL; char *value = NULL; char *new_value = NULL; if (lt_split_name_value (arg, &name, &value) != 0) { XFREE (name); XFREE (value); lt_fatal ("bad argument for %s: '%s'", env_prepend_opt, arg); } new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); XFREE (name); XFREE (value); } void lt_opt_process_env_append (const char *arg) { char *name = NULL; char *value = NULL; char *new_value = NULL; if (lt_split_name_value (arg, &name, &value) != 0) { XFREE (name); XFREE (value); lt_fatal ("bad argument for %s: '%s'", env_append_opt, arg); } new_value = lt_extend_str (getenv (name), value, 1); lt_setenv (name, new_value); XFREE (new_value); XFREE (name); XFREE (value); } void lt_update_exe_path (const char *name, const char *value) { LTWRAPPER_DEBUGPRINTF (("(lt_update_exe_path) modifying '%s' by prepending '%s'\n", (name ? name : ""), (value ? value : ""))); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ int len = strlen (new_value); while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[len-1] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { LTWRAPPER_DEBUGPRINTF (("(lt_update_lib_path) modifying '%s' by prepending '%s'\n", (name ? name : ""), (value ? value : ""))); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF } # end: func_emit_cwrapperexe_src # func_mode_link arg... func_mode_link () { $opt_debug case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # which system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll which has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=no prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module="${wl}-single_module" func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg="$1" shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result func_append libtool_args " $func_quote_for_eval_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in dlfiles|dlprefiles) if test "$preload" = no; then # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=yes fi case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test "$dlself" = no; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test "$prev" = dlprefiles; then dlself=yes elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test "$prev" = dlfiles; then dlfiles="$dlfiles $arg" else dlprefiles="$dlprefiles $arg" fi prev= continue ;; esac ;; expsyms) export_symbols="$arg" test -f "$arg" \ || func_fatal_error "symbol file \`$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex="$arg" prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) deplibs="$deplibs $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir="$arg" prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # moreargs="$moreargs $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then dlfiles="$dlfiles $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. dlprefiles="$dlprefiles $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file \`$arg' does not exist" fi arg=$save_arg prev= continue ;; precious_regex) precious_files_regex="$arg" prev= continue ;; release) release="-$arg" prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test "$prev" = rpath; then case "$rpath " in *" $arg "*) ;; *) rpath="$rpath $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) xrpath="$xrpath $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds="$arg" prev= continue ;; weak) weak_libs="$weak_libs $arg" prev= continue ;; xcclinker) linker_flags="$linker_flags $qarg" compiler_flags="$compiler_flags $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) compiler_flags="$compiler_flags $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) linker_flags="$linker_flags $qarg" compiler_flags="$compiler_flags $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg="$arg" case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "\`-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test "X$arg" = "X-export-symbols"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname '-L' '' "$arg" dir=$func_stripname_result if test -z "$dir"; then if test "$#" -gt 0; then func_fatal_error "require no space between \`-L' and \`$1'" else func_fatal_error "need path for \`-L' option" fi fi # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of \`$dir'" dir="$absdir" ;; esac case "$deplibs " in *" -L$dir "*) ;; *) deplibs="$deplibs -L$dir" lib_search_path="$lib_search_path $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "X$dir" | $Xsed -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) dllsearchpath="$dllsearchpath:$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) dllsearchpath="$dllsearchpath:$testbindir";; esac ;; esac continue ;; -l*) if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test "X$arg" = "X-lc" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. test "X$arg" = "X-lc" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework deplibs="$deplibs System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test "X$arg" = "X-lc" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test "X$arg" = "X-lc" && continue ;; esac elif test "X$arg" = "X-lc_r"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi deplibs="$deplibs $arg" continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot) compiler_flags="$compiler_flags $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) compiler_flags="$compiler_flags $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) new_inherited_linker_flags="$new_inherited_linker_flags $arg" ;; esac continue ;; -multi_module) single_module="${wl}-multi_module" continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "\`-no-install' is ignored for $host" func_warning "assuming \`-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) xrpath="$xrpath $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" arg="$arg $wl$func_quote_for_eval_result" compiler_flags="$compiler_flags $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" arg="$arg $wl$func_quote_for_eval_result" compiler_flags="$compiler_flags $wl$func_quote_for_eval_result" linker_flags="$linker_flags $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; # -64, -mips[0-9] enable 64-bit mode on the SGI compiler # -r[0-9][0-9]* specifies the processor on the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler # +DA*, +DD* enable 64-bit mode on the HP compiler # -q* pass through compiler args for the IBM compiler # -m*, -t[45]*, -txscale* pass through architecture-specific # compiler args for GCC # -F/path gives path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC # @file GCC response files -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" func_append compile_command " $arg" func_append finalize_command " $arg" compiler_flags="$compiler_flags $arg" continue ;; # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; *.$objext) # A standard object. objs="$objs $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then dlfiles="$dlfiles $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. dlprefiles="$dlprefiles $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. deplibs="$deplibs $arg" old_deplibs="$old_deplibs $arg" continue ;; *.la) # A libtool-controlled library. if test "$prev" = dlfiles; then # This library was specified with -dlopen. dlfiles="$dlfiles $arg" prev= elif test "$prev" = dlprefiles; then # The library was specified with -dlpreopen. dlprefiles="$dlprefiles $arg" prev= else deplibs="$deplibs $arg" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the \`$prevarg' option requires an argument" if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname="$func_basename_result" libobjs_save="$libobjs" if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" func_dirname "$output" "/" "" output_objdir="$func_dirname_result$objdir" # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_duplicate_deps ; then case "$libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi libs="$libs $deplib" done if test "$linkmode" = lib; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; esac pre_post_deps="$pre_post_deps $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=no newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test "$linkmode,$pass" = "lib,link"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs="$tmp_deplibs" fi if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan"; then libs="$deplibs" deplibs= fi if test "$linkmode" = prog; then case $pass in dlopen) libs="$dlfiles" ;; dlpreopen) libs="$dlprefiles" ;; link) libs="$deplibs %DEPLIBS%" test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" ;; esac fi if test "$linkmode,$pass" = "lib,dlpreopen"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= case $lib in *.la) func_source "$lib" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do deplib_base=`$ECHO "X$deplib" | $Xsed -e "$basename"` case " $weak_libs " in *" $deplib_base "*) ;; *) deplibs="$deplibs $deplib" ;; esac done done libs="$dlprefiles" fi if test "$pass" = dlopen; then # Collect dlpreopened libraries save_deplibs="$deplibs" deplibs= fi for deplib in $libs; do lib= found=no case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else compiler_flags="$compiler_flags $deplib" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;; esac fi fi continue ;; -l*) if test "$linkmode" != lib && test "$linkmode" != prog; then func_warning "\`-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test "$linkmode" = lib; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib="$searchdir/lib${name}${search_ext}" if test -f "$lib"; then if test "$search_ext" = ".la"; then found=yes else found=no fi break 2 fi done done if test "$found" != yes; then # deplib doesn't seem to be a libtool library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue else # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll="$l" done if test "X$ll" = "X$old_library" ; then # only static version available found=no func_dirname "$lib" "" "." ladir="$func_dirname_result" lib=$ladir/$old_library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi fi ;; # -l *.ltframework) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test "$pass" = conv && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" newlib_search_path="$newlib_search_path $func_stripname_result" ;; prog) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi if test "$pass" = scan; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" newlib_search_path="$newlib_search_path $func_stripname_result" ;; *) func_warning "\`-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test "$pass" = link; then func_stripname '-R' '' "$deplib" dir=$func_stripname_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) xrpath="$xrpath $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) lib="$deplib" ;; *.$libext) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=no case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"X$deplib\"" 2>/dev/null | $Xsed -e 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=yes fi ;; pass_all) valid_a_lib=yes ;; esac if test "$valid_a_lib" != yes; then $ECHO $ECHO "*** Warning: Trying to link with static lib archive $deplib." $ECHO "*** I have the capability to make that library automatically link in when" $ECHO "*** you link to this library. But I can only do this if you have a" $ECHO "*** shared version of the library, which you do not appear to have" $ECHO "*** because the file extensions .$libext of this argument makes me believe" $ECHO "*** that it is just a static archive that I should not use here." else $ECHO $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" fi ;; esac continue ;; prog) if test "$pass" != link; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test "$pass" = conv; then deplibs="$deplib $deplibs" elif test "$linkmode" = prog; then if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlopen support or we're linking statically, # we need to preload. newdlprefiles="$newdlprefiles $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else newdlfiles="$newdlfiles $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=yes continue ;; esac # case $deplib if test "$found" = yes || test -f "$lib"; then : else func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" fi # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "\`$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir="$func_dirname_result" dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "X$inherited_linker_flags" | $Xsed -e 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) new_inherited_linker_flags="$new_inherited_linker_flags $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO "X $dependency_libs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan" || { test "$linkmode" != prog && test "$linkmode" != lib; }; then test -n "$dlopen" && dlfiles="$dlfiles $dlopen" test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" fi if test "$pass" = conv; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # It is a libtool convenience library, so add in its objects. convenience="$convenience $ladir/$objdir/$old_library" old_convenience="$old_convenience $ladir/$objdir/$old_library" elif test "$linkmode" != prog && test "$linkmode" != lib; then func_fatal_error "\`$lib' is not a convenience library" fi tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_duplicate_deps ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done continue fi # $pass = conv # Get the name of the library we link against. linklib= for l in $old_library $library_names; do linklib="$l" done if test -z "$linklib"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # This library was specified with -dlopen. if test "$pass" = dlopen; then if test -z "$libdir"; then func_fatal_error "cannot -dlopen a convenience library: \`$lib'" fi if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. dlprefiles="$dlprefiles $lib $dependency_libs" else newdlfiles="$newdlfiles $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of \`$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir="$ladir" fi ;; esac func_basename "$lib" laname="$func_basename_result" # Find the relevant object directory and library name. if test "X$installed" = Xyes; then if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library \`$lib' was moved." dir="$ladir" absdir="$abs_ladir" libdir="$abs_ladir" else dir="$libdir" absdir="$libdir" fi test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir="$ladir" absdir="$abs_ladir" # Remove this search path later notinst_path="$notinst_path $abs_ladir" else dir="$ladir/$objdir" absdir="$abs_ladir/$objdir" # Remove this search path later notinst_path="$notinst_path $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test "$pass" = dlpreopen; then if test -z "$libdir" && test "$linkmode" = prog; then func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" fi # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then newdlprefiles="$newdlprefiles $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ dlpreconveniencelibs="$dlpreconveniencelibs $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then newdlprefiles="$newdlprefiles $dir/$dlname" else newdlprefiles="$newdlprefiles $dir/$linklib" fi fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test "$linkmode" = lib; then deplibs="$dir/$old_library $deplibs" elif test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test "$linkmode" = prog && test "$pass" != link; then newlib_search_path="$newlib_search_path $ladir" deplibs="$lib $deplibs" linkalldeplibs=no if test "$link_all_deplibs" != no || test -z "$library_names" || test "$build_libtool_libs" = no; then linkalldeplibs=yes fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" newlib_search_path="$newlib_search_path $func_stripname_result" ;; esac # Need to link against all dependency_libs? if test "$linkalldeplibs" = yes; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_duplicate_deps ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done # for deplib continue fi # $linkmode = prog... if test "$linkmode,$pass" = "prog,link"; then if test -n "$library_names" && { { test "$prefer_static_libs" = no || test "$prefer_static_libs,$installed" = "built,yes"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then # Make sure the rpath contains only unique directories. case "$temp_rpath:" in *"$absdir:"*) ;; *) temp_rpath="$temp_rpath$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) compile_rpath="$compile_rpath $absdir" esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" esac ;; esac fi # $linkmode,$pass = prog,link... if test "$alldeplibs" = yes && { test "$deplibs_check_method" = pass_all || { test "$build_libtool_libs" = yes && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test "$use_static_libs" = built && test "$installed" = yes; then use_static_libs=no fi if test -n "$library_names" && { test "$use_static_libs" = no || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc*) # No point in relinking DLLs because paths are not encoded notinst_deplibs="$notinst_deplibs $lib" need_relink=no ;; *) if test "$installed" = no; then notinst_deplibs="$notinst_deplibs $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule="" for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule="$dlpremoduletest" break fi done if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then $ECHO if test "$linkmode" = prog; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test "$linkmode" = lib && test "$hardcode_into_libs" = yes; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) compile_rpath="$compile_rpath $absdir" esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname="$1" shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname="$dlname" elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc*) func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; esac eval soname=\"$soname_spec\" else soname="$realname" fi # Make a new name for the extract_expsyms_cmds to use soroot="$soname" func_basename "$soroot" soname="$func_basename_result" func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from \`$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for \`$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test "$linkmode" = prog || test "$mode" != relink; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test "$hardcode_direct" = no; then add="$dir/$linklib" case $host in *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; *-*-sysv4*uw2*) add_dir="-L$dir" ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir="-L$dir" ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we can not # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null ; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library" ; then $ECHO $ECHO "*** And there doesn't seem to be a static archive available" $ECHO "*** The link will probably fail, sorry" else add="$dir/$old_library" fi elif test -n "$old_library"; then add="$dir/$old_library" fi fi esac elif test "$hardcode_minus_L" = no; then case $host in *-*-sunos*) add_shlibpath="$dir" ;; esac add_dir="-L$dir" add="-l$name" elif test "$hardcode_shlibpath_var" = no; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; relink) if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$dir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$dir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) add_dir="$add_dir -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; *) lib_linked=no ;; esac if test "$lib_linked" != yes; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; esac fi if test "$linkmode" = prog; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test "$hardcode_direct" != yes && test "$hardcode_minus_L" != yes && test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; esac fi fi fi if test "$linkmode" = prog || test "$mode" = relink; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$libdir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$libdir" add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; esac add="-l$name" elif test "$hardcode_automatic" = yes; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib" ; then add="$inst_prefix_dir$libdir/$linklib" else add="$libdir/$linklib" fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir="-L$libdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) add_dir="$add_dir -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" fi if test "$linkmode" = prog; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test "$linkmode" = prog; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test "$hardcode_direct" != unsupported; then test -n "$old_library" && linklib="$old_library" compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test "$build_libtool_libs" = yes; then # Not a shared library if test "$deplibs_check_method" != pass_all; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. $ECHO $ECHO "*** Warning: This system can not link to static lib archive $lib." $ECHO "*** I have the capability to make that library automatically link in when" $ECHO "*** you link to this library. But I can only do this if you have a" $ECHO "*** shared version of the library, which you do not appear to have." if test "$module" = yes; then $ECHO "*** But as you try to build a module library, libtool will still create " $ECHO "*** a static module, that should work as long as the dlopening application" $ECHO "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then $ECHO $ECHO "*** However, this would only work if libtool was able to extract symbol" $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could" $ECHO "*** not find such a program. So, this module is probably useless." $ECHO "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test "$linkmode" = lib; then if test -n "$dependency_libs" && { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes || test "$link_static" = yes; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) xrpath="$xrpath $temp_xrpath";; esac;; *) temp_deplibs="$temp_deplibs $libdir";; esac done dependency_libs="$temp_deplibs" fi newlib_search_path="$newlib_search_path $absdir" # Link against this library test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" if $opt_duplicate_deps ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done if test "$link_all_deplibs" != no; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do case $deplib in -L*) path="$deplib" ;; *.la) func_dirname "$deplib" "" "." dir="$func_dirname_result" # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of \`$dir'" absdir="$dir" fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names" ; then for tmp in $deplibrary_names ; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl" ; then depdepl="$absdir/$objdir/$depdepl" darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi compiler_flags="$compiler_flags ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" linker_flags="$linker_flags -dylib_file ${darwin_install_name}:${depdepl}" path= fi fi ;; *) path="-L$absdir/$objdir" ;; esac else eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "\`$deplib' seems to be moved" path="-L$absdir" fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test "$pass" = link; then if test "$linkmode" = "prog"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs="$newdependency_libs" if test "$pass" = dlpreopen; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test "$pass" != dlopen; then if test "$pass" != conv; then # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) lib_search_path="$lib_search_path $dir" ;; esac done newlib_search_path= fi if test "$linkmode,$pass" != "prog,link"; then vars="deplibs" else vars="compile_deplibs finalize_deplibs" fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) tmp_libs="$tmp_libs $deplib" ;; esac ;; *) tmp_libs="$tmp_libs $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs ; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i="" ;; esac if test -n "$i" ; then tmp_libs="$tmp_libs $i" fi done dependency_libs=$tmp_libs done # for pass if test "$linkmode" = prog; then dlfiles="$newdlfiles" fi if test "$linkmode" = prog || test "$linkmode" = lib; then dlprefiles="$newdlprefiles" fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "\`-R' is ignored for archives" test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "\`-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "\`-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs="$output" objs="$objs$old_deplibs" ;; lib) # Make sure we only generate libraries of the form `libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test "$module" = no && \ func_fatal_help "libtool library \`$output' must begin with \`lib'" if test "$need_lib_prefix" != no; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test "$deplibs_check_method" != pass_all; then func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" else $ECHO $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" libobjs="$libobjs $objs" fi fi test "$dlself" != no && \ func_warning "\`-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test "$#" -gt 1 && \ func_warning "ignoring multiple \`-rpath's for a libtool library" install_libdir="$1" oldlibs= if test -z "$rpath"; then if test "$build_libtool_libs" = yes; then # Building a libtool convenience library. # Some compilers have problems with a `.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "\`-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs="$IFS"; IFS=':' set dummy $vinfo 0 0 0 shift IFS="$save_ifs" test -n "$7" && \ func_fatal_help "too many parameters to \`-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major="$1" number_minor="$2" number_revision="$3" # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # which has an extra 1 added just for fun # case $version_type in darwin|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_revision" ;; freebsd-aout|freebsd-elf|sunos) current="$number_major" revision="$number_minor" age="0" ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_minor" lt_irix_increment=no ;; *) func_fatal_configuration "$modename: unknown library version type \`$version_type'" ;; esac ;; no) current="$1" revision="$2" age="$3" ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT \`$current' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION \`$revision' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE \`$age' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE \`$age' is greater than the current interface number \`$current'" func_fatal_error "\`$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; freebsd-aout) major=".$current" versuffix=".$current.$revision"; ;; freebsd-elf) major=".$current" versuffix=".$current" ;; irix | nonstopux) if test "X$lt_irix_increment" = "Xno"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring="$verstring_prefix$major.$revision" # Add in all the interfaces that we are compatible with. loop=$revision while test "$loop" -ne 0; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring_prefix$major.$iface:$verstring" done # Before this point, $major must not contain `.'. major=.$major versuffix="$major.$revision" ;; linux) func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=".$current.$age.$revision" verstring="$current.$age.$revision" # Add in all the interfaces that we are compatible with. loop=$age while test "$loop" -ne 0; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring:${iface}.0" done # Make executables depend on our current version. verstring="$verstring:${current}.0" ;; qnx) major=".$current" versuffix=".$current" ;; sunos) major=".$current" versuffix=".$current.$revision" ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 filesystems. func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; *) func_fatal_configuration "unknown library version type \`$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring="0.0" ;; esac if test "$need_version" = no; then versuffix= else versuffix=".0.0" fi fi # Remove version info from name if versioning should be avoided if test "$avoid_version" = yes && test "$need_version" = no; then major= versuffix= verstring="" fi # Check to see if the archive will have undefined symbols. if test "$allow_undefined" = yes; then if test "$allow_undefined_flag" = unsupported; then func_warning "undefined symbols not allowed in $host shared libraries" build_libtool_libs=no build_old_libs=yes fi else # Don't allow undefined symbols. allow_undefined_flag="$no_undefined_flag" fi fi func_generate_dlsyms "$libname" "$libname" "yes" libobjs="$libobjs $symfileobj" test "X$libobjs" = "X " && libobjs= if test "$mode" != relink; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) if test "X$precious_files_regex" != "X"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi removelist="$removelist $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then oldlibs="$oldlibs $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "X$lib_search_path " | $Xsed -e "s% $path % %g"` # deplibs=`$ECHO "X$deplibs " | $Xsed -e "s% -L$path % %g"` # dependency_libs=`$ECHO "X$dependency_libs " | $Xsed -e "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do temp_xrpath="$temp_xrpath -R$libdir" case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" ;; esac done if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles="$dlfiles" dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) dlfiles="$dlfiles $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles="$dlprefiles" dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) dlprefiles="$dlprefiles $lib" ;; esac done if test "$build_libtool_libs" = yes; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework deplibs="$deplibs System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test "$build_libtool_need_lc" = "yes"; then deplibs="$deplibs -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release="" versuffix="" major="" newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c </dev/null` for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib="$potent_lib" while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; *) potlib=`$ECHO "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then newdeplibs="$newdeplibs $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes $ECHO $ECHO "*** Warning: linker path does not have real file for library $a_deplib." $ECHO "*** I have the capability to make that library automatically link in when" $ECHO "*** you link to this library. But I can only do this if you have a" $ECHO "*** shared version of the library, which you do not appear to have" $ECHO "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. newdeplibs="$newdeplibs $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $a_deplib "*) newdeplibs="$newdeplibs $a_deplib" a_deplib="" ;; esac fi if test -n "$a_deplib" ; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib="$potent_lib" # see symlink-check above in file_magic test if eval "\$ECHO \"X$potent_lib\"" 2>/dev/null | $Xsed -e 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then newdeplibs="$newdeplibs $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes $ECHO $ECHO "*** Warning: linker path does not have real file for library $a_deplib." $ECHO "*** I have the capability to make that library automatically link in when" $ECHO "*** you link to this library. But I can only do this if you have a" $ECHO "*** shared version of the library, which you do not appear to have" $ECHO "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. newdeplibs="$newdeplibs $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs="" tmp_deplibs=`$ECHO "X $deplibs" | $Xsed \ -e 's/ -lc$//' -e 's/ -[LR][^ ]*//g'` if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then for i in $predeps $postdeps ; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO "X $tmp_deplibs" | $Xsed -e "s,$i,,"` done fi if $ECHO "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' | $GREP . >/dev/null; then $ECHO if test "X$deplibs_check_method" = "Xnone"; then $ECHO "*** Warning: inter-library dependencies are not supported in this platform." else $ECHO "*** Warning: inter-library dependencies are not known to be supported." fi $ECHO "*** All declared inter-library dependencies are being dropped." droppeddeps=yes fi ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's/ -lc / System.ltframework /'` ;; esac if test "$droppeddeps" = yes; then if test "$module" = yes; then $ECHO $ECHO "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" $ECHO "*** a static module, that should work as long as the dlopening" $ECHO "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then $ECHO $ECHO "*** However, this would only work if libtool was able to extract symbol" $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could" $ECHO "*** not find such a program. So, this module is probably useless." $ECHO "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else $ECHO "*** The inter-library dependencies that have been dropped here will be" $ECHO "*** automatically added whenever a program is linked with this library" $ECHO "*** or is declared to -dlopen it." if test "$allow_undefined" = no; then $ECHO $ECHO "*** Since this library must not contain undefined symbols," $ECHO "*** because either the platform does not support them or" $ECHO "*** it was explicitly requested with -no-undefined," $ECHO "*** libtool will only create a static version of it." if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO "X $deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) new_libs="$new_libs -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$new_libs $deplib" ;; esac ;; *) new_libs="$new_libs $deplib" ;; esac done deplibs="$new_libs" # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test "$build_libtool_libs" = yes; then if test "$hardcode_into_libs" = yes; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath="$finalize_rpath" test "$mode" != relink && rpath="$compile_rpath$rpath" for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" dep_rpath="$dep_rpath $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) perm_rpath="$perm_rpath $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" if test -n "$hardcode_libdir_flag_spec_ld"; then eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" else eval dep_rpath=\"$hardcode_libdir_flag_spec\" fi fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do rpath="$rpath$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath="$finalize_shlibpath" test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname="$1" shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname="$realname" fi if test -z "$dlname"; then dlname=$soname fi lib="$output_objdir/$realname" linknames= for link do linknames="$linknames $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols="$output_objdir/$libname.uexp" delfiles="$delfiles $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile if test "x`$SED 1q $export_symbols`" != xEXPORTS; then # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols="$export_symbols" export_symbols= always_export_symbols=yes fi fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" func_len " $cmd" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then func_show_eval "$cmd" 'exit $?' skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS="$save_ifs" if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"' fi if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter delfiles="$delfiles $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) tmp_deplibs="$tmp_deplibs $test_deplib" ;; esac done deplibs="$tmp_deplibs" if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test "$compiler_needs_object" = yes && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_extract_archives $gentop $convenience libobjs="$libobjs $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" linker_flags="$linker_flags $flag" fi # Make a backup of the uninstalled library when relinking if test "$mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test "X$skipped_export" != "X:" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output output_la=`$ECHO "X$output" | $Xsed -e "$basename"` # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then output=${output_objdir}/${output_la}.lnkscript func_verbose "creating GNU ld script: $output" $ECHO 'INPUT (' > $output for obj in $save_libobjs do $ECHO "$obj" >> $output done $ECHO ')' >> $output delfiles="$delfiles $output" elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then output=${output_objdir}/${output_la}.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test "$compiler_needs_object" = yes; then firstobj="$1 " shift fi for obj do $ECHO "$obj" >> $output done delfiles="$delfiles $output" output=$firstobj\"$file_list_spec$output\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-${k}.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test "X$objlist" = X || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test "$k" -eq 1 ; then # The first file doesn't have a previous command to add. eval concat_cmds=\"$reload_cmds $objlist $last_robj\" else # All subsequent reloadable object files will link in # the last one created. eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-${k}.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-${k}.$objext objlist=$obj func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" if test -n "$last_robj"; then eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" fi delfiles="$delfiles $output" else output= fi if ${skipped_export-false}; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi fi test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs="$IFS"; IFS='~' for cmd in $concat_cmds; do IFS="$save_ifs" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi if ${skipped_export-false}; then if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter delfiles="$delfiles $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi fi libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_extract_archives $gentop $dlprefiles libobjs="$libobjs $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" # Restore the uninstalled library and exit if test "$mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test "$module" = yes || test "$export_dynamic" = yes; then # On all known operating systems, these are identical. dlname="$soname" fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "\`-R' is ignored for objects" test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for objects" test -n "$release" && \ func_warning "\`-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object \`$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj="$output" ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # reload_cmds runs $LD directly, so let us get rid of # -Wl from whole_archive_flag_spec and hope we can get by with # turning comma into space.. wl= if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" reload_conv_objs=$reload_objs\ `$ECHO "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'` else gentop="$output_objdir/${obj}x" generated="$generated $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # Create the old-style object. reload_objs="$objs$old_deplibs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test output="$obj" func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi if test "$build_libtool_libs" != yes; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS fi if test -n "$pic_flag" || test "$pic_mode" != default; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output="$libobj" func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for programs" test -n "$release" && \ func_warning "\`-release' is ignored for programs" test "$preload" = yes \ && test "$dlopen_support" = unknown \ && test "$dlopen_self" = unknown \ && test "$dlopen_self_static" = unknown && \ func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test "$tagname" = CXX ; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) compile_command="$compile_command ${wl}-bind_at_load" finalize_command="$finalize_command ${wl}-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) new_libs="$new_libs -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$new_libs $deplib" ;; esac ;; *) new_libs="$new_libs $deplib" ;; esac done compile_deplibs="$new_libs" compile_command="$compile_command $compile_deplibs" finalize_command="$finalize_command $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" rpath="$rpath $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) perm_rpath="$perm_rpath $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) dllsearchpath="$dllsearchpath:$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) dllsearchpath="$dllsearchpath:$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath="$rpath" rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" rpath="$rpath $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath="$rpath" if test -n "$libobjs" && test "$build_old_libs" = yes; then # Transform all the library objects into standard objects. compile_command=`$ECHO "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` finalize_command=`$ECHO "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" "no" # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=yes case $host in *cygwin* | *mingw* ) if test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; *cegcc) # Disable wrappers for cegcc, we are cross compiling anyway. wrappers_required=no ;; *) if test "$need_relink" = no || test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; esac if test "$wrappers_required" = no; then # Replace the output file specification. compile_command=`$ECHO "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` link_command="$compile_command$compile_rpath" # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' # Delete the generated files. if test -f "$output_objdir/${outputname}S.${objext}"; then func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' fi exit $exit_status fi if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do rpath="$rpath$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do rpath="$rpath$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test "$no_install" = yes; then # We don't need to create a wrapper script. link_command="$compile_var$compile_command$compile_rpath" # Replace the output file specification. link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' exit $EXIT_SUCCESS fi if test "$hardcode_action" = relink; then # Fast installation is not supported link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" func_warning "this platform does not like uninstalled shared libraries" func_warning "\`$output' will be relinked during installation" else if test "$fast_install" != no; then link_command="$finalize_var$compile_command$finalize_rpath" if test "$fast_install" = yes; then relink_command=`$ECHO "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` else # fast_install is set to needless relink_command= fi else link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" fi fi # Replace the output file specification. link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"` fi # Quote $ECHO for shipping. if test "X$ECHO" = "X$SHELL $progpath --fallback-echo"; then case $progpath in [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; esac qecho=`$ECHO "X$qecho" | $Xsed -e "$sed_quote_subst"` else qecho=`$ECHO "X$ECHO" | $Xsed -e "$sed_quote_subst"` fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource="$output_path/$objdir/lt-$output_name.c" cwrapper="$output_path/$output_name.exe" $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host" ; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do if test "$build_libtool_libs" = convenience; then oldobjs="$libobjs_save $symfileobj" addlibs="$convenience" build_libtool_libs=no else if test "$build_libtool_libs" = module; then oldobjs="$libobjs_save" build_libtool_libs=no else oldobjs="$old_deplibs $non_pic_objects" if test "$preload" = yes && test -f "$symfileobj"; then oldobjs="$oldobjs $symfileobj" fi fi addlibs="$old_convenience" fi if test -n "$addlibs"; then gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_extract_archives $gentop $addlibs oldobjs="$oldobjs $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_extract_archives $gentop $dlprefiles oldobjs="$oldobjs $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else $ECHO "copying selected object files to avoid basename conflicts..." gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase="$func_basename_result" case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" oldobjs="$oldobjs $gentop/$newobj" ;; *) oldobjs="$oldobjs $obj" ;; esac done fi eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj" ; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test "X$oldobjs" = "X" ; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test "$build_old_libs" = yes && old_library="$libname.$libext" func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"` if test "$hardcode_automatic" = yes ; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test "$installed" = yes; then if test -z "$install_libdir"; then break fi output="$output_objdir/$outputname"i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" newdependency_libs="$newdependency_libs $libdir/$name" ;; *) newdependency_libs="$newdependency_libs $deplib" ;; esac done dependency_libs="$newdependency_libs" newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" newdlfiles="$newdlfiles $libdir/$name" ;; *) newdlfiles="$newdlfiles $lib" ;; esac done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" newdlprefiles="$newdlprefiles $libdir/$name" ;; esac done dlprefiles="$newdlprefiles" else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac newdlfiles="$newdlfiles $abs" done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac newdlprefiles="$newdlprefiles $abs" done dlprefiles="$newdlprefiles" fi $RM $output # place dlname in correct position for cygwin tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that can not go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test "$installed" = no && test "$need_relink" = yes; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } { test "$mode" = link || test "$mode" = relink; } && func_mode_link ${1+"$@"} # func_mode_uninstall arg... func_mode_uninstall () { $opt_debug RM="$nonopt" files= rmforce= exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" for arg do case $arg in -f) RM="$RM $arg"; rmforce=yes ;; -*) RM="$RM $arg" ;; *) files="$files $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= origobjdir="$objdir" for file in $files; do func_dirname "$file" "" "." dir="$func_dirname_result" if test "X$dir" = X.; then objdir="$origobjdir" else objdir="$dir/$origobjdir" fi func_basename "$file" name="$func_basename_result" test "$mode" = uninstall && objdir="$dir" # Remember objdir for removal later, being careful to avoid duplicates if test "$mode" = clean; then case " $rmdirs " in *" $objdir "*) ;; *) rmdirs="$rmdirs $objdir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif test "$rmforce" = yes; then continue fi rmfiles="$file" case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do rmfiles="$rmfiles $objdir/$n" done test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" case "$mode" in clean) case " $library_names " in # " " in the beginning catches empty $dlname *" $dlname "*) ;; *) rmfiles="$rmfiles $objdir/$dlname" ;; esac test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test "$pic_object" != none; then rmfiles="$rmfiles $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test "$non_pic_object" != none; then rmfiles="$rmfiles $dir/$non_pic_object" fi fi ;; *) if test "$mode" = clean ; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe rmfiles="$rmfiles $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result rmfiles="$rmfiles $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" if test "$fast_install" = yes && test -n "$relink_command"; then rmfiles="$rmfiles $objdir/lt-$name" fi if test "X$noexename" != "X$name" ; then rmfiles="$rmfiles $objdir/lt-${noexename}.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done objdir="$origobjdir" # Try to remove the ${objdir}s in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } { test "$mode" = uninstall || test "$mode" = clean; } && func_mode_uninstall ${1+"$@"} test -z "$mode" && { help="$generic_help" func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode \`$mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # in which we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: # vi:sw=2 proftpd-dfsg-1.3.5~rc3/lib/libltdl/config/config.guess0000755000175000017500000012743211757733521022552 0ustar frankiefrankie#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012 Free Software Foundation, Inc. timestamp='2012-02-10' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner. Please send patches (context # diff format) to and include a ChangeLog # entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm:riscos:*:*|arm:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-gnu else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-gnueabi else echo ${UNAME_MACHINE}-unknown-linux-gnueabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-gnu exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:Linux:*:*) LIBC=gnu eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; padre:Linux:*:*) echo sparc-unknown-linux-gnu exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in i386) eval $set_cc_for_build if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then UNAME_PROCESSOR="x86_64" fi fi ;; unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: proftpd-dfsg-1.3.5~rc3/lib/libltdl/config/install-sh0000755000175000017500000003246411300565264022225 0ustar frankiefrankie#!/bin/sh # install - install a program, script, or datafile scriptversion=2006-12-25.00 # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. nl=' ' IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else doit_exec=$doit fi # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_glob='?' initialize_posix_glob=' test "$posix_glob" != "?" || { if (set -f) 2>/dev/null; then posix_glob= else posix_glob=: fi } ' posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false no_target_directory= usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) dst_arg=$2 shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call `install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then trap '(exit $?); exit' 1 2 13 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names starting with `-'. case $src in -*) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # Protect names starting with `-'. case $dst in -*) dst=./$dst;; esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else # Prefer dirname, but fall back on a substitute if dirname fails. dstdir=` (dirname "$dst") 2>/dev/null || expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$dst" : 'X\(//\)[^/]' \| \ X"$dst" : 'X\(//\)$' \| \ X"$dst" : 'X\(/\)' \| . 2>/dev/null || echo X"$dst" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q' ` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writeable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; -*) prefix='./';; *) prefix='';; esac eval "$initialize_posix_glob" oIFS=$IFS IFS=/ $posix_glob set -f set fnord $dstdir shift $posix_glob set +f IFS=$oIFS prefixes= for d do test -z "$d" && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && eval "$initialize_posix_glob" && $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && $posix_glob set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: proftpd-dfsg-1.3.5~rc3/lib/libltdl/config/config.sub0000755000175000017500000010527411757733521022215 0ustar frankiefrankie#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012 Free Software Foundation, Inc. timestamp='2012-04-18' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . Submit a context # diff and a properly formatted GNU ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ | be32 | be64 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | epiphany \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 \ | ns16k | ns32k \ | open8 \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze) basic_machine=microblaze-xilinx ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i386-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: proftpd-dfsg-1.3.5~rc3/lib/libltdl/config/missing0000755000175000017500000002557711300565264021627 0ustar frankiefrankie#! /bin/sh # Common stub for a few missing GNU programs while installing. scriptversion=2006-05-10.23 # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006 # Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' sed_minuso='s/.* -o \([^ ]*\).*/\1/p' # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi msg="missing on your system" case $1 in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 # Exit code 63 means version mismatch. This often happens # when the user try to use an ancient version of a tool on # a file that requires a minimum version. In this case we # we should proceed has if the program had been absent, or # if --run hadn't been passed. if test $? = 63; then run=: msg="probably too old" fi ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' autom4te touch the output file, or create a stub one automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch] Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; esac # Now exit if we have it, but it failed. Also exit now if we # don't have it and --version was passed (most likely to detect # the program). case $1 in lex|yacc) # Not GNU programs, they don't have --version. ;; tar) if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then exit 1 fi ;; *) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then # Could not run --version or --help. This is probably someone # running `$TOOL --version' or `$TOOL --help' to check whether # $TOOL exists and not knowing $TOOL uses missing. exit 1 fi ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case $1 in aclocal*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case $f in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te) echo 1>&2 "\ WARNING: \`$1' is needed, but is $msg. You might have modified some files without having the proper tools for further handling them. You can get \`$1' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' $msg. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if test $# -ne 1; then eval LASTARG="\${$#}" case $LASTARG in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.h fi ;; esac fi if test ! -f y.tab.h; then echo >y.tab.h fi if test ! -f y.tab.c; then echo 'main() { return 0; }' >y.tab.c fi ;; lex|flex) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if test $# -ne 1; then eval LASTARG="\${$#}" case $LASTARG in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if test -f "$SRCFILE"; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if test ! -f lex.yy.c; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit 1 fi ;; makeinfo) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." # The file to touch is that specified with -o ... file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -z "$file"; then # ... or it is the one specified with @setfilename ... infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n ' /^@setfilename/{ s/.* \([^ ]*\) *$/\1/ p q }' $infile` # ... or it is derived from the source name (dir/f.texi becomes f.info) test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info fi # If the file does not exist, the user really needs makeinfo; # let's fail without touching anything. test -f $file || exit 1 touch $file ;; tar) shift # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar "$@" && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar "$@" && exit 0 fi firstarg="$1" if shift; then case $firstarg in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac case $firstarg in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and is $msg. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequisites for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: proftpd-dfsg-1.3.5~rc3/lib/libltdl/Makefile.am0000644000175000017500000001207711300565263021005 0ustar frankiefrankie## Makefile.am -- Process this file with automake to produce Makefile.in ## ## Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation, Inc. ## Written by Gary V. Vaughan, 2003 ## ## NOTE: The canonical source of this file is maintained with the ## GNU Libtool package. Report bugs to bug-libtool@gnu.org. ## ## GNU Libltdl is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public ## License as published by the Free Software Foundation; either ## version 2 of the License, or (at your option) any later version. ## ## As a special exception to the GNU Lesser General Public License, ## if you distribute this file as part of a program or library that ## is built using GNU libtool, you may include this file under the ## same distribution terms that you use for the rest of that program. ## ## GNU Libltdl is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU LesserGeneral Public ## License along with GNU Libltdl; see the file COPYING.LIB. If not, a ## copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, ## or obtained by writing to the Free Software Foundation, Inc., ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ##### ACLOCAL_AMFLAGS = -I m4 AUTOMAKE_OPTIONS = foreign AM_CPPFLAGS = AM_LDFLAGS = BUILT_SOURCES = include_HEADERS = noinst_LTLIBRARIES = lib_LTLIBRARIES = EXTRA_LTLIBRARIES = EXTRA_DIST = CLEANFILES = MOSTLYCLEANFILES = # -I$(srcdir) is needed for user that built libltdl with a sub-Automake # (not as a sub-package!) using 'nostdinc': AM_CPPFLAGS += -DLT_CONFIG_H='<$(LT_CONFIG_H)>' \ -DLTDL -I. -I$(srcdir) -Ilibltdl \ -I$(srcdir)/libltdl -I$(srcdir)/libltdl AM_LDFLAGS += -no-undefined LTDL_VERSION_INFO = -version-info 9:0:2 noinst_LTLIBRARIES += $(LT_DLLOADERS) if INSTALL_LTDL ltdlincludedir = $(includedir)/libltdl ltdlinclude_HEADERS = libltdl/lt_system.h \ libltdl/lt_error.h \ libltdl/lt_dlloader.h include_HEADERS += ltdl.h lib_LTLIBRARIES += libltdl.la endif if CONVENIENCE_LTDL noinst_LTLIBRARIES += libltdlc.la endif libltdl_la_SOURCES = libltdl/lt__alloc.h \ libltdl/lt__dirent.h \ libltdl/lt__glibc.h \ libltdl/lt__private.h \ libltdl/lt__strl.h \ libltdl/lt_dlloader.h \ libltdl/lt_error.h \ libltdl/lt_system.h \ libltdl/slist.h \ loaders/preopen.c \ lt__alloc.c \ lt_dlloader.c \ lt_error.c \ ltdl.c \ ltdl.h \ slist.c EXTRA_DIST += lt__dirent.c \ lt__strl.c libltdl_la_CPPFLAGS = -DLTDLOPEN=$(LTDLOPEN) $(AM_CPPFLAGS) libltdl_la_LDFLAGS = $(AM_LDFLAGS) $(LTDL_VERSION_INFO) $(LT_DLPREOPEN) libltdl_la_LIBADD = $(LTLIBOBJS) libltdl_la_DEPENDENCIES = $(LT_DLLOADERS) $(LTLIBOBJS) libltdlc_la_SOURCES = $(libltdl_la_SOURCES) libltdlc_la_CPPFLAGS = -DLTDLOPEN=$(LTDLOPEN)c $(AM_CPPFLAGS) libltdlc_la_LDFLAGS = $(AM_LDFLAGS) $(LT_DLPREOPEN) libltdlc_la_LIBADD = $(libltdl_la_LIBADD) libltdlc_la_DEPENDENCIES= $(libltdl_la_DEPENDENCIES) ## The loaders are preopened by libltdl, itself always built from ## pic-objects (either as a shared library, or a convenience library), ## so the loaders themselves must be made from pic-objects too. We ## use convenience libraries for that purpose: EXTRA_LTLIBRARIES += dlopen.la \ dld_link.la \ dyld.la \ load_add_on.la \ loadlibrary.la \ shl_load.la dlopen_la_SOURCES = loaders/dlopen.c dlopen_la_LDFLAGS = -module -avoid-version dlopen_la_LIBADD = $(LIBADD_DLOPEN) dld_link_la_SOURCES = loaders/dld_link.c dld_link_la_LDFLAGS = -module -avoid-version dld_link_la_LIBADD = -ldld dyld_la_SOURCES = loaders/dyld.c dyld_la_LDFLAGS = -module -avoid-version load_add_on_la_SOURCES = loaders/load_add_on.c load_add_on_la_LDFLAGS = -module -avoid-version loadlibrary_la_SOURCES = loaders/loadlibrary.c loadlibrary_la_LDFLAGS = -module -avoid-version shl_load_la_SOURCES = loaders/shl_load.c shl_load_la_LDFLAGS = -module -avoid-version shl_load_la_LIBADD = $(LIBADD_SHL_LOAD) ## Make sure these will be cleaned even when they're not built by default: CLEANFILES += libltdl.la \ libltdlc.la \ libdlloader.la ## Automake-1.9.6 doesn't clean subdir AC_LIBOBJ compiled objects ## automatically: CLEANFILES += $(LIBOBJS) $(LTLIBOBJS) EXTRA_DIST += COPYING.LIB \ configure.ac \ Makefile.am \ aclocal.m4 \ Makefile.in \ configure \ config-h.in \ README ## --------------------------- ## ## Gnulib Makefile.am snippets ## ## --------------------------- ## BUILT_SOURCES += $(ARGZ_H) EXTRA_DIST += argz_.h \ argz.c # We need the following in order to create an when the system # doesn't have one that works with the given compiler. all-local $(lib_OBJECTS): $(ARGZ_H) argz.h: argz_.h $(mkinstalldirs) . cp $(srcdir)/argz_.h $@-t mv $@-t $@ MOSTLYCLEANFILES += argz.h \ argz.h-t proftpd-dfsg-1.3.5~rc3/lib/libltdl/Makefile.in0000644000175000017500000013552611300567412021021 0ustar frankiefrankie# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ ##### VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @INSTALL_LTDL_TRUE@am__append_1 = ltdl.h @INSTALL_LTDL_TRUE@am__append_2 = libltdl.la @CONVENIENCE_LTDL_TRUE@am__append_3 = libltdlc.la subdir = . DIST_COMMON = README $(am__configure_deps) $(am__include_HEADERS_DIST) \ $(am__ltdlinclude_HEADERS_DIST) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/config-h.in \ $(top_srcdir)/configure COPYING.LIB argz.c config/compile \ config/config.guess config/config.sub config/depcomp \ config/install-sh config/ltmain.sh \ config/missing lt__dirent.c lt__strl.c ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/argz.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltdl.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" \ "$(DESTDIR)$(ltdlincludedir)" libLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES) dld_link_la_DEPENDENCIES = am_dld_link_la_OBJECTS = dld_link.lo dld_link_la_OBJECTS = $(am_dld_link_la_OBJECTS) dld_link_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(dld_link_la_LDFLAGS) $(LDFLAGS) -o $@ am__DEPENDENCIES_1 = dlopen_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am_dlopen_la_OBJECTS = dlopen.lo dlopen_la_OBJECTS = $(am_dlopen_la_OBJECTS) dlopen_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(dlopen_la_LDFLAGS) $(LDFLAGS) -o $@ dyld_la_LIBADD = am_dyld_la_OBJECTS = dyld.lo dyld_la_OBJECTS = $(am_dyld_la_OBJECTS) dyld_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(dyld_la_LDFLAGS) \ $(LDFLAGS) -o $@ am_libltdl_la_OBJECTS = libltdl_la-preopen.lo libltdl_la-lt__alloc.lo \ libltdl_la-lt_dlloader.lo libltdl_la-lt_error.lo \ libltdl_la-ltdl.lo libltdl_la-slist.lo libltdl_la_OBJECTS = $(am_libltdl_la_OBJECTS) libltdl_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libltdl_la_LDFLAGS) $(LDFLAGS) -o $@ @INSTALL_LTDL_TRUE@am_libltdl_la_rpath = -rpath $(libdir) am__objects_1 = libltdlc_la-preopen.lo libltdlc_la-lt__alloc.lo \ libltdlc_la-lt_dlloader.lo libltdlc_la-lt_error.lo \ libltdlc_la-ltdl.lo libltdlc_la-slist.lo am_libltdlc_la_OBJECTS = $(am__objects_1) libltdlc_la_OBJECTS = $(am_libltdlc_la_OBJECTS) libltdlc_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libltdlc_la_LDFLAGS) $(LDFLAGS) -o $@ @CONVENIENCE_LTDL_TRUE@am_libltdlc_la_rpath = load_add_on_la_LIBADD = am_load_add_on_la_OBJECTS = load_add_on.lo load_add_on_la_OBJECTS = $(am_load_add_on_la_OBJECTS) load_add_on_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(load_add_on_la_LDFLAGS) $(LDFLAGS) -o $@ loadlibrary_la_LIBADD = am_loadlibrary_la_OBJECTS = loadlibrary.lo loadlibrary_la_OBJECTS = $(am_loadlibrary_la_OBJECTS) loadlibrary_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(loadlibrary_la_LDFLAGS) $(LDFLAGS) -o $@ shl_load_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am_shl_load_la_OBJECTS = shl_load.lo shl_load_la_OBJECTS = $(am_shl_load_la_OBJECTS) shl_load_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(shl_load_la_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(dld_link_la_SOURCES) $(dlopen_la_SOURCES) \ $(dyld_la_SOURCES) $(libltdl_la_SOURCES) \ $(libltdlc_la_SOURCES) $(load_add_on_la_SOURCES) \ $(loadlibrary_la_SOURCES) $(shl_load_la_SOURCES) DIST_SOURCES = $(dld_link_la_SOURCES) $(dlopen_la_SOURCES) \ $(dyld_la_SOURCES) $(libltdl_la_SOURCES) \ $(libltdlc_la_SOURCES) $(load_add_on_la_SOURCES) \ $(loadlibrary_la_SOURCES) $(shl_load_la_SOURCES) am__include_HEADERS_DIST = ltdl.h includeHEADERS_INSTALL = $(INSTALL_HEADER) am__ltdlinclude_HEADERS_DIST = libltdl/lt_system.h libltdl/lt_error.h \ libltdl/lt_dlloader.h ltdlincludeHEADERS_INSTALL = $(INSTALL_HEADER) HEADERS = $(include_HEADERS) $(ltdlinclude_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ { test ! -d $(distdir) \ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -fr $(distdir); }; } DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ ARGZ_H = @ARGZ_H@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ LIBADD_DLOPEN = @LIBADD_DLOPEN@ LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTDLOPEN = @LTDLOPEN@ LTLIBOBJS = @LTLIBOBJS@ LT_CONFIG_H = @LT_CONFIG_H@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sys_symbol_underscore = @sys_symbol_underscore@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ACLOCAL_AMFLAGS = -I m4 AUTOMAKE_OPTIONS = foreign # -I$(srcdir) is needed for user that built libltdl with a sub-Automake # (not as a sub-package!) using 'nostdinc': AM_CPPFLAGS = -DLT_CONFIG_H='<$(LT_CONFIG_H)>' -DLTDL -I. -I$(srcdir) \ -Ilibltdl -I$(srcdir)/libltdl -I$(srcdir)/libltdl AM_LDFLAGS = -no-undefined BUILT_SOURCES = $(ARGZ_H) include_HEADERS = $(am__append_1) noinst_LTLIBRARIES = $(LT_DLLOADERS) $(am__append_3) lib_LTLIBRARIES = $(am__append_2) EXTRA_LTLIBRARIES = dlopen.la dld_link.la dyld.la load_add_on.la \ loadlibrary.la shl_load.la EXTRA_DIST = lt__dirent.c lt__strl.c COPYING.LIB configure.ac \ Makefile.am aclocal.m4 Makefile.in configure config-h.in \ README argz_.h argz.c CLEANFILES = libltdl.la libltdlc.la libdlloader.la $(LIBOBJS) \ $(LTLIBOBJS) MOSTLYCLEANFILES = argz.h argz.h-t LTDL_VERSION_INFO = -version-info 9:0:2 @INSTALL_LTDL_TRUE@ltdlincludedir = $(includedir)/libltdl @INSTALL_LTDL_TRUE@ltdlinclude_HEADERS = libltdl/lt_system.h \ @INSTALL_LTDL_TRUE@ libltdl/lt_error.h \ @INSTALL_LTDL_TRUE@ libltdl/lt_dlloader.h libltdl_la_SOURCES = libltdl/lt__alloc.h \ libltdl/lt__dirent.h \ libltdl/lt__glibc.h \ libltdl/lt__private.h \ libltdl/lt__strl.h \ libltdl/lt_dlloader.h \ libltdl/lt_error.h \ libltdl/lt_system.h \ libltdl/slist.h \ loaders/preopen.c \ lt__alloc.c \ lt_dlloader.c \ lt_error.c \ ltdl.c \ ltdl.h \ slist.c libltdl_la_CPPFLAGS = -DLTDLOPEN=$(LTDLOPEN) $(AM_CPPFLAGS) libltdl_la_LDFLAGS = $(AM_LDFLAGS) $(LTDL_VERSION_INFO) $(LT_DLPREOPEN) libltdl_la_LIBADD = $(LTLIBOBJS) libltdl_la_DEPENDENCIES = $(LT_DLLOADERS) $(LTLIBOBJS) libltdlc_la_SOURCES = $(libltdl_la_SOURCES) libltdlc_la_CPPFLAGS = -DLTDLOPEN=$(LTDLOPEN)c $(AM_CPPFLAGS) libltdlc_la_LDFLAGS = $(AM_LDFLAGS) $(LT_DLPREOPEN) libltdlc_la_LIBADD = $(libltdl_la_LIBADD) libltdlc_la_DEPENDENCIES = $(libltdl_la_DEPENDENCIES) dlopen_la_SOURCES = loaders/dlopen.c dlopen_la_LDFLAGS = -module -avoid-version dlopen_la_LIBADD = $(LIBADD_DLOPEN) dld_link_la_SOURCES = loaders/dld_link.c dld_link_la_LDFLAGS = -module -avoid-version dld_link_la_LIBADD = -ldld dyld_la_SOURCES = loaders/dyld.c dyld_la_LDFLAGS = -module -avoid-version load_add_on_la_SOURCES = loaders/load_add_on.c load_add_on_la_LDFLAGS = -module -avoid-version loadlibrary_la_SOURCES = loaders/loadlibrary.c loadlibrary_la_LDFLAGS = -module -avoid-version shl_load_la_SOURCES = loaders/shl_load.c shl_load_la_LDFLAGS = -module -avoid-version shl_load_la_LIBADD = $(LIBADD_SHL_LOAD) all: $(BUILT_SOURCES) config.h $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj am--refresh: @: .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps) config.h: stamp-h1 @if test ! -f $@; then \ rm -f stamp-h1; \ $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ else :; fi stamp-h1: $(srcdir)/config-h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config-h.in: $(am__configure_deps) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ f=$(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ else :; fi; \ done uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ p=$(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done dld_link.la: $(dld_link_la_OBJECTS) $(dld_link_la_DEPENDENCIES) $(dld_link_la_LINK) $(dld_link_la_OBJECTS) $(dld_link_la_LIBADD) $(LIBS) dlopen.la: $(dlopen_la_OBJECTS) $(dlopen_la_DEPENDENCIES) $(dlopen_la_LINK) $(dlopen_la_OBJECTS) $(dlopen_la_LIBADD) $(LIBS) dyld.la: $(dyld_la_OBJECTS) $(dyld_la_DEPENDENCIES) $(dyld_la_LINK) $(dyld_la_OBJECTS) $(dyld_la_LIBADD) $(LIBS) libltdl.la: $(libltdl_la_OBJECTS) $(libltdl_la_DEPENDENCIES) $(libltdl_la_LINK) $(am_libltdl_la_rpath) $(libltdl_la_OBJECTS) $(libltdl_la_LIBADD) $(LIBS) libltdlc.la: $(libltdlc_la_OBJECTS) $(libltdlc_la_DEPENDENCIES) $(libltdlc_la_LINK) $(am_libltdlc_la_rpath) $(libltdlc_la_OBJECTS) $(libltdlc_la_LIBADD) $(LIBS) load_add_on.la: $(load_add_on_la_OBJECTS) $(load_add_on_la_DEPENDENCIES) $(load_add_on_la_LINK) $(load_add_on_la_OBJECTS) $(load_add_on_la_LIBADD) $(LIBS) loadlibrary.la: $(loadlibrary_la_OBJECTS) $(loadlibrary_la_DEPENDENCIES) $(loadlibrary_la_LINK) $(loadlibrary_la_OBJECTS) $(loadlibrary_la_LIBADD) $(LIBS) shl_load.la: $(shl_load_la_OBJECTS) $(shl_load_la_DEPENDENCIES) $(shl_load_la_LINK) $(shl_load_la_OBJECTS) $(shl_load_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/argz.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/lt__dirent.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/lt__strl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dld_link.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dlopen.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dyld.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libltdl_la-lt__alloc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libltdl_la-lt_dlloader.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libltdl_la-lt_error.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libltdl_la-ltdl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libltdl_la-preopen.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libltdl_la-slist.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libltdlc_la-lt__alloc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libltdlc_la-lt_dlloader.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libltdlc_la-lt_error.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libltdlc_la-ltdl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libltdlc_la-preopen.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libltdlc_la-slist.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/load_add_on.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loadlibrary.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shl_load.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< dld_link.lo: loaders/dld_link.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dld_link.lo -MD -MP -MF $(DEPDIR)/dld_link.Tpo -c -o dld_link.lo `test -f 'loaders/dld_link.c' || echo '$(srcdir)/'`loaders/dld_link.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/dld_link.Tpo $(DEPDIR)/dld_link.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='loaders/dld_link.c' object='dld_link.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dld_link.lo `test -f 'loaders/dld_link.c' || echo '$(srcdir)/'`loaders/dld_link.c dlopen.lo: loaders/dlopen.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dlopen.lo -MD -MP -MF $(DEPDIR)/dlopen.Tpo -c -o dlopen.lo `test -f 'loaders/dlopen.c' || echo '$(srcdir)/'`loaders/dlopen.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/dlopen.Tpo $(DEPDIR)/dlopen.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='loaders/dlopen.c' object='dlopen.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dlopen.lo `test -f 'loaders/dlopen.c' || echo '$(srcdir)/'`loaders/dlopen.c dyld.lo: loaders/dyld.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dyld.lo -MD -MP -MF $(DEPDIR)/dyld.Tpo -c -o dyld.lo `test -f 'loaders/dyld.c' || echo '$(srcdir)/'`loaders/dyld.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/dyld.Tpo $(DEPDIR)/dyld.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='loaders/dyld.c' object='dyld.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dyld.lo `test -f 'loaders/dyld.c' || echo '$(srcdir)/'`loaders/dyld.c libltdl_la-preopen.lo: loaders/preopen.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libltdl_la-preopen.lo -MD -MP -MF $(DEPDIR)/libltdl_la-preopen.Tpo -c -o libltdl_la-preopen.lo `test -f 'loaders/preopen.c' || echo '$(srcdir)/'`loaders/preopen.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libltdl_la-preopen.Tpo $(DEPDIR)/libltdl_la-preopen.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='loaders/preopen.c' object='libltdl_la-preopen.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libltdl_la-preopen.lo `test -f 'loaders/preopen.c' || echo '$(srcdir)/'`loaders/preopen.c libltdl_la-lt__alloc.lo: lt__alloc.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libltdl_la-lt__alloc.lo -MD -MP -MF $(DEPDIR)/libltdl_la-lt__alloc.Tpo -c -o libltdl_la-lt__alloc.lo `test -f 'lt__alloc.c' || echo '$(srcdir)/'`lt__alloc.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libltdl_la-lt__alloc.Tpo $(DEPDIR)/libltdl_la-lt__alloc.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='lt__alloc.c' object='libltdl_la-lt__alloc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libltdl_la-lt__alloc.lo `test -f 'lt__alloc.c' || echo '$(srcdir)/'`lt__alloc.c libltdl_la-lt_dlloader.lo: lt_dlloader.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libltdl_la-lt_dlloader.lo -MD -MP -MF $(DEPDIR)/libltdl_la-lt_dlloader.Tpo -c -o libltdl_la-lt_dlloader.lo `test -f 'lt_dlloader.c' || echo '$(srcdir)/'`lt_dlloader.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libltdl_la-lt_dlloader.Tpo $(DEPDIR)/libltdl_la-lt_dlloader.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='lt_dlloader.c' object='libltdl_la-lt_dlloader.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libltdl_la-lt_dlloader.lo `test -f 'lt_dlloader.c' || echo '$(srcdir)/'`lt_dlloader.c libltdl_la-lt_error.lo: lt_error.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libltdl_la-lt_error.lo -MD -MP -MF $(DEPDIR)/libltdl_la-lt_error.Tpo -c -o libltdl_la-lt_error.lo `test -f 'lt_error.c' || echo '$(srcdir)/'`lt_error.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libltdl_la-lt_error.Tpo $(DEPDIR)/libltdl_la-lt_error.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='lt_error.c' object='libltdl_la-lt_error.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libltdl_la-lt_error.lo `test -f 'lt_error.c' || echo '$(srcdir)/'`lt_error.c libltdl_la-ltdl.lo: ltdl.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libltdl_la-ltdl.lo -MD -MP -MF $(DEPDIR)/libltdl_la-ltdl.Tpo -c -o libltdl_la-ltdl.lo `test -f 'ltdl.c' || echo '$(srcdir)/'`ltdl.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libltdl_la-ltdl.Tpo $(DEPDIR)/libltdl_la-ltdl.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ltdl.c' object='libltdl_la-ltdl.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libltdl_la-ltdl.lo `test -f 'ltdl.c' || echo '$(srcdir)/'`ltdl.c libltdl_la-slist.lo: slist.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libltdl_la-slist.lo -MD -MP -MF $(DEPDIR)/libltdl_la-slist.Tpo -c -o libltdl_la-slist.lo `test -f 'slist.c' || echo '$(srcdir)/'`slist.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libltdl_la-slist.Tpo $(DEPDIR)/libltdl_la-slist.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='slist.c' object='libltdl_la-slist.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libltdl_la-slist.lo `test -f 'slist.c' || echo '$(srcdir)/'`slist.c libltdlc_la-preopen.lo: loaders/preopen.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdlc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libltdlc_la-preopen.lo -MD -MP -MF $(DEPDIR)/libltdlc_la-preopen.Tpo -c -o libltdlc_la-preopen.lo `test -f 'loaders/preopen.c' || echo '$(srcdir)/'`loaders/preopen.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libltdlc_la-preopen.Tpo $(DEPDIR)/libltdlc_la-preopen.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='loaders/preopen.c' object='libltdlc_la-preopen.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdlc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libltdlc_la-preopen.lo `test -f 'loaders/preopen.c' || echo '$(srcdir)/'`loaders/preopen.c libltdlc_la-lt__alloc.lo: lt__alloc.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdlc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libltdlc_la-lt__alloc.lo -MD -MP -MF $(DEPDIR)/libltdlc_la-lt__alloc.Tpo -c -o libltdlc_la-lt__alloc.lo `test -f 'lt__alloc.c' || echo '$(srcdir)/'`lt__alloc.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libltdlc_la-lt__alloc.Tpo $(DEPDIR)/libltdlc_la-lt__alloc.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='lt__alloc.c' object='libltdlc_la-lt__alloc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdlc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libltdlc_la-lt__alloc.lo `test -f 'lt__alloc.c' || echo '$(srcdir)/'`lt__alloc.c libltdlc_la-lt_dlloader.lo: lt_dlloader.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdlc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libltdlc_la-lt_dlloader.lo -MD -MP -MF $(DEPDIR)/libltdlc_la-lt_dlloader.Tpo -c -o libltdlc_la-lt_dlloader.lo `test -f 'lt_dlloader.c' || echo '$(srcdir)/'`lt_dlloader.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libltdlc_la-lt_dlloader.Tpo $(DEPDIR)/libltdlc_la-lt_dlloader.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='lt_dlloader.c' object='libltdlc_la-lt_dlloader.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdlc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libltdlc_la-lt_dlloader.lo `test -f 'lt_dlloader.c' || echo '$(srcdir)/'`lt_dlloader.c libltdlc_la-lt_error.lo: lt_error.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdlc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libltdlc_la-lt_error.lo -MD -MP -MF $(DEPDIR)/libltdlc_la-lt_error.Tpo -c -o libltdlc_la-lt_error.lo `test -f 'lt_error.c' || echo '$(srcdir)/'`lt_error.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libltdlc_la-lt_error.Tpo $(DEPDIR)/libltdlc_la-lt_error.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='lt_error.c' object='libltdlc_la-lt_error.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdlc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libltdlc_la-lt_error.lo `test -f 'lt_error.c' || echo '$(srcdir)/'`lt_error.c libltdlc_la-ltdl.lo: ltdl.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdlc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libltdlc_la-ltdl.lo -MD -MP -MF $(DEPDIR)/libltdlc_la-ltdl.Tpo -c -o libltdlc_la-ltdl.lo `test -f 'ltdl.c' || echo '$(srcdir)/'`ltdl.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libltdlc_la-ltdl.Tpo $(DEPDIR)/libltdlc_la-ltdl.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ltdl.c' object='libltdlc_la-ltdl.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdlc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libltdlc_la-ltdl.lo `test -f 'ltdl.c' || echo '$(srcdir)/'`ltdl.c libltdlc_la-slist.lo: slist.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdlc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libltdlc_la-slist.lo -MD -MP -MF $(DEPDIR)/libltdlc_la-slist.Tpo -c -o libltdlc_la-slist.lo `test -f 'slist.c' || echo '$(srcdir)/'`slist.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libltdlc_la-slist.Tpo $(DEPDIR)/libltdlc_la-slist.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='slist.c' object='libltdlc_la-slist.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdlc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libltdlc_la-slist.lo `test -f 'slist.c' || echo '$(srcdir)/'`slist.c load_add_on.lo: loaders/load_add_on.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT load_add_on.lo -MD -MP -MF $(DEPDIR)/load_add_on.Tpo -c -o load_add_on.lo `test -f 'loaders/load_add_on.c' || echo '$(srcdir)/'`loaders/load_add_on.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/load_add_on.Tpo $(DEPDIR)/load_add_on.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='loaders/load_add_on.c' object='load_add_on.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o load_add_on.lo `test -f 'loaders/load_add_on.c' || echo '$(srcdir)/'`loaders/load_add_on.c loadlibrary.lo: loaders/loadlibrary.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT loadlibrary.lo -MD -MP -MF $(DEPDIR)/loadlibrary.Tpo -c -o loadlibrary.lo `test -f 'loaders/loadlibrary.c' || echo '$(srcdir)/'`loaders/loadlibrary.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/loadlibrary.Tpo $(DEPDIR)/loadlibrary.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='loaders/loadlibrary.c' object='loadlibrary.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o loadlibrary.lo `test -f 'loaders/loadlibrary.c' || echo '$(srcdir)/'`loaders/loadlibrary.c shl_load.lo: loaders/shl_load.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shl_load.lo -MD -MP -MF $(DEPDIR)/shl_load.Tpo -c -o shl_load.lo `test -f 'loaders/shl_load.c' || echo '$(srcdir)/'`loaders/shl_load.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/shl_load.Tpo $(DEPDIR)/shl_load.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='loaders/shl_load.c' object='shl_load.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shl_load.lo `test -f 'loaders/shl_load.c' || echo '$(srcdir)/'`loaders/shl_load.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool install-includeHEADERS: $(include_HEADERS) @$(NORMAL_INSTALL) test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)" @list='$(include_HEADERS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f=$(am__strip_dir) \ echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \ $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \ done uninstall-includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_HEADERS)'; for p in $$list; do \ f=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \ rm -f "$(DESTDIR)$(includedir)/$$f"; \ done install-ltdlincludeHEADERS: $(ltdlinclude_HEADERS) @$(NORMAL_INSTALL) test -z "$(ltdlincludedir)" || $(MKDIR_P) "$(DESTDIR)$(ltdlincludedir)" @list='$(ltdlinclude_HEADERS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f=$(am__strip_dir) \ echo " $(ltdlincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(ltdlincludedir)/$$f'"; \ $(ltdlincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(ltdlincludedir)/$$f"; \ done uninstall-ltdlincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(ltdlinclude_HEADERS)'; for p in $$list; do \ f=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(ltdlincludedir)/$$f'"; \ rm -f "$(DESTDIR)$(ltdlincludedir)/$$f"; \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) config-h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) config-h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) config-h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) config-h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) $(am__remove_distdir) test -d $(distdir) || mkdir $(distdir) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r $(distdir) dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-lzma: distdir tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma $(am__remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lzma*) \ unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && cd $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @cd $(distuninstallcheck_dir) \ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) config.h installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" "$(DESTDIR)$(ltdlincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ clean-noinstLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(DEPDIR) ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-libtool distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-includeHEADERS install-ltdlincludeHEADERS install-dvi: install-dvi-am install-exec-am: install-libLTLIBRARIES install-html: install-html-am install-info: install-info-am install-man: install-pdf: install-pdf-am install-ps: install-ps-am installcheck-am: maintainer-clean: maintainer-clean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -rf $(DEPDIR) ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES \ uninstall-ltdlincludeHEADERS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am am--refresh check check-am clean \ clean-generic clean-libLTLIBRARIES clean-libtool \ clean-noinstLTLIBRARIES ctags dist dist-all dist-bzip2 \ dist-gzip dist-lzma dist-shar dist-tarZ dist-zip distcheck \ distclean distclean-compile distclean-generic distclean-hdr \ distclean-libtool distclean-tags distcleancheck distdir \ distuninstallcheck dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-includeHEADERS install-info \ install-info-am install-libLTLIBRARIES \ install-ltdlincludeHEADERS install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am uninstall-includeHEADERS \ uninstall-libLTLIBRARIES uninstall-ltdlincludeHEADERS # We need the following in order to create an when the system # doesn't have one that works with the given compiler. all-local $(lib_OBJECTS): $(ARGZ_H) argz.h: argz_.h $(mkinstalldirs) . cp $(srcdir)/argz_.h $@-t mv $@-t $@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: proftpd-dfsg-1.3.5~rc3/lib/libltdl/lt_error.c0000644000175000017500000000562111300565264020743 0ustar frankiefrankie/* lt_error.c -- error propogation interface Copyright (C) 1999, 2000, 2001, 2004, 2005, 2007 Free Software Foundation, Inc. Written by Thomas Tanner, 1999 NOTE: The canonical source of this file is maintained with the GNU Libtool package. Report bugs to bug-libtool@gnu.org. GNU Libltdl is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exception to the GNU Lesser General Public License, if you distribute this file as part of a program or library that is built using GNU Libtool, you may include this file under the same distribution terms that you use for the rest of that program. GNU Libltdl is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with GNU Libltdl; see the file COPYING.LIB. If not, a copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, or obtained by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "lt__private.h" #include "lt_error.h" static const char *last_error = 0; static const char error_strings[LT_ERROR_MAX][LT_ERROR_LEN_MAX + 1] = { #define LT_ERROR(name, diagnostic) diagnostic, lt_dlerror_table #undef LT_ERROR }; static const char **user_error_strings = 0; static int errorcount = LT_ERROR_MAX; int lt_dladderror (const char *diagnostic) { int errindex = 0; int result = -1; const char **temp = (const char **) 0; assert (diagnostic); errindex = errorcount - LT_ERROR_MAX; temp = REALLOC (const char *, user_error_strings, 1 + errindex); if (temp) { user_error_strings = temp; user_error_strings[errindex] = diagnostic; result = errorcount++; } return result; } int lt_dlseterror (int errindex) { int errors = 0; if (errindex >= errorcount || errindex < 0) { /* Ack! Error setting the error message! */ LT__SETERROR (INVALID_ERRORCODE); ++errors; } else if (errindex < LT_ERROR_MAX) { /* No error setting the error message! */ LT__SETERRORSTR (error_strings[errindex]); } else { /* No error setting the error message! */ LT__SETERRORSTR (user_error_strings[errindex - LT_ERROR_MAX]); } return errors; } const char * lt__error_string (int errorcode) { assert (errorcode >= 0); assert (errorcode < LT_ERROR_MAX); return error_strings[errorcode]; } const char * lt__get_last_error (void) { return last_error; } const char * lt__set_last_error (const char *errormsg) { return last_error = errormsg; } proftpd-dfsg-1.3.5~rc3/lib/libltdl/config-h.in0000644000175000017500000001073611300565263020773 0ustar frankiefrankie/* config-h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if you have the `argz_add' function. */ #undef HAVE_ARGZ_ADD /* Define to 1 if you have the `argz_append' function. */ #undef HAVE_ARGZ_APPEND /* Define to 1 if you have the `argz_count' function. */ #undef HAVE_ARGZ_COUNT /* Define to 1 if you have the `argz_create_sep' function. */ #undef HAVE_ARGZ_CREATE_SEP /* Define to 1 if you have the header file. */ #undef HAVE_ARGZ_H /* Define to 1 if you have the `argz_insert' function. */ #undef HAVE_ARGZ_INSERT /* Define to 1 if you have the `argz_next' function. */ #undef HAVE_ARGZ_NEXT /* Define to 1 if you have the `argz_stringify' function. */ #undef HAVE_ARGZ_STRINGIFY /* Define to 1 if you have the `closedir' function. */ #undef HAVE_CLOSEDIR /* Define to 1 if you have the declaration of `cygwin_conv_path', and to 0 if you don't. */ #undef HAVE_DECL_CYGWIN_CONV_PATH /* Define to 1 if you have the header file. */ #undef HAVE_DIRENT_H /* Define if you have the GNU dld library. */ #undef HAVE_DLD /* Define to 1 if you have the header file. */ #undef HAVE_DLD_H /* Define to 1 if you have the `dlerror' function. */ #undef HAVE_DLERROR /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the header file. */ #undef HAVE_DL_H /* Define if you have the _dyld_func_lookup function. */ #undef HAVE_DYLD /* Define to 1 if the system has the type `error_t'. */ #undef HAVE_ERROR_T /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define if you have the libdl library or equivalent. */ #undef HAVE_LIBDL /* Define if libdlloader will be built on this platform */ #undef HAVE_LIBDLLOADER /* Define to 1 if you have the header file. */ #undef HAVE_MACH_O_DYLD_H /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `opendir' function. */ #undef HAVE_OPENDIR /* Define if libtool can extract symbol lists from object files. */ #undef HAVE_PRELOADED_SYMBOLS /* Define to 1 if you have the `readdir' function. */ #undef HAVE_READDIR /* Define if you have the shl_load function. */ #undef HAVE_SHL_LOAD /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the `strlcat' function. */ #undef HAVE_STRLCAT /* Define to 1 if you have the `strlcpy' function. */ #undef HAVE_STRLCPY /* Define to 1 if you have the header file. */ #undef HAVE_SYS_DL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* This value is set to 1 to indicate that the system argz facility works */ #undef HAVE_WORKING_ARGZ /* Define if the OS needs help to load dependent libraries for dlopen(). */ #undef LTDL_DLOPEN_DEPLIBS /* Define to the system default library search path. */ #undef LT_DLSEARCH_PATH /* The archive extension */ #undef LT_LIBEXT /* Define to the extension used for runtime loadable modules, say, ".so". */ #undef LT_MODULE_EXT /* Define to the name of the environment variable that determines the run-time module search path. */ #undef LT_MODULE_PATH_VAR /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Define if dlsym() requires a leading underscore in symbol names. */ #undef NEED_USCORE /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Version number of package */ #undef VERSION /* Define so that glibc/gnulib argp.h does not typedef error_t. */ #undef __error_t_defined /* Define to a type to use for `error_t' if it is not otherwise available. */ #undef error_t proftpd-dfsg-1.3.5~rc3/lib/libltdl/ltdl.c0000644000175000017500000015127111300567642020057 0ustar frankiefrankie/* ltdl.c -- system independent dlopen wrapper Copyright (C) 1998, 1999, 2000, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. Written by Thomas Tanner, 1998 NOTE: The canonical source of this file is maintained with the GNU Libtool package. Report bugs to bug-libtool@gnu.org. GNU Libltdl is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exception to the GNU Lesser General Public License, if you distribute this file as part of a program or library that is built using GNU Libtool, you may include this file under the same distribution terms that you use for the rest of that program. GNU Libltdl is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with GNU Libltdl; see the file COPYING.LIB. If not, a copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, or obtained by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "lt__private.h" #include "lt_system.h" #include "lt_dlloader.h" /* --- MANIFEST CONSTANTS --- */ /* Standard libltdl search path environment variable name */ #undef LTDL_SEARCHPATH_VAR #define LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH" /* Standard libtool archive file extension. */ #undef LT_ARCHIVE_EXT #define LT_ARCHIVE_EXT ".la" /* max. filename length */ #if !defined(LT_FILENAME_MAX) # define LT_FILENAME_MAX 1024 #endif #if !defined(LT_LIBEXT) # define LT_LIBEXT "a" #endif /* This is the maximum symbol size that won't require malloc/free */ #undef LT_SYMBOL_LENGTH #define LT_SYMBOL_LENGTH 128 /* This accounts for the _LTX_ separator */ #undef LT_SYMBOL_OVERHEAD #define LT_SYMBOL_OVERHEAD 5 /* Various boolean flags can be stored in the flags field of an lt_dlhandle... */ #define LT_DLIS_RESIDENT(handle) ((handle)->info.is_resident) #define LT_DLIS_SYMGLOBAL(handle) ((handle)->info.is_symglobal) #define LT_DLIS_SYMLOCAL(handle) ((handle)->info.is_symlocal) static const char objdir[] = LT_OBJDIR; static const char archive_ext[] = LT_ARCHIVE_EXT; static const char libext[] = LT_LIBEXT; #if defined(LT_MODULE_EXT) static const char shlib_ext[] = LT_MODULE_EXT; #endif #if defined(LT_DLSEARCH_PATH) static const char sys_dlsearch_path[] = LT_DLSEARCH_PATH; #endif /* --- DYNAMIC MODULE LOADING --- */ /* The type of a function used at each iteration of foreach_dirinpath(). */ typedef int foreach_callback_func (char *filename, void *data1, void *data2); /* foreachfile_callback itself calls a function of this type: */ typedef int file_worker_func (const char *filename, void *data); static int foreach_dirinpath (const char *search_path, const char *base_name, foreach_callback_func *func, void *data1, void *data2); static int find_file_callback (char *filename, void *data1, void *data2); static int find_handle_callback (char *filename, void *data, void *ignored); static int foreachfile_callback (char *filename, void *data1, void *data2); static int canonicalize_path (const char *path, char **pcanonical); static int argzize_path (const char *path, char **pargz, size_t *pargz_len); static FILE *find_file (const char *search_path, const char *base_name, char **pdir); static lt_dlhandle *find_handle (const char *search_path, const char *base_name, lt_dlhandle *handle, lt_dladvise advise); static int find_module (lt_dlhandle *handle, const char *dir, const char *libdir, const char *dlname, const char *old_name, int installed, lt_dladvise advise); static int has_library_ext (const char *filename); static int load_deplibs (lt_dlhandle handle, char *deplibs); static int trim (char **dest, const char *str); static int try_dlopen (lt_dlhandle *handle, const char *filename, const char *ext, lt_dladvise advise); static int tryall_dlopen (lt_dlhandle *handle, const char *filename, lt_dladvise padvise, const lt_dlvtable *vtable); static int unload_deplibs (lt_dlhandle handle); static int lt_argz_insert (char **pargz, size_t *pargz_len, char *before, const char *entry); static int lt_argz_insertinorder (char **pargz, size_t *pargz_len, const char *entry); static int lt_argz_insertdir (char **pargz, size_t *pargz_len, const char *dirnam, struct dirent *dp); static int lt_dlpath_insertdir (char **ppath, char *before, const char *dir); static int list_files_by_dir (const char *dirnam, char **pargz, size_t *pargz_len); static int file_not_found (void); #ifdef HAVE_LIBDLLOADER static int loader_init_callback (lt_dlhandle handle); #endif /* HAVE_LIBDLLOADER */ static int loader_init (lt_get_vtable *vtable_func, lt_user_data data); static char *user_search_path= 0; static lt_dlhandle handles = 0; static int initialized = 0; /* Our memory failure callback sets the error message to be passed back up to the client, so we must be careful to return from mallocation callers if allocation fails (as this callback returns!!). */ void lt__alloc_die_callback (void) { LT__SETERROR (NO_MEMORY); } #ifdef HAVE_LIBDLLOADER /* This function is called to initialise each preloaded module loader, and hook it into the list of loaders to be used when attempting to dlopen an application module. */ static int loader_init_callback (lt_dlhandle handle) { lt_get_vtable *vtable_func = (lt_get_vtable *) lt_dlsym (handle, "get_vtable"); return loader_init (vtable_func, 0); } #endif /* HAVE_LIBDLLOADER */ static int loader_init (lt_get_vtable *vtable_func, lt_user_data data) { const lt_dlvtable *vtable = 0; int errors = 0; if (vtable_func) { vtable = (*vtable_func) (data); } /* lt_dlloader_add will LT__SETERROR if it fails. */ errors += lt_dlloader_add (vtable); assert (errors || vtable); if ((!errors) && vtable->dlloader_init) { if ((*vtable->dlloader_init) (vtable->dlloader_data)) { LT__SETERROR (INIT_LOADER); ++errors; } } return errors; } /* Bootstrap the loader loading with the preopening loader. */ #define get_vtable preopen_LTX_get_vtable #define preloaded_symbols LT_CONC3(lt_, LTDLOPEN, _LTX_preloaded_symbols) LT_BEGIN_C_DECLS LT_SCOPE const lt_dlvtable * get_vtable (lt_user_data data); LT_END_C_DECLS #ifdef HAVE_LIBDLLOADER extern lt_dlsymlist preloaded_symbols; #endif /* Initialize libltdl. */ int lt_dlinit (void) { int errors = 0; /* Initialize only at first call. */ if (++initialized == 1) { lt__alloc_die = lt__alloc_die_callback; handles = 0; user_search_path = 0; /* empty search path */ /* First set up the statically loaded preload module loader, so we can use it to preopen the other loaders we linked in at compile time. */ errors += loader_init (get_vtable, 0); /* Now open all the preloaded module loaders, so the application can use _them_ to lt_dlopen its own modules. */ #ifdef HAVE_LIBDLLOADER if (!errors) { errors += lt_dlpreload (&preloaded_symbols); } if (!errors) { errors += lt_dlpreload_open (LT_STR(LTDLOPEN), loader_init_callback); } #endif /* HAVE_LIBDLLOADER */ } #ifdef LT_DEBUG_LOADERS lt_dlloader_dump(); #endif return errors; } int lt_dlexit (void) { /* shut down libltdl */ lt_dlloader *loader = 0; lt_dlhandle handle = handles; int errors = 0; if (!initialized) { LT__SETERROR (SHUTDOWN); ++errors; goto done; } /* shut down only at last call. */ if (--initialized == 0) { int level; while (handles && LT_DLIS_RESIDENT (handles)) { handles = handles->next; } /* close all modules */ for (level = 1; handle; ++level) { lt_dlhandle cur = handles; int saw_nonresident = 0; while (cur) { lt_dlhandle tmp = cur; cur = cur->next; if (!LT_DLIS_RESIDENT (tmp)) { saw_nonresident = 1; if (tmp->info.ref_count <= level) { if (lt_dlclose (tmp)) { ++errors; } /* Make sure that the handle pointed to by 'cur' still exists. lt_dlclose recursively closes dependent libraries which removes them from the linked list. One of these might be the one pointed to by 'cur'. */ if (cur) { for (tmp = handles; tmp; tmp = tmp->next) if (tmp == cur) break; if (! tmp) cur = handles; } } } } /* done if only resident modules are left */ if (!saw_nonresident) break; } /* When removing loaders, we can only find out failure by testing the error string, so avoid a spurious one from an earlier failed command. */ if (!errors) LT__SETERRORSTR (0); /* close all loaders */ for (loader = (lt_dlloader *) lt_dlloader_next (NULL); loader;) { lt_dlloader *next = (lt_dlloader *) lt_dlloader_next (loader); lt_dlvtable *vtable = (lt_dlvtable *) lt_dlloader_get (loader); if ((vtable = lt_dlloader_remove ((char *) vtable->name))) { FREE (vtable); } else { /* ignore errors due to resident modules */ const char *err; LT__GETERROR (err); if (err) ++errors; } loader = next; } FREE(user_search_path); } done: return errors; } /* Try VTABLE or, if VTABLE is NULL, all available loaders for FILENAME. If the library is not successfully loaded, return non-zero. Otherwise, the dlhandle is stored at the address given in PHANDLE. */ static int tryall_dlopen (lt_dlhandle *phandle, const char *filename, lt_dladvise advise, const lt_dlvtable *vtable) { lt_dlhandle handle = handles; const char * saved_error = 0; int errors = 0; #ifdef LT_DEBUG_LOADERS fprintf (stderr, "tryall_dlopen (%s, %s)\n", filename ? filename : "(null)", vtable ? vtable->name : "(ALL)"); #endif LT__GETERROR (saved_error); /* check whether the module was already opened */ for (;handle; handle = handle->next) { if ((handle->info.filename == filename) /* dlopen self: 0 == 0 */ || (handle->info.filename && filename && streq (handle->info.filename, filename))) { break; } } if (handle) { ++handle->info.ref_count; *phandle = handle; goto done; } handle = *phandle; if (filename) { /* Comment out the check of file permissions using access. This call seems to always return -1 with error EACCES. */ /* We need to catch missing file errors early so that file_not_found() can detect what happened. if (access (filename, R_OK) != 0) { LT__SETERROR (FILE_NOT_FOUND); ++errors; goto done; } */ handle->info.filename = lt__strdup (filename); if (!handle->info.filename) { ++errors; goto done; } } else { handle->info.filename = 0; } { lt_dlloader loader = lt_dlloader_next (0); const lt_dlvtable *loader_vtable; do { if (vtable) loader_vtable = vtable; else loader_vtable = lt_dlloader_get (loader); #ifdef LT_DEBUG_LOADERS fprintf (stderr, "Calling %s->module_open (%s)\n", (loader_vtable && loader_vtable->name) ? loader_vtable->name : "(null)", filename ? filename : "(null)"); #endif handle->module = (*loader_vtable->module_open) (loader_vtable->dlloader_data, filename, advise); #ifdef LT_DEBUG_LOADERS fprintf (stderr, " Result: %s\n", handle->module ? "Success" : "Failed"); #endif if (handle->module != 0) { if (advise) { handle->info.is_resident = advise->is_resident; handle->info.is_symglobal = advise->is_symglobal; handle->info.is_symlocal = advise->is_symlocal; } break; } } while (!vtable && (loader = lt_dlloader_next (loader))); /* If VTABLE was given but couldn't open the module, or VTABLE wasn't given but we exhausted all loaders without opening the module, bail out! */ if ((vtable && !handle->module) || (!vtable && !loader)) { FREE (handle->info.filename); ++errors; goto done; } handle->vtable = loader_vtable; } LT__SETERRORSTR (saved_error); done: return errors; } static int tryall_dlopen_module (lt_dlhandle *handle, const char *prefix, const char *dirname, const char *dlname, lt_dladvise advise) { int error = 0; char *filename = 0; size_t filename_len = 0; size_t dirname_len = LT_STRLEN (dirname); assert (handle); assert (dirname); assert (dlname); #if defined(LT_DIRSEP_CHAR) /* Only canonicalized names (i.e. with DIRSEP chars already converted) should make it into this function: */ assert (strchr (dirname, LT_DIRSEP_CHAR) == 0); #endif if (dirname_len > 0) if (dirname[dirname_len -1] == '/') --dirname_len; filename_len = dirname_len + 1 + LT_STRLEN (dlname); /* Allocate memory, and combine DIRNAME and MODULENAME into it. The PREFIX (if any) is handled below. */ filename = MALLOC (char, filename_len + 1); if (!filename) return 1; sprintf (filename, "%.*s/%s", (int) dirname_len, dirname, dlname); /* Now that we have combined DIRNAME and MODULENAME, if there is also a PREFIX to contend with, simply recurse with the arguments shuffled. Otherwise, attempt to open FILENAME as a module. */ if (prefix) { error += tryall_dlopen_module (handle, (const char *) 0, prefix, filename, advise); } else if (tryall_dlopen (handle, filename, advise, 0) != 0) { ++error; } FREE (filename); return error; } static int find_module (lt_dlhandle *handle, const char *dir, const char *libdir, const char *dlname, const char *old_name, int installed, lt_dladvise advise) { /* Try to open the old library first; if it was dlpreopened, we want the preopened version of it, even if a dlopenable module is available. */ if (old_name && tryall_dlopen (handle, old_name, advise, lt_dlloader_find ("lt_preopen") ) == 0) { return 0; } /* Try to open the dynamic library. */ if (dlname) { /* try to open the installed module */ if (installed && libdir) { if (tryall_dlopen_module (handle, (const char *) 0, libdir, dlname, advise) == 0) return 0; } /* try to open the not-installed module */ if (!installed) { if (tryall_dlopen_module (handle, dir, objdir, dlname, advise) == 0) return 0; } /* maybe it was moved to another directory */ { if (dir && (tryall_dlopen_module (handle, (const char *) 0, dir, dlname, advise) == 0)) return 0; } } return 1; } static int canonicalize_path (const char *path, char **pcanonical) { char *canonical = 0; assert (path && *path); assert (pcanonical); canonical = MALLOC (char, 1+ LT_STRLEN (path)); if (!canonical) return 1; { size_t dest = 0; size_t src; for (src = 0; path[src] != LT_EOS_CHAR; ++src) { /* Path separators are not copied to the beginning or end of the destination, or if another separator would follow immediately. */ if (path[src] == LT_PATHSEP_CHAR) { if ((dest == 0) || (path[1+ src] == LT_PATHSEP_CHAR) || (path[1+ src] == LT_EOS_CHAR)) continue; } /* Anything other than a directory separator is copied verbatim. */ if ((path[src] != '/') #if defined(LT_DIRSEP_CHAR) && (path[src] != LT_DIRSEP_CHAR) #endif ) { canonical[dest++] = path[src]; } /* Directory separators are converted and copied only if they are not at the end of a path -- i.e. before a path separator or NULL terminator. */ else if ((path[1+ src] != LT_PATHSEP_CHAR) && (path[1+ src] != LT_EOS_CHAR) #if defined(LT_DIRSEP_CHAR) && (path[1+ src] != LT_DIRSEP_CHAR) #endif && (path[1+ src] != '/')) { canonical[dest++] = '/'; } } /* Add an end-of-string marker at the end. */ canonical[dest] = LT_EOS_CHAR; } /* Assign new value. */ *pcanonical = canonical; return 0; } static int argzize_path (const char *path, char **pargz, size_t *pargz_len) { error_t error; assert (path); assert (pargz); assert (pargz_len); if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len))) { switch (error) { case ENOMEM: LT__SETERROR (NO_MEMORY); break; default: LT__SETERROR (UNKNOWN); break; } return 1; } return 0; } /* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns non-zero or all elements are exhausted. If BASE_NAME is non-NULL, it is appended to each SEARCH_PATH element before FUNC is called. */ static int foreach_dirinpath (const char *search_path, const char *base_name, foreach_callback_func *func, void *data1, void *data2) { int result = 0; size_t filenamesize = 0; size_t lenbase = LT_STRLEN (base_name); size_t argz_len = 0; char *argz = 0; char *filename = 0; char *canonical = 0; if (!search_path || !*search_path) { LT__SETERROR (FILE_NOT_FOUND); goto cleanup; } if (canonicalize_path (search_path, &canonical) != 0) goto cleanup; if (argzize_path (canonical, &argz, &argz_len) != 0) goto cleanup; { char *dir_name = 0; while ((dir_name = argz_next (argz, argz_len, dir_name))) { size_t lendir = LT_STRLEN (dir_name); if (1+ lendir + lenbase >= filenamesize) { FREE (filename); filenamesize = 1+ lendir + 1+ lenbase; /* "/d" + '/' + "f" + '\0' */ filename = MALLOC (char, filenamesize); if (!filename) goto cleanup; } assert (filenamesize > lendir); strcpy (filename, dir_name); if (base_name && *base_name) { if (filename[lendir -1] != '/') filename[lendir++] = '/'; strcpy (filename +lendir, base_name); } if ((result = (*func) (filename, data1, data2))) { break; } } } cleanup: FREE (argz); FREE (canonical); FREE (filename); return result; } /* If FILEPATH can be opened, store the name of the directory component in DATA1, and the opened FILE* structure address in DATA2. Otherwise DATA1 is unchanged, but DATA2 is set to a pointer to NULL. */ static int find_file_callback (char *filename, void *data1, void *data2) { char **pdir = (char **) data1; FILE **pfile = (FILE **) data2; int is_done = 0; assert (filename && *filename); assert (pdir); assert (pfile); if ((*pfile = fopen (filename, LT_READTEXT_MODE))) { char *dirend = strrchr (filename, '/'); if (dirend > filename) *dirend = LT_EOS_CHAR; FREE (*pdir); *pdir = lt__strdup (filename); is_done = (*pdir == 0) ? -1 : 1; } return is_done; } static FILE * find_file (const char *search_path, const char *base_name, char **pdir) { FILE *file = 0; foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file); return file; } static int find_handle_callback (char *filename, void *data, void *data2) { lt_dlhandle *phandle = (lt_dlhandle *) data; int notfound = access (filename, R_OK); lt_dladvise advise = (lt_dladvise) data2; /* Bail out if file cannot be read... */ if (notfound) return 0; /* Try to dlopen the file, but do not continue searching in any case. */ if (tryall_dlopen (phandle, filename, advise, 0) != 0) *phandle = 0; return 1; } /* If HANDLE was found return it, otherwise return 0. If HANDLE was found but could not be opened, *HANDLE will be set to 0. */ static lt_dlhandle * find_handle (const char *search_path, const char *base_name, lt_dlhandle *phandle, lt_dladvise advise) { if (!search_path) return 0; if (!foreach_dirinpath (search_path, base_name, find_handle_callback, phandle, advise)) return 0; return phandle; } #if !defined(LTDL_DLOPEN_DEPLIBS) static int load_deplibs (lt_dlhandle handle, char * LT__UNUSED deplibs) { handle->depcount = 0; return 0; } #else /* defined(LTDL_DLOPEN_DEPLIBS) */ static int load_deplibs (lt_dlhandle handle, char *deplibs) { char *p, *save_search_path = 0; int depcount = 0; int i; char **names = 0; int errors = 0; handle->depcount = 0; if (!deplibs) { return errors; } ++errors; if (user_search_path) { save_search_path = lt__strdup (user_search_path); if (!save_search_path) goto cleanup; } /* extract search paths and count deplibs */ p = deplibs; while (*p) { if (!isspace ((unsigned char) *p)) { char *end = p+1; while (*end && !isspace((unsigned char) *end)) { ++end; } if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0) { char save = *end; *end = 0; /* set a temporary string terminator */ if (lt_dladdsearchdir(p+2)) { goto cleanup; } *end = save; } else { ++depcount; } p = end; } else { ++p; } } if (!depcount) { errors = 0; goto cleanup; } names = MALLOC (char *, depcount); if (!names) goto cleanup; /* now only extract the actual deplibs */ depcount = 0; p = deplibs; while (*p) { if (isspace ((unsigned char) *p)) { ++p; } else { char *end = p+1; while (*end && !isspace ((unsigned char) *end)) { ++end; } if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0) { char *name; char save = *end; *end = 0; /* set a temporary string terminator */ if (strncmp(p, "-l", 2) == 0) { size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2); name = MALLOC (char, 1+ name_len); if (name) sprintf (name, "lib%s", p+2); } else name = lt__strdup(p); if (!name) goto cleanup_names; names[depcount++] = name; *end = save; } p = end; } } /* load the deplibs (in reverse order) At this stage, don't worry if the deplibs do not load correctly, they may already be statically linked into the loading application for instance. There will be a more enlightening error message later on if the loaded module cannot resolve all of its symbols. */ if (depcount) { lt_dlhandle cur = handle; int j = 0; cur->deplibs = MALLOC (lt_dlhandle, depcount); if (!cur->deplibs) goto cleanup_names; for (i = 0; i < depcount; ++i) { cur->deplibs[j] = lt_dlopenext(names[depcount-1-i]); if (cur->deplibs[j]) { ++j; } } cur->depcount = j; /* Number of successfully loaded deplibs */ errors = 0; } cleanup_names: for (i = 0; i < depcount; ++i) { FREE (names[i]); } cleanup: FREE (names); /* restore the old search path */ if (save_search_path) { MEMREASSIGN (user_search_path, save_search_path); } return errors; } #endif /* defined(LTDL_DLOPEN_DEPLIBS) */ static int unload_deplibs (lt_dlhandle handle) { int i; int errors = 0; lt_dlhandle cur = handle; if (cur->depcount) { for (i = 0; i < cur->depcount; ++i) { if (!LT_DLIS_RESIDENT (cur->deplibs[i])) { errors += lt_dlclose (cur->deplibs[i]); } } FREE (cur->deplibs); } return errors; } static int trim (char **dest, const char *str) { /* remove the leading and trailing "'" from str and store the result in dest */ const char *end = strrchr (str, '\''); size_t len = LT_STRLEN (str); char *tmp; FREE (*dest); if (!end) return 1; if (len > 3 && str[0] == '\'') { tmp = MALLOC (char, end - str); if (!tmp) return 1; memcpy(tmp, &str[1], (end - str) - 1); tmp[(end - str) - 1] = LT_EOS_CHAR; *dest = tmp; } else { *dest = 0; } return 0; } /* Read the .la file FILE. */ static int parse_dotla_file(FILE *file, char **dlname, char **libdir, char **deplibs, char **old_name, int *installed) { int errors = 0; size_t line_len = LT_FILENAME_MAX; char * line = MALLOC (char, line_len); if (!line) { LT__SETERROR (FILE_NOT_FOUND); return 1; } while (!feof (file)) { line[line_len-2] = '\0'; if (!fgets (line, (int) line_len, file)) { break; } /* Handle the case where we occasionally need to read a line that is longer than the initial buffer size. Behave even if the file contains NUL bytes due to corruption. */ while (line[line_len-2] != '\0' && line[line_len-2] != '\n' && !feof (file)) { line = REALLOC (char, line, line_len *2); if (!line) { ++errors; goto cleanup; } line[line_len * 2 - 2] = '\0'; if (!fgets (&line[line_len -1], (int) line_len +1, file)) { break; } line_len *= 2; } if (line[0] == '\n' || line[0] == '#') { continue; } #undef STR_DLNAME #define STR_DLNAME "dlname=" if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0) { errors += trim (dlname, &line[sizeof (STR_DLNAME) - 1]); } #undef STR_OLD_LIBRARY #define STR_OLD_LIBRARY "old_library=" else if (strncmp (line, STR_OLD_LIBRARY, sizeof (STR_OLD_LIBRARY) - 1) == 0) { errors += trim (old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]); } #undef STR_LIBDIR #define STR_LIBDIR "libdir=" else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0) { errors += trim (libdir, &line[sizeof(STR_LIBDIR) - 1]); } #undef STR_DL_DEPLIBS #define STR_DL_DEPLIBS "dependency_libs=" else if (strncmp (line, STR_DL_DEPLIBS, sizeof (STR_DL_DEPLIBS) - 1) == 0) { errors += trim (deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]); } else if (streq (line, "installed=yes\n")) { *installed = 1; } else if (streq (line, "installed=no\n")) { *installed = 0; } #undef STR_LIBRARY_NAMES #define STR_LIBRARY_NAMES "library_names=" else if (!*dlname && strncmp (line, STR_LIBRARY_NAMES, sizeof (STR_LIBRARY_NAMES) - 1) == 0) { char *last_libname; errors += trim (dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]); if (!errors && *dlname && (last_libname = strrchr (*dlname, ' ')) != 0) { last_libname = lt__strdup (last_libname + 1); if (!last_libname) { ++errors; goto cleanup; } MEMREASSIGN (*dlname, last_libname); } } if (errors) break; } cleanup: FREE (line); return errors; } /* Try to open FILENAME as a module. */ static int try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext, lt_dladvise advise) { const char * saved_error = 0; char * archive_name = 0; char * canonical = 0; char * base_name = 0; char * dir = 0; char * name = 0; char * attempt = 0; int errors = 0; lt_dlhandle newhandle; assert (phandle); assert (*phandle == 0); #ifdef LT_DEBUG_LOADERS fprintf (stderr, "try_dlopen (%s, %s)\n", filename ? filename : "(null)", ext ? ext : "(null)"); #endif LT__GETERROR (saved_error); /* dlopen self? */ if (!filename) { *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle)); if (*phandle == 0) return 1; newhandle = *phandle; /* lt_dlclose()ing yourself is very bad! Disallow it. */ newhandle->info.is_resident = 1; if (tryall_dlopen (&newhandle, 0, advise, 0) != 0) { FREE (*phandle); return 1; } goto register_handle; } assert (filename && *filename); if (ext) { attempt = MALLOC (char, LT_STRLEN (filename) + LT_STRLEN (ext) + 1); if (!attempt) return 1; sprintf(attempt, "%s%s", filename, ext); } else { attempt = lt__strdup (filename); if (!attempt) return 1; } /* Doing this immediately allows internal functions to safely assume only canonicalized paths are passed. */ if (canonicalize_path (attempt, &canonical) != 0) { ++errors; goto cleanup; } /* If the canonical module name is a path (relative or absolute) then split it into a directory part and a name part. */ base_name = strrchr (canonical, '/'); if (base_name) { size_t dirlen = (1+ base_name) - canonical; dir = MALLOC (char, 1+ dirlen); if (!dir) { ++errors; goto cleanup; } strncpy (dir, canonical, dirlen); dir[dirlen] = LT_EOS_CHAR; ++base_name; } else MEMREASSIGN (base_name, canonical); assert (base_name && *base_name); ext = strrchr (base_name, '.'); if (!ext) { ext = base_name + LT_STRLEN (base_name); } /* extract the module name from the file name */ name = MALLOC (char, ext - base_name + 1); if (!name) { ++errors; goto cleanup; } /* canonicalize the module name */ { int i; for (i = 0; i < ext - base_name; ++i) { if (isalnum ((unsigned char)(base_name[i]))) { name[i] = base_name[i]; } else { name[i] = '_'; } } name[ext - base_name] = LT_EOS_CHAR; } /* Before trawling through the filesystem in search of a module, check whether we are opening a preloaded module. */ if (!dir) { const lt_dlvtable *vtable = lt_dlloader_find ("lt_preopen"); if (vtable) { /* name + "." + libext + NULL */ archive_name = MALLOC (char, LT_STRLEN (name) + LT_STRLEN (libext) + 2); *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle)); if ((*phandle == NULL) || (archive_name == NULL)) { ++errors; goto cleanup; } newhandle = *phandle; /* Preloaded modules are always named according to their old archive name. */ sprintf (archive_name, "%s.%s", name, libext); if (tryall_dlopen (&newhandle, archive_name, advise, vtable) == 0) { goto register_handle; } /* If we're still here, there was no matching preloaded module, so put things back as we found them, and continue searching. */ FREE (*phandle); newhandle = NULL; } } /* If we are allowing only preloaded modules, and we didn't find anything yet, give up on the search here. */ if (advise && advise->try_preload_only) { goto cleanup; } /* Check whether we are opening a libtool module (.la extension). */ if (ext && streq (ext, archive_ext)) { /* this seems to be a libtool module */ FILE * file = 0; char * dlname = 0; char * old_name = 0; char * libdir = 0; char * deplibs = 0; /* if we can't find the installed flag, it is probably an installed libtool archive, produced with an old version of libtool */ int installed = 1; /* Now try to open the .la file. If there is no directory name component, try to find it first in user_search_path and then other prescribed paths. Otherwise (or in any case if the module was not yet found) try opening just the module name as passed. */ if (!dir) { const char *search_path = user_search_path; if (search_path) file = find_file (user_search_path, base_name, &dir); if (!file) { search_path = getenv (LTDL_SEARCHPATH_VAR); if (search_path) file = find_file (search_path, base_name, &dir); } #if defined(LT_MODULE_PATH_VAR) if (!file) { search_path = getenv (LT_MODULE_PATH_VAR); if (search_path) file = find_file (search_path, base_name, &dir); } #endif #if defined(LT_DLSEARCH_PATH) if (!file && *sys_dlsearch_path) { file = find_file (sys_dlsearch_path, base_name, &dir); } #endif } else { file = fopen (attempt, LT_READTEXT_MODE); } /* If we didn't find the file by now, it really isn't there. Set the status flag, and bail out. */ if (!file) { LT__SETERROR (FILE_NOT_FOUND); ++errors; goto cleanup; } /* read the .la file */ if (parse_dotla_file(file, &dlname, &libdir, &deplibs, &old_name, &installed) != 0) ++errors; fclose (file); /* allocate the handle */ *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle)); if (*phandle == 0) ++errors; if (errors) { FREE (dlname); FREE (old_name); FREE (libdir); FREE (deplibs); FREE (*phandle); goto cleanup; } assert (*phandle); if (load_deplibs (*phandle, deplibs) == 0) { newhandle = *phandle; /* find_module may replace newhandle */ if (find_module (&newhandle, dir, libdir, dlname, old_name, installed, advise)) { unload_deplibs (*phandle); ++errors; } } else { ++errors; } FREE (dlname); FREE (old_name); FREE (libdir); FREE (deplibs); if (errors) { FREE (*phandle); goto cleanup; } if (*phandle != newhandle) { unload_deplibs (*phandle); } } else { /* not a libtool module */ *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle)); if (*phandle == 0) { ++errors; goto cleanup; } newhandle = *phandle; /* If the module has no directory name component, try to find it first in user_search_path and then other prescribed paths. Otherwise (or in any case if the module was not yet found) try opening just the module name as passed. */ if ((dir || (!find_handle (user_search_path, base_name, &newhandle, advise) && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name, &newhandle, advise) #if defined(LT_MODULE_PATH_VAR) && !find_handle (getenv (LT_MODULE_PATH_VAR), base_name, &newhandle, advise) #endif #if defined(LT_DLSEARCH_PATH) && !find_handle (sys_dlsearch_path, base_name, &newhandle, advise) #endif ))) { if (tryall_dlopen (&newhandle, attempt, advise, 0) != 0) { newhandle = NULL; } } if (!newhandle) { FREE (*phandle); ++errors; goto cleanup; } } register_handle: MEMREASSIGN (*phandle, newhandle); if ((*phandle)->info.ref_count == 0) { (*phandle)->info.ref_count = 1; MEMREASSIGN ((*phandle)->info.name, name); (*phandle)->next = handles; handles = *phandle; } LT__SETERRORSTR (saved_error); cleanup: FREE (dir); FREE (attempt); FREE (name); if (!canonical) /* was MEMREASSIGNed */ FREE (base_name); FREE (canonical); FREE (archive_name); return errors; } /* If the last error messge store was `FILE_NOT_FOUND', then return non-zero. */ static int file_not_found (void) { const char *error = 0; LT__GETERROR (error); if (error == LT__STRERROR (FILE_NOT_FOUND)) return 1; return 0; } /* Unless FILENAME already bears a suitable library extension, then return 0. */ static int has_library_ext (const char *filename) { char * ext = 0; assert (filename); ext = strrchr (filename, '.'); if (ext && ((streq (ext, archive_ext)) #if defined(LT_MODULE_EXT) || (streq (ext, shlib_ext)) #endif )) { return 1; } return 0; } /* Initialise and configure a user lt_dladvise opaque object. */ int lt_dladvise_init (lt_dladvise *padvise) { lt_dladvise advise = (lt_dladvise) lt__zalloc (sizeof (struct lt__advise)); *padvise = advise; return (advise ? 0 : 1); } int lt_dladvise_destroy (lt_dladvise *padvise) { if (padvise) FREE(*padvise); return 0; } int lt_dladvise_ext (lt_dladvise *padvise) { assert (padvise && *padvise); (*padvise)->try_ext = 1; return 0; } int lt_dladvise_resident (lt_dladvise *padvise) { assert (padvise && *padvise); (*padvise)->is_resident = 1; return 0; } int lt_dladvise_local (lt_dladvise *padvise) { assert (padvise && *padvise); (*padvise)->is_symlocal = 1; return 0; } int lt_dladvise_global (lt_dladvise *padvise) { assert (padvise && *padvise); (*padvise)->is_symglobal = 1; return 0; } int lt_dladvise_preload (lt_dladvise *padvise) { assert (padvise && *padvise); (*padvise)->try_preload_only = 1; return 0; } /* Libtool-1.5.x interface for loading a new module named FILENAME. */ lt_dlhandle lt_dlopen (const char *filename) { return lt_dlopenadvise (filename, NULL); } /* If FILENAME has an ARCHIVE_EXT or MODULE_EXT extension, try to open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT, and if a file is still not found try again with MODULE_EXT appended instead. */ lt_dlhandle lt_dlopenext (const char *filename) { lt_dlhandle handle = 0; lt_dladvise advise; if (!lt_dladvise_init (&advise) && !lt_dladvise_ext (&advise)) handle = lt_dlopenadvise (filename, advise); lt_dladvise_destroy (&advise); return handle; } lt_dlhandle lt_dlopenadvise (const char *filename, lt_dladvise advise) { lt_dlhandle handle = 0; int errors = 0; /* Can't have symbols hidden and visible at the same time! */ if (advise && advise->is_symlocal && advise->is_symglobal) { LT__SETERROR (CONFLICTING_FLAGS); return 0; } if (!filename || !advise || !advise->try_ext || has_library_ext (filename)) { /* Just incase we missed a code path in try_dlopen() that reports an error, but forgot to reset handle... */ if (try_dlopen (&handle, filename, NULL, advise) != 0) return 0; return handle; } else if (filename && *filename) { /* First try appending ARCHIVE_EXT. */ errors += try_dlopen (&handle, filename, archive_ext, advise); /* If we found FILENAME, stop searching -- whether we were able to load the file as a module or not. If the file exists but loading failed, it is better to return an error message here than to report FILE_NOT_FOUND when the alternatives (foo.so etc) are not in the module search path. */ if (handle || ((errors > 0) && !file_not_found ())) return handle; #if defined(LT_MODULE_EXT) /* Try appending SHLIB_EXT. */ errors = try_dlopen (&handle, filename, shlib_ext, advise); /* As before, if the file was found but loading failed, return now with the current error message. */ if (handle || ((errors > 0) && !file_not_found ())) return handle; #endif } /* Still here? Then we really did fail to locate any of the file names we tried. */ LT__SETERROR (FILE_NOT_FOUND); return 0; } static int lt_argz_insert (char **pargz, size_t *pargz_len, char *before, const char *entry) { error_t error; /* Prior to Sep 8, 2005, newlib had a bug where argz_insert(pargz, pargz_len, NULL, entry) failed with EINVAL. */ if (before) error = argz_insert (pargz, pargz_len, before, entry); else error = argz_append (pargz, pargz_len, entry, 1 + strlen (entry)); if (error) { switch (error) { case ENOMEM: LT__SETERROR (NO_MEMORY); break; default: LT__SETERROR (UNKNOWN); break; } return 1; } return 0; } static int lt_argz_insertinorder (char **pargz, size_t *pargz_len, const char *entry) { char *before = 0; assert (pargz); assert (pargz_len); assert (entry && *entry); if (*pargz) while ((before = argz_next (*pargz, *pargz_len, before))) { int cmp = strcmp (entry, before); if (cmp < 0) break; if (cmp == 0) return 0; /* No duplicates! */ } return lt_argz_insert (pargz, pargz_len, before, entry); } static int lt_argz_insertdir (char **pargz, size_t *pargz_len, const char *dirnam, struct dirent *dp) { char *buf = 0; size_t buf_len = 0; char *end = 0; size_t end_offset = 0; size_t dir_len = 0; int errors = 0; assert (pargz); assert (pargz_len); assert (dp); dir_len = LT_STRLEN (dirnam); end = dp->d_name + D_NAMLEN(dp); /* Ignore version numbers. */ { char *p; for (p = end; p -1 > dp->d_name; --p) if (strchr (".0123456789", p[-1]) == 0) break; if (*p == '.') end = p; } /* Ignore filename extension. */ { char *p; for (p = end -1; p > dp->d_name; --p) if (*p == '.') { end = p; break; } } /* Prepend the directory name. */ end_offset = end - dp->d_name; buf_len = dir_len + 1+ end_offset; buf = MALLOC (char, 1+ buf_len); if (!buf) return ++errors; assert (buf); strcpy (buf, dirnam); strcat (buf, "/"); strncat (buf, dp->d_name, end_offset); buf[buf_len] = LT_EOS_CHAR; /* Try to insert (in order) into ARGZ/ARGZ_LEN. */ if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0) ++errors; FREE (buf); return errors; } static int list_files_by_dir (const char *dirnam, char **pargz, size_t *pargz_len) { DIR *dirp = 0; int errors = 0; assert (dirnam && *dirnam); assert (pargz); assert (pargz_len); assert (dirnam[LT_STRLEN(dirnam) -1] != '/'); dirp = opendir (dirnam); if (dirp) { struct dirent *dp = 0; while ((dp = readdir (dirp))) if (dp->d_name[0] != '.') if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp)) { ++errors; break; } closedir (dirp); } else ++errors; return errors; } /* If there are any files in DIRNAME, call the function passed in DATA1 (with the name of each file and DATA2 as arguments). */ static int foreachfile_callback (char *dirname, void *data1, void *data2) { file_worker_func *func = *(file_worker_func **) data1; int is_done = 0; char *argz = 0; size_t argz_len = 0; if (list_files_by_dir (dirname, &argz, &argz_len) != 0) goto cleanup; if (!argz) goto cleanup; { char *filename = 0; while ((filename = argz_next (argz, argz_len, filename))) if ((is_done = (*func) (filename, data2))) break; } cleanup: FREE (argz); return is_done; } /* Call FUNC for each unique extensionless file in SEARCH_PATH, along with DATA. The filenames passed to FUNC would be suitable for passing to lt_dlopenext. The extensions are stripped so that individual modules do not generate several entries (e.g. libfoo.la, libfoo.so, libfoo.so.1, libfoo.so.1.0.0). If SEARCH_PATH is NULL, then the same directories that lt_dlopen would search are examined. */ int lt_dlforeachfile (const char *search_path, int (*func) (const char *filename, void *data), void *data) { int is_done = 0; file_worker_func **fpptr = &func; if (search_path) { /* If a specific path was passed, search only the directories listed in it. */ is_done = foreach_dirinpath (search_path, 0, foreachfile_callback, fpptr, data); } else { /* Otherwise search the default paths. */ is_done = foreach_dirinpath (user_search_path, 0, foreachfile_callback, fpptr, data); if (!is_done) { is_done = foreach_dirinpath (getenv(LTDL_SEARCHPATH_VAR), 0, foreachfile_callback, fpptr, data); } #if defined(LT_MODULE_PATH_VAR) if (!is_done) { is_done = foreach_dirinpath (getenv(LT_MODULE_PATH_VAR), 0, foreachfile_callback, fpptr, data); } #endif #if defined(LT_DLSEARCH_PATH) if (!is_done && *sys_dlsearch_path) { is_done = foreach_dirinpath (sys_dlsearch_path, 0, foreachfile_callback, fpptr, data); } #endif } return is_done; } int lt_dlclose (lt_dlhandle handle) { lt_dlhandle cur, last; int errors = 0; /* check whether the handle is valid */ last = cur = handles; while (cur && handle != cur) { last = cur; cur = cur->next; } if (!cur) { LT__SETERROR (INVALID_HANDLE); ++errors; goto done; } cur = handle; cur->info.ref_count--; /* Note that even with resident modules, we must track the ref_count correctly incase the user decides to reset the residency flag later (even though the API makes no provision for that at the moment). */ if (cur->info.ref_count <= 0 && !LT_DLIS_RESIDENT (cur)) { lt_user_data data = cur->vtable->dlloader_data; if (cur != handles) { last->next = cur->next; } else { handles = cur->next; } errors += cur->vtable->module_close (data, cur->module); errors += unload_deplibs (handle); /* It is up to the callers to free the data itself. */ FREE (cur->interface_data); FREE (cur->info.filename); FREE (cur->info.name); FREE (cur); goto done; } if (LT_DLIS_RESIDENT (handle)) { LT__SETERROR (CLOSE_RESIDENT_MODULE); ++errors; } done: return errors; } void * lt_dlsym (lt_dlhandle place, const char *symbol) { size_t lensym; char lsym[LT_SYMBOL_LENGTH]; char *sym; void *address; lt_user_data data; lt_dlhandle handle; if (!place) { LT__SETERROR (INVALID_HANDLE); return 0; } handle = place; if (!symbol) { LT__SETERROR (SYMBOL_NOT_FOUND); return 0; } lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->vtable->sym_prefix) + LT_STRLEN (handle->info.name); if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH) { sym = lsym; } else { sym = MALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1); if (!sym) { LT__SETERROR (BUFFER_OVERFLOW); return 0; } } data = handle->vtable->dlloader_data; if (handle->info.name) { const char *saved_error; LT__GETERROR (saved_error); /* this is a libtool module */ if (handle->vtable->sym_prefix) { strcpy(sym, handle->vtable->sym_prefix); strcat(sym, handle->info.name); } else { strcpy(sym, handle->info.name); } strcat(sym, "_LTX_"); strcat(sym, symbol); /* try "modulename_LTX_symbol" */ address = handle->vtable->find_sym (data, handle->module, sym); if (address) { if (sym != lsym) { FREE (sym); } return address; } LT__SETERRORSTR (saved_error); } /* otherwise try "symbol" */ if (handle->vtable->sym_prefix) { strcpy(sym, handle->vtable->sym_prefix); strcat(sym, symbol); } else { strcpy(sym, symbol); } address = handle->vtable->find_sym (data, handle->module, sym); if (sym != lsym) { FREE (sym); } return address; } const char * lt_dlerror (void) { const char *error; LT__GETERROR (error); LT__SETERRORSTR (0); return error ? error : NULL; } static int lt_dlpath_insertdir (char **ppath, char *before, const char *dir) { int errors = 0; char *canonical = 0; char *argz = 0; size_t argz_len = 0; assert (ppath); assert (dir && *dir); if (canonicalize_path (dir, &canonical) != 0) { ++errors; goto cleanup; } assert (canonical && *canonical); /* If *PPATH is empty, set it to DIR. */ if (*ppath == 0) { assert (!before); /* BEFORE cannot be set without PPATH. */ assert (dir); /* Without DIR, don't call this function! */ *ppath = lt__strdup (dir); if (*ppath == 0) ++errors; goto cleanup; } assert (ppath && *ppath); if (argzize_path (*ppath, &argz, &argz_len) != 0) { ++errors; goto cleanup; } /* Convert BEFORE into an equivalent offset into ARGZ. This only works if *PPATH is already canonicalized, and hence does not change length with respect to ARGZ. We canonicalize each entry as it is added to the search path, and don't call this function with (uncanonicalized) user paths, so this is a fair assumption. */ if (before) { assert (*ppath <= before); assert ((int) (before - *ppath) <= (int) strlen (*ppath)); before = before - *ppath + argz; } if (lt_argz_insert (&argz, &argz_len, before, dir) != 0) { ++errors; goto cleanup; } argz_stringify (argz, argz_len, LT_PATHSEP_CHAR); MEMREASSIGN(*ppath, argz); cleanup: FREE (argz); FREE (canonical); return errors; } int lt_dladdsearchdir (const char *search_dir) { int errors = 0; if (search_dir && *search_dir) { if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0) ++errors; } return errors; } int lt_dlinsertsearchdir (const char *before, const char *search_dir) { int errors = 0; if (before) { if ((before < user_search_path) || (before >= user_search_path + LT_STRLEN (user_search_path))) { LT__SETERROR (INVALID_POSITION); return 1; } } if (search_dir && *search_dir) { if (lt_dlpath_insertdir (&user_search_path, (char *) before, search_dir) != 0) { ++errors; } } return errors; } int lt_dlsetsearchpath (const char *search_path) { int errors = 0; FREE (user_search_path); if (!search_path || !LT_STRLEN (search_path)) { return errors; } if (canonicalize_path (search_path, &user_search_path) != 0) ++errors; return errors; } const char * lt_dlgetsearchpath (void) { const char *saved_path; saved_path = user_search_path; return saved_path; } int lt_dlmakeresident (lt_dlhandle handle) { int errors = 0; if (!handle) { LT__SETERROR (INVALID_HANDLE); ++errors; } else { handle->info.is_resident = 1; } return errors; } int lt_dlisresident (lt_dlhandle handle) { if (!handle) { LT__SETERROR (INVALID_HANDLE); return -1; } return LT_DLIS_RESIDENT (handle); } /* --- MODULE INFORMATION --- */ typedef struct { const char *id_string; lt_dlhandle_interface *iface; } lt__interface_id; lt_dlinterface_id lt_dlinterface_register (const char *id_string, lt_dlhandle_interface *iface) { lt__interface_id *interface_id = (lt__interface_id *) lt__malloc (sizeof *interface_id); /* If lt__malloc fails, it will LT__SETERROR (NO_MEMORY), which can then be detected with lt_dlerror() if we return 0. */ if (interface_id) { interface_id->id_string = lt__strdup (id_string); if (!interface_id->id_string) FREE (interface_id); else interface_id->iface = iface; } return (lt_dlinterface_id) interface_id; } void lt_dlinterface_free (lt_dlinterface_id key) { lt__interface_id *interface_id = (lt__interface_id *)key; FREE (interface_id->id_string); FREE (interface_id); } void * lt_dlcaller_set_data (lt_dlinterface_id key, lt_dlhandle handle, void *data) { int n_elements = 0; void *stale = (void *) 0; lt_dlhandle cur = handle; int i; if (cur->interface_data) while (cur->interface_data[n_elements].key) ++n_elements; for (i = 0; i < n_elements; ++i) { if (cur->interface_data[i].key == key) { stale = cur->interface_data[i].data; break; } } /* Ensure that there is enough room in this handle's interface_data array to accept a new element (and an empty end marker). */ if (i == n_elements) { lt_interface_data *temp = REALLOC (lt_interface_data, cur->interface_data, 2+ n_elements); if (!temp) { stale = 0; goto done; } cur->interface_data = temp; /* We only need this if we needed to allocate a new interface_data. */ cur->interface_data[i].key = key; cur->interface_data[1+ i].key = 0; } cur->interface_data[i].data = data; done: return stale; } void * lt_dlcaller_get_data (lt_dlinterface_id key, lt_dlhandle handle) { void *result = (void *) 0; lt_dlhandle cur = handle; /* Locate the index of the element with a matching KEY. */ if (cur->interface_data) { int i; for (i = 0; cur->interface_data[i].key; ++i) { if (cur->interface_data[i].key == key) { result = cur->interface_data[i].data; break; } } } return result; } const lt_dlinfo * lt_dlgetinfo (lt_dlhandle handle) { if (!handle) { LT__SETERROR (INVALID_HANDLE); return 0; } return &(handle->info); } lt_dlhandle lt_dlhandle_iterate (lt_dlinterface_id iface, lt_dlhandle place) { lt_dlhandle handle = place; lt__interface_id *iterator = (lt__interface_id *) iface; assert (iface); /* iface is a required argument */ if (!handle) handle = handles; else handle = handle->next; /* advance while the interface check fails */ while (handle && iterator->iface && ((*iterator->iface) (handle, iterator->id_string) != 0)) { handle = handle->next; } return handle; } lt_dlhandle lt_dlhandle_fetch (lt_dlinterface_id iface, const char *module_name) { lt_dlhandle handle = 0; assert (iface); /* iface is a required argument */ while ((handle = lt_dlhandle_iterate (iface, handle))) { lt_dlhandle cur = handle; if (cur && cur->info.name && streq (cur->info.name, module_name)) break; } return handle; } int lt_dlhandle_map (lt_dlinterface_id iface, int (*func) (lt_dlhandle handle, void *data), void *data) { lt__interface_id *iterator = (lt__interface_id *) iface; lt_dlhandle cur = handles; assert (iface); /* iface is a required argument */ while (cur) { int errorcode = 0; /* advance while the interface check fails */ while (cur && iterator->iface && ((*iterator->iface) (cur, iterator->id_string) != 0)) { cur = cur->next; } if ((errorcode = (*func) (cur, data)) != 0) return errorcode; } return 0; } proftpd-dfsg-1.3.5~rc3/lib/libltdl/ltdl.h0000644000175000017500000001312311300565264020053 0ustar frankiefrankie/* ltdl.h -- generic dlopen functions Copyright (C) 1998-2000, 2004, 2005, 2007, 2008 Free Software Foundation, Inc. Written by Thomas Tanner, 1998 NOTE: The canonical source of this file is maintained with the GNU Libtool package. Report bugs to bug-libtool@gnu.org. GNU Libltdl is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exception to the GNU Lesser General Public License, if you distribute this file as part of a program or library that is built using GNU Libtool, you may include this file under the same distribution terms that you use for the rest of that program. GNU Libltdl is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with GNU Libltdl; see the file COPYING.LIB. If not, a copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, or obtained by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Only include this header file once. */ #if !defined(LTDL_H) #define LTDL_H 1 #include #include #include LT_BEGIN_C_DECLS /* LT_STRLEN can be used safely on NULL pointers. */ #define LT_STRLEN(s) (((s) && (s)[0]) ? strlen (s) : 0) /* --- DYNAMIC MODULE LOADING API --- */ typedef struct lt__handle *lt_dlhandle; /* A loaded module. */ /* Initialisation and finalisation functions for libltdl. */ LT_SCOPE int lt_dlinit (void); LT_SCOPE int lt_dlexit (void); /* Module search path manipulation. */ LT_SCOPE int lt_dladdsearchdir (const char *search_dir); LT_SCOPE int lt_dlinsertsearchdir (const char *before, const char *search_dir); LT_SCOPE int lt_dlsetsearchpath (const char *search_path); LT_SCOPE const char *lt_dlgetsearchpath (void); LT_SCOPE int lt_dlforeachfile ( const char *search_path, int (*func) (const char *filename, void *data), void *data); /* User module loading advisors. */ LT_SCOPE int lt_dladvise_init (lt_dladvise *advise); LT_SCOPE int lt_dladvise_destroy (lt_dladvise *advise); LT_SCOPE int lt_dladvise_ext (lt_dladvise *advise); LT_SCOPE int lt_dladvise_resident (lt_dladvise *advise); LT_SCOPE int lt_dladvise_local (lt_dladvise *advise); LT_SCOPE int lt_dladvise_global (lt_dladvise *advise); LT_SCOPE int lt_dladvise_preload (lt_dladvise *advise); /* Portable libltdl versions of the system dlopen() API. */ LT_SCOPE lt_dlhandle lt_dlopen (const char *filename); LT_SCOPE lt_dlhandle lt_dlopenext (const char *filename); LT_SCOPE lt_dlhandle lt_dlopenadvise (const char *filename, lt_dladvise advise); LT_SCOPE void * lt_dlsym (lt_dlhandle handle, const char *name); LT_SCOPE const char *lt_dlerror (void); LT_SCOPE int lt_dlclose (lt_dlhandle handle); /* --- PRELOADED MODULE SUPPORT --- */ /* A preopened symbol. Arrays of this type comprise the exported symbols for a dlpreopened module. */ typedef struct { const char *name; void *address; } lt_dlsymlist; typedef int lt_dlpreload_callback_func (lt_dlhandle handle); LT_SCOPE int lt_dlpreload (const lt_dlsymlist *preloaded); LT_SCOPE int lt_dlpreload_default (const lt_dlsymlist *preloaded); LT_SCOPE int lt_dlpreload_open (const char *originator, lt_dlpreload_callback_func *func); #define lt_preloaded_symbols lt__PROGRAM__LTX_preloaded_symbols #define LTDL_SET_PRELOADED_SYMBOLS() LT_STMT_START{ \ extern const lt_dlsymlist lt_preloaded_symbols[]; \ lt_dlpreload_default(lt_preloaded_symbols); \ }LT_STMT_END /* --- MODULE INFORMATION --- */ /* Associating user data with loaded modules. */ typedef void * lt_dlinterface_id; typedef int lt_dlhandle_interface (lt_dlhandle handle, const char *id_string); LT_SCOPE lt_dlinterface_id lt_dlinterface_register (const char *id_string, lt_dlhandle_interface *iface); LT_SCOPE void lt_dlinterface_free (lt_dlinterface_id key); LT_SCOPE void * lt_dlcaller_set_data (lt_dlinterface_id key, lt_dlhandle handle, void *data); LT_SCOPE void * lt_dlcaller_get_data (lt_dlinterface_id key, lt_dlhandle handle); /* Read only information pertaining to a loaded module. */ typedef struct { char * filename; /* file name */ char * name; /* module name */ int ref_count; /* number of times lt_dlopened minus number of times lt_dlclosed. */ unsigned int is_resident:1; /* module can't be unloaded. */ unsigned int is_symglobal:1; /* module symbols can satisfy subsequently loaded modules. */ unsigned int is_symlocal:1; /* module symbols are only available locally. */ } lt_dlinfo; LT_SCOPE const lt_dlinfo *lt_dlgetinfo (lt_dlhandle handle); LT_SCOPE lt_dlhandle lt_dlhandle_iterate (lt_dlinterface_id iface, lt_dlhandle place); LT_SCOPE lt_dlhandle lt_dlhandle_fetch (lt_dlinterface_id iface, const char *module_name); LT_SCOPE int lt_dlhandle_map (lt_dlinterface_id iface, int (*func) (lt_dlhandle handle, void *data), void *data); /* Deprecated module residency management API. */ LT_SCOPE int lt_dlmakeresident (lt_dlhandle handle); LT_SCOPE int lt_dlisresident (lt_dlhandle handle); #define lt_ptr void * LT_END_C_DECLS #endif /*!defined(LTDL_H)*/ proftpd-dfsg-1.3.5~rc3/lib/libltdl/lt__alloc.c0000644000175000017500000000435511300565264021046 0ustar frankiefrankie/* lt__alloc.c -- internal memory management interface Copyright (C) 2004, 2006, 2007 Free Software Foundation, Inc. Written by Gary V. Vaughan, 2004 NOTE: The canonical source of this file is maintained with the GNU Libtool package. Report bugs to bug-libtool@gnu.org. GNU Libltdl is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exception to the GNU Lesser General Public License, if you distribute this file as part of a program or library that is built using GNU Libtool, you may include this file under the same distribution terms that you use for the rest of that program. GNU Libltdl is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with GNU Libltdl; see the file COPYING.LIB. If not, a copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, or obtained by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "lt__private.h" #include #include "lt__alloc.h" static void alloc_die_default (void); void (*lt__alloc_die) (void) = alloc_die_default; /* Unless overridden, exit on memory failure. */ static void alloc_die_default (void) { fprintf (stderr, "Out of memory.\n"); exit (EXIT_FAILURE); } void * lt__malloc (size_t n) { void *mem; if (! (mem = malloc (n))) (*lt__alloc_die) (); return mem; } void * lt__zalloc (size_t n) { void *mem; if ((mem = lt__malloc (n))) memset (mem, 0, n); return mem; } void * lt__realloc (void *mem, size_t n) { if (! (mem = realloc (mem, n))) (*lt__alloc_die) (); return mem; } void * lt__memdup (void const *mem, size_t n) { void *newmem; if ((newmem = lt__malloc (n))) return memcpy (newmem, mem, n); return 0; } char * lt__strdup (const char *string) { return (char *) lt__memdup (string, strlen (string) +1); } proftpd-dfsg-1.3.5~rc3/lib/libltdl/lt__strl.c0000644000175000017500000000702611300565264020736 0ustar frankiefrankie/* lt__strl.c -- size-bounded string copying and concatenation Copyright (C) 2004 Free Software Foundation, Inc. Written by Bob Friesenhahn, 2004 NOTE: The canonical source of this file is maintained with the GNU Libtool package. Report bugs to bug-libtool@gnu.org. GNU Libltdl is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exception to the GNU Lesser General Public License, if you distribute this file as part of a program or library that is built using GNU Libtool, you may include this file under the same distribution terms that you use for the rest of that program. GNU Libltdl is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with GNU Libltdl; see the file COPYING.LIB. If not, a copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, or obtained by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include "lt__strl.h" /* lt_strlcat appends the NULL-terminated string src to the end of dst. It will append at most dstsize - strlen(dst) - 1 bytes, NULL-terminating the result. The total length of the string which would have been created given sufficient buffer size (may be longer than dstsize) is returned. This function substitutes for strlcat() which is available under NetBSD, FreeBSD and Solaris 9. Buffer overflow can be checked as follows: if (lt_strlcat(dst, src, dstsize) >= dstsize) return -1; */ #if !defined(HAVE_STRLCAT) size_t lt_strlcat(char *dst, const char *src, const size_t dstsize) { size_t length; char *p; const char *q; assert(dst != NULL); assert(src != (const char *) NULL); assert(dstsize >= 1); length=strlen(dst); /* Copy remaining characters from src while constraining length to size - 1. */ for ( p = dst + length, q = src; (*q != 0) && (length < dstsize - 1) ; length++, p++, q++ ) *p = *q; dst[length]='\0'; /* Add remaining length of src to length. */ while (*q++) length++; return length; } #endif /* !defined(HAVE_STRLCAT) */ /* lt_strlcpy copies up to dstsize - 1 characters from the NULL-terminated string src to dst, NULL-terminating the result. The total length of the string which would have been created given sufficient buffer size (may be longer than dstsize) is returned. This function substitutes for strlcpy() which is available under OpenBSD, FreeBSD and Solaris 9. Buffer overflow can be checked as follows: if (lt_strlcpy(dst, src, dstsize) >= dstsize) return -1; */ #if !defined(HAVE_STRLCPY) size_t lt_strlcpy(char *dst, const char *src, const size_t dstsize) { size_t length=0; char *p; const char *q; assert(dst != NULL); assert(src != (const char *) NULL); assert(dstsize >= 1); /* Copy src to dst within bounds of size-1. */ for ( p=dst, q=src, length=0 ; (*q != 0) && (length < dstsize-1) ; length++, p++, q++ ) *p = *q; dst[length]='\0'; /* Add remaining length of src to length. */ while (*q++) length++; return length; } #endif /* !defined(HAVE_STRLCPY) */ proftpd-dfsg-1.3.5~rc3/lib/libltdl/argz_.h0000644000175000017500000000425411300565263020222 0ustar frankiefrankie/* lt__argz.h -- internal argz interface for non-glibc systems Copyright (C) 2004, 2007, 2008 Free Software Foundation, Inc. Written by Gary V. Vaughan, 2004 NOTE: The canonical source of this file is maintained with the GNU Libtool package. Report bugs to bug-libtool@gnu.org. GNU Libltdl is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exception to the GNU Lesser General Public License, if you distribute this file as part of a program or library that is built using GNU Libtool, you may include this file under the same distribution terms that you use for the rest of that program. GNU Libltdl is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with GNU Libltdl; see the file COPYING.LIB. If not, a copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, or obtained by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if !defined(LT__ARGZ_H) #define LT__ARGZ_H 1 #include #define __need_error_t #include #include #if defined(LTDL) # include "lt__glibc.h" # include "lt_system.h" #else # define LT_SCOPE #endif #if defined(__cplusplus) extern "C" { #endif LT_SCOPE error_t argz_append (char **pargz, size_t *pargz_len, const char *buf, size_t buf_len); LT_SCOPE error_t argz_create_sep(const char *str, int delim, char **pargz, size_t *pargz_len); LT_SCOPE error_t argz_insert (char **pargz, size_t *pargz_len, char *before, const char *entry); LT_SCOPE char * argz_next (char *argz, size_t argz_len, const char *entry); LT_SCOPE void argz_stringify (char *argz, size_t argz_len, int sep); #if defined(__cplusplus) } #endif #if !defined(LTDL) # undef LT_SCOPE #endif #endif /*!defined(LT__ARGZ_H)*/ proftpd-dfsg-1.3.5~rc3/lib/libltdl/lt_dlloader.c0000644000175000017500000001363611300565264021405 0ustar frankiefrankie/* lt_dlloader.c -- dynamic library loader interface Copyright (C) 2004, 2007, 2008 Free Software Foundation, Inc. Written by Gary V. Vaughan, 2004 NOTE: The canonical source of this file is maintained with the GNU Libtool package. Report bugs to bug-libtool@gnu.org. GNU Libltdl is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exception to the GNU Lesser General Public License, if you distribute this file as part of a program or library that is built using GNU Libtool, you may include this file under the same distribution terms that you use for the rest of that program. GNU Libltdl is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with GNU Libltdl; see the file COPYING.LIB. If not, a copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, or obtained by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "lt__private.h" #include "lt_dlloader.h" #define RETURN_SUCCESS 0 #define RETURN_FAILURE 1 static void * loader_callback (SList *item, void *userdata); /* A list of all the dlloaders we know about, each stored as a boxed SList item: */ static SList *loaders = 0; /* Return NULL, unless the loader in this ITEM has a matching name, in which case we return the matching item so that its address is passed back out (for possible freeing) by slist_remove. */ static void * loader_callback (SList *item, void *userdata) { const lt_dlvtable *vtable = (const lt_dlvtable *) item->userdata; const char * name = (const char *) userdata; assert (vtable); return streq (vtable->name, name) ? (void *) item : NULL; } /* Hook VTABLE into our global LOADERS list according to its own PRIORITY field value. */ int lt_dlloader_add (const lt_dlvtable *vtable) { SList *item; if ((vtable == 0) /* diagnose invalid vtable fields */ || (vtable->module_open == 0) || (vtable->module_close == 0) || (vtable->find_sym == 0) || ((vtable->priority != LT_DLLOADER_PREPEND) && (vtable->priority != LT_DLLOADER_APPEND))) { LT__SETERROR (INVALID_LOADER); return RETURN_FAILURE; } item = slist_box (vtable); if (!item) { (*lt__alloc_die) (); /* Let the caller know something went wrong if lt__alloc_die doesn't abort. */ return RETURN_FAILURE; } if (vtable->priority == LT_DLLOADER_PREPEND) { loaders = slist_cons (item, loaders); } else { assert (vtable->priority == LT_DLLOADER_APPEND); loaders = slist_concat (loaders, item); } return RETURN_SUCCESS; } #ifdef LT_DEBUG_LOADERS static void * loader_dump_callback (SList *item, void *userdata) { const lt_dlvtable *vtable = (const lt_dlvtable *) item->userdata; fprintf (stderr, ", %s", (vtable && vtable->name) ? vtable->name : "(null)"); return 0; } void lt_dlloader_dump (void) { fprintf (stderr, "loaders: "); if (!loaders) { fprintf (stderr, "(empty)"); } else { const lt_dlvtable *head = (const lt_dlvtable *) loaders->userdata; fprintf (stderr, "%s", (head && head->name) ? head->name : "(null)"); if (slist_tail (loaders)) slist_foreach (slist_tail (loaders), loader_dump_callback, NULL); } fprintf (stderr, "\n"); } #endif /* An iterator for the global loader list: if LOADER is NULL, then return the first element, otherwise the following element. */ lt_dlloader lt_dlloader_next (lt_dlloader loader) { SList *item = (SList *) loader; return (lt_dlloader) (item ? item->next : loaders); } /* Non-destructive unboxing of a loader. */ const lt_dlvtable * lt_dlloader_get (lt_dlloader loader) { return (const lt_dlvtable *) (loader ? ((SList *) loader)->userdata : NULL); } /* Return the contents of the first item in the global loader list with a matching NAME after removing it from that list. If there was no match, return NULL; if there is an error, return NULL and set an error for lt_dlerror; do not set an error if only resident modules need this loader; in either case, the loader list is not changed if NULL is returned. */ lt_dlvtable * lt_dlloader_remove (char *name) { const lt_dlvtable * vtable = lt_dlloader_find (name); static const char id_string[] = "lt_dlloader_remove"; lt_dlinterface_id iface; lt_dlhandle handle = 0; int in_use = 0; int in_use_by_resident = 0; if (!vtable) { LT__SETERROR (INVALID_LOADER); return 0; } /* Fail if there are any open modules which use this loader. */ iface = lt_dlinterface_register (id_string, NULL); while ((handle = lt_dlhandle_iterate (iface, handle))) { lt_dlhandle cur = handle; if (cur->vtable == vtable) { in_use = 1; if (lt_dlisresident (handle)) in_use_by_resident = 1; } } lt_dlinterface_free (iface); if (in_use) { if (!in_use_by_resident) LT__SETERROR (REMOVE_LOADER); return 0; } /* Call the loader finalisation function. */ if (vtable && vtable->dlloader_exit) { if ((*vtable->dlloader_exit) (vtable->dlloader_data) != 0) { /* If there is an exit function, and it returns non-zero then it must set an error, and we will not remove it from the list. */ return 0; } } /* If we got this far, remove the loader from our global list. */ return (lt_dlvtable *) slist_unbox ((SList *) slist_remove (&loaders, loader_callback, name)); } const lt_dlvtable * lt_dlloader_find (char *name) { return lt_dlloader_get (slist_find (loaders, loader_callback, name)); } proftpd-dfsg-1.3.5~rc3/lib/pr_fnmatch_loop.c0000644000175000017500000007465411745576245020671 0ustar frankiefrankie/* Copyright (C) 1991-1993,1996-2001,2003-2005,2007 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. */ /* This file comes from the GNU C Library and has been modified for use in * ProFTPD. * * Changes are released under the GNU Public License, version 2. * Copyright (C) 2000 MacGyver aka Habeeb J. Dihu * Copyright (C) 2010-2012 The ProFTPD Project */ /* AIX requires this to be the first thing in the file. */ #if defined _AIX && !defined __GNUC__ #pragma alloca #endif #include struct STRUCT { const CHAR *pattern; const CHAR *string; int no_leading_period; }; /* Match STRING against the filename pattern PATTERN, returning zero if it matches, nonzero if not. */ static int FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, int no_leading_period, int flags, struct STRUCT *ends) internal_function; static int EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end, int no_leading_period, int flags) internal_function; static const CHAR *END (const CHAR *patternp) internal_function; #ifndef HAVE_MEMPCPY /* Copy N bytes of SRC to DEST, return pointer to bytes after the last written byte. */ static void * __mempcpy (void *dest, const void *src, size_t n) { return (char *) memcpy (dest, src, n) + n; } #endif static int internal_function FCT (pattern, string, string_end, no_leading_period, flags, ends) const CHAR *pattern; const CHAR *string; const CHAR *string_end; int no_leading_period; int flags; struct STRUCT *ends; { register const CHAR *p = pattern, *n = string; register UCHAR c; int is_seqval; #ifdef _LIBC # if WIDE_CHAR_VERSION const char *collseq = (const char *) _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQWC); # else const UCHAR *collseq = (const UCHAR *) _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQMB); # endif #endif while ((c = *p++) != L('\0')) { int new_no_leading_period = 0; c = FOLD (c); switch (c) { case L('?'): if (__builtin_expect (flags & PR_FNM_EXTMATCH, 0) && *p == '(') { int res; res = EXT (c, p, n, string_end, no_leading_period, flags); if (res != -1) return res; } if (n == string_end) return PR_FNM_NOMATCH; else if (*n == L('/') && (flags & PR_FNM_FILE_NAME)) return PR_FNM_NOMATCH; else if (*n == L('.') && no_leading_period) return PR_FNM_NOMATCH; break; case L('\\'): if (!(flags & PR_FNM_NOESCAPE)) { c = *p++; if (c == L('\0')) /* Trailing \ loses. */ return PR_FNM_NOMATCH; c = FOLD (c); } if (n == string_end || FOLD ((UCHAR) *n) != c) return PR_FNM_NOMATCH; break; case L('*'): if (__builtin_expect (flags & PR_FNM_EXTMATCH, 0) && *p == '(') { int res; res = EXT (c, p, n, string_end, no_leading_period, flags); if (res != -1) return res; } else if (ends != NULL) { ends->pattern = p - 1; ends->string = n; ends->no_leading_period = no_leading_period; return 0; } if (n != string_end && *n == L('.') && no_leading_period) return PR_FNM_NOMATCH; for (c = *p++; c == L('?') || c == L('*'); c = *p++) { if (*p == L('(') && (flags & PR_FNM_EXTMATCH) != 0) { const CHAR *endp = END (p); if (endp != p) { /* This is a pattern. Skip over it. */ p = endp; continue; } } if (c == L('?')) { /* A ? needs to match one character. */ if (n == string_end) /* There isn't another character; no match. */ return PR_FNM_NOMATCH; else if (*n == L('/') && __builtin_expect (flags & PR_FNM_FILE_NAME, 0)) /* A slash does not match a wildcard under PR_FNM_FILE_NAME. */ return PR_FNM_NOMATCH; else /* One character of the string is consumed in matching this ? wildcard, so *??? won't match if there are less than three characters. */ ++n; } } if (c == L('\0')) /* The wildcard(s) is/are the last element of the pattern. If the name is a file name and contains another slash this means it cannot match, unless the PR_FNM_LEADING_DIR flag is set. */ { int result = (flags & PR_FNM_FILE_NAME) == 0 ? 0 : PR_FNM_NOMATCH; if (flags & PR_FNM_FILE_NAME) { if (flags & PR_FNM_LEADING_DIR) result = 0; else { if (MEMCHR (n, L('/'), string_end - n) == NULL) result = 0; } } return result; } else { const CHAR *endp; struct STRUCT end; end.pattern = NULL; endp = MEMCHR (n, (flags & PR_FNM_FILE_NAME) ? L('/') : L('\0'), string_end - n); if (endp == NULL) endp = string_end; if (c == L('[') || (__builtin_expect (flags & PR_FNM_EXTMATCH, 0) != 0 && (c == L('@') || c == L('+') || c == L('!')) && *p == L('('))) { int flags2 = ((flags & PR_FNM_FILE_NAME) ? flags : (flags & ~PR_FNM_PERIOD)); for (--p; n < endp; ++n, no_leading_period = 0) if (FCT (p, n, string_end, no_leading_period, flags2, &end) == 0) goto found; } else if (c == L('/') && (flags & PR_FNM_FILE_NAME)) { while (n < string_end && *n != L('/')) ++n; if (n < string_end && *n == L('/') && (FCT (p, n + 1, string_end, flags & PR_FNM_PERIOD, flags, NULL) == 0)) return 0; } else { int flags2 = ((flags & PR_FNM_FILE_NAME) ? flags : (flags & ~PR_FNM_PERIOD)); if (c == L('\\') && !(flags & PR_FNM_NOESCAPE)) c = *p; c = FOLD (c); for (--p; n < endp; ++n, no_leading_period = 0) if (FOLD ((UCHAR) *n) == c && (FCT (p, n, string_end, no_leading_period, flags2, &end) == 0)) { found: if (end.pattern == NULL) return 0; break; } if (end.pattern != NULL) { p = end.pattern; n = end.string; no_leading_period = end.no_leading_period; continue; } } } /* If we come here no match is possible with the wildcard. */ return PR_FNM_NOMATCH; case L('['): { /* Nonzero if the sense of the character class is inverted. */ register int not; CHAR cold; UCHAR fn; if (posixly_correct == 0) posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1; if (n == string_end) return PR_FNM_NOMATCH; if (*n == L('.') && no_leading_period) return PR_FNM_NOMATCH; if (*n == L('/') && (flags & PR_FNM_FILE_NAME)) /* `/' cannot be matched. */ return PR_FNM_NOMATCH; not = (*p == L('!') || (posixly_correct < 0 && *p == L('^'))); if (not) ++p; fn = FOLD ((UCHAR) *n); c = *p++; for (;;) { if (!(flags & PR_FNM_NOESCAPE) && c == L('\\')) { if (*p == L('\0')) return PR_FNM_NOMATCH; c = FOLD ((UCHAR) *p); ++p; goto normal_bracket; } else if (c == L('[') && *p == L(':')) { /* Leave room for the null. */ CHAR str[CHAR_CLASS_MAX_LENGTH + 1]; size_t c1 = 0; #if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) wctype_t wt; #endif const CHAR *startp = p; for (;;) { if (c1 == CHAR_CLASS_MAX_LENGTH) /* The name is too long and therefore the pattern is ill-formed. */ return PR_FNM_NOMATCH; c = *++p; if (c == L(':') && p[1] == L(']')) { p += 2; break; } if (c < L('a') || c >= L('z')) { /* This cannot possibly be a character class name. Match it as a normal range. */ p = startp; c = L('['); goto normal_bracket; } str[c1++] = c; } str[c1] = L('\0'); #if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) wt = IS_CHAR_CLASS (str); if (wt == 0) /* Invalid character class name. */ return PR_FNM_NOMATCH; # if defined _LIBC && ! WIDE_CHAR_VERSION /* The following code is glibc specific but does there a good job in speeding up the code since we can avoid the btowc() call. */ if (_ISCTYPE ((UCHAR) *n, wt)) goto matched; # else if (ISWCTYPE (BTOWC ((UCHAR) *n), wt)) goto matched; # endif #else if ((STREQ (str, L("alnum")) && ISALNUM ((UCHAR) *n)) || (STREQ (str, L("alpha")) && ISALPHA ((UCHAR) *n)) || (STREQ (str, L("blank")) && ISBLANK ((UCHAR) *n)) || (STREQ (str, L("cntrl")) && ISCNTRL ((UCHAR) *n)) || (STREQ (str, L("digit")) && ISDIGIT ((UCHAR) *n)) || (STREQ (str, L("graph")) && ISGRAPH ((UCHAR) *n)) || (STREQ (str, L("lower")) && ISLOWER ((UCHAR) *n)) || (STREQ (str, L("print")) && ISPRINT ((UCHAR) *n)) || (STREQ (str, L("punct")) && ISPUNCT ((UCHAR) *n)) || (STREQ (str, L("space")) && ISSPACE ((UCHAR) *n)) || (STREQ (str, L("upper")) && ISUPPER ((UCHAR) *n)) || (STREQ (str, L("xdigit")) && ISXDIGIT ((UCHAR) *n))) goto matched; #endif c = *p++; } #ifdef _LIBC else if (c == L('[') && *p == L('=')) { UCHAR str[1]; uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); const CHAR *startp = p; c = *++p; if (c == L('\0')) { p = startp; c = L('['); goto normal_bracket; } str[0] = c; c = *++p; if (c != L('=') || p[1] != L(']')) { p = startp; c = L('['); goto normal_bracket; } p += 2; if (nrules == 0) { if ((UCHAR) *n == str[0]) goto matched; } else { const int32_t *table; # if WIDE_CHAR_VERSION const int32_t *weights; const int32_t *extra; # else const unsigned char *weights; const unsigned char *extra; # endif const int32_t *indirect; int32_t idx; const UCHAR *cp = (const UCHAR *) str; /* This #include defines a local function! */ # if WIDE_CHAR_VERSION # include # else # include # endif # if WIDE_CHAR_VERSION table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEWC); weights = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTWC); extra = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAWC); indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTWC); # else table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); weights = (const unsigned char *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB); extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB); indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB); # endif idx = findidx (&cp); if (idx != 0) { /* We found a table entry. Now see whether the character we are currently at has the same equivalance class value. */ int len = weights[idx & 0xffffff]; int32_t idx2; const UCHAR *np = (const UCHAR *) n; idx2 = findidx (&np); if (idx2 != 0 && (idx >> 24) == (idx2 >> 24) && len == weights[idx2 & 0xffffff]) { int cnt = 0; idx &= 0xffffff; idx2 &= 0xffffff; while (cnt < len && (weights[idx + 1 + cnt] == weights[idx2 + 1 + cnt])) ++cnt; if (cnt == len) goto matched; } } } c = *p++; } #endif else if (c == L('\0')) /* [ (unterminated) loses. */ return PR_FNM_NOMATCH; else { int is_range = 0; #ifdef _LIBC is_seqval = 0; if (c == L('[') && *p == L('.')) { uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); const CHAR *startp = p; size_t c1 = 0; while (1) { c = *++p; if (c == L('.') && p[1] == L(']')) { p += 2; break; } if (c == '\0') return PR_FNM_NOMATCH; ++c1; } /* We have to handling the symbols differently in ranges since then the collation sequence is important. */ is_range = *p == L('-') && p[1] != L('\0'); if (nrules == 0) { /* There are no names defined in the collation data. Therefore we only accept the trivial names consisting of the character itself. */ if (c1 != 1) return PR_FNM_NOMATCH; if (!is_range && *n == startp[1]) goto matched; cold = startp[1]; c = *p++; } else { int32_t table_size; const int32_t *symb_table; # ifdef WIDE_CHAR_VERSION char str[c1]; unsigned int strcnt; # else # define str (startp + 1) # endif const unsigned char *extra; int32_t idx; int32_t elem; int32_t second; int32_t hash; # ifdef WIDE_CHAR_VERSION /* We have to convert the name to a single-byte string. This is possible since the names consist of ASCII characters and the internal representation is UCS4. */ for (strcnt = 0; strcnt < c1; ++strcnt) str[strcnt] = startp[1 + strcnt]; #endif table_size = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_SYMB_HASH_SIZEMB); symb_table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_TABLEMB); extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB); /* Locate the character in the hashing table. */ hash = elem_hash (str, c1); idx = 0; elem = hash % table_size; if (symb_table[2 * elem] != 0) { second = hash % (table_size - 2) + 1; do { /* First compare the hashing value. */ if (symb_table[2 * elem] == hash && (c1 == extra[symb_table[2 * elem + 1]]) && memcmp (str, &extra[symb_table[2 * elem + 1] + 1], c1) == 0) { /* Yep, this is the entry. */ idx = symb_table[2 * elem + 1]; idx += 1 + extra[idx]; break; } /* Next entry. */ elem += second; } while (symb_table[2 * elem] != 0); } if (symb_table[2 * elem] != 0) { /* Compare the byte sequence but only if this is not part of a range. */ # ifdef WIDE_CHAR_VERSION int32_t *wextra; idx += 1 + extra[idx]; /* Adjust for the alignment. */ idx = (idx + 3) & ~3; wextra = (int32_t *) &extra[idx + 4]; # endif if (! is_range) { # ifdef WIDE_CHAR_VERSION for (c1 = 0; (int32_t) c1 < wextra[idx]; ++c1) if (n[c1] != wextra[1 + c1]) break; if ((int32_t) c1 == wextra[idx]) goto matched; # else for (c1 = 0; c1 < extra[idx]; ++c1) if (n[c1] != extra[1 + c1]) break; if (c1 == extra[idx]) goto matched; # endif } /* Get the collation sequence value. */ is_seqval = 1; # ifdef WIDE_CHAR_VERSION cold = wextra[1 + wextra[idx]]; # else /* Adjust for the alignment. */ idx += 1 + extra[idx]; idx = (idx + 3) & ~4; cold = *((int32_t *) &extra[idx]); # endif c = *p++; } else if (c1 == 1) { /* No valid character. Match it as a single byte. */ if (!is_range && *n == str[0]) goto matched; cold = str[0]; c = *p++; } else return PR_FNM_NOMATCH; } } else # undef str #endif { c = FOLD (c); normal_bracket: /* We have to handling the symbols differently in ranges since then the collation sequence is important. */ is_range = (*p == L('-') && p[1] != L('\0') && p[1] != L(']')); if (!is_range && c == fn) goto matched; /* This is needed if we goto normal_bracket; from outside of is_seqval's scope. */ is_seqval = 0; cold = c; c = *p++; } if (c == L('-') && *p != L(']')) { #ifdef _LIBC /* We have to find the collation sequence value for C. Collation sequence is nothing we can regularly access. The sequence value is defined by the order in which the definitions of the collation values for the various characters appear in the source file. A strange concept, nowhere documented. */ uint32_t fcollseq; uint32_t lcollseq; UCHAR cend = *p++; # ifdef WIDE_CHAR_VERSION /* Search in the `names' array for the characters. */ fcollseq = __collseq_table_lookup (collseq, fn); if (fcollseq == ~((uint32_t) 0)) /* XXX We don't know anything about the character we are supposed to match. This means we are failing. */ goto range_not_matched; if (is_seqval) lcollseq = cold; else lcollseq = __collseq_table_lookup (collseq, cold); # else fcollseq = collseq[fn]; lcollseq = is_seqval ? cold : collseq[(UCHAR) cold]; # endif is_seqval = 0; if (cend == L('[') && *p == L('.')) { uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); const CHAR *startp = p; size_t c1 = 0; while (1) { c = *++p; if (c == L('.') && p[1] == L(']')) { p += 2; break; } if (c == '\0') return PR_FNM_NOMATCH; ++c1; } if (nrules == 0) { /* There are no names defined in the collation data. Therefore we only accept the trivial names consisting of the character itself. */ if (c1 != 1) return PR_FNM_NOMATCH; cend = startp[1]; } else { int32_t table_size; const int32_t *symb_table; # ifdef WIDE_CHAR_VERSION char str[c1]; unsigned int strcnt; # else # define str (startp + 1) # endif const unsigned char *extra; int32_t idx; int32_t elem; int32_t second; int32_t hash; # ifdef WIDE_CHAR_VERSION /* We have to convert the name to a single-byte string. This is possible since the names consist of ASCII characters and the internal representation is UCS4. */ for (strcnt = 0; strcnt < c1; ++strcnt) str[strcnt] = startp[1 + strcnt]; # endif table_size = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_SYMB_HASH_SIZEMB); symb_table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_TABLEMB); extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB); /* Locate the character in the hashing table. */ hash = elem_hash (str, c1); idx = 0; elem = hash % table_size; if (symb_table[2 * elem] != 0) { second = hash % (table_size - 2) + 1; do { /* First compare the hashing value. */ if (symb_table[2 * elem] == hash && (c1 == extra[symb_table[2 * elem + 1]]) && memcmp (str, &extra[symb_table[2 * elem + 1] + 1], c1) == 0) { /* Yep, this is the entry. */ idx = symb_table[2 * elem + 1]; idx += 1 + extra[idx]; break; } /* Next entry. */ elem += second; } while (symb_table[2 * elem] != 0); } if (symb_table[2 * elem] != 0) { /* Compare the byte sequence but only if this is not part of a range. */ # ifdef WIDE_CHAR_VERSION int32_t *wextra; idx += 1 + extra[idx]; /* Adjust for the alignment. */ idx = (idx + 3) & ~4; wextra = (int32_t *) &extra[idx + 4]; # endif /* Get the collation sequence value. */ is_seqval = 1; # ifdef WIDE_CHAR_VERSION cend = wextra[1 + wextra[idx]]; # else /* Adjust for the alignment. */ idx += 1 + extra[idx]; idx = (idx + 3) & ~4; cend = *((int32_t *) &extra[idx]); # endif } else if (symb_table[2 * elem] != 0 && c1 == 1) { cend = str[0]; c = *p++; } else return PR_FNM_NOMATCH; } # undef str } else { if (!(flags & PR_FNM_NOESCAPE) && cend == L('\\')) cend = *p++; if (cend == L('\0')) return PR_FNM_NOMATCH; cend = FOLD (cend); } /* XXX It is not entirely clear to me how to handle characters which are not mentioned in the collation specification. */ if ( # ifdef WIDE_CHAR_VERSION lcollseq == 0xffffffff || # endif lcollseq <= fcollseq) { /* We have to look at the upper bound. */ uint32_t hcollseq; if (is_seqval) hcollseq = cend; else { # ifdef WIDE_CHAR_VERSION hcollseq = __collseq_table_lookup (collseq, cend); if (hcollseq == ~((uint32_t) 0)) { /* Hum, no information about the upper bound. The matching succeeds if the lower bound is matched exactly. */ if (lcollseq != fcollseq) goto range_not_matched; goto matched; } # else hcollseq = collseq[cend]; # endif } if (lcollseq <= hcollseq && fcollseq <= hcollseq) goto matched; } # ifdef WIDE_CHAR_VERSION range_not_matched: # endif #else /* We use a boring value comparison of the character values. This is better than comparing using `strcoll' since the latter would have surprising and sometimes fatal consequences. */ UCHAR cend = *p++; if (!(flags & PR_FNM_NOESCAPE) && cend == L('\\')) cend = *p++; if (cend == L('\0')) return PR_FNM_NOMATCH; /* It is a range. */ if (cold <= fn && fn <= cend) goto matched; #endif c = *p++; } } if (c == L(']')) break; } if (!not) return PR_FNM_NOMATCH; break; matched: /* Skip the rest of the [...] that already matched. */ do { ignore_next: c = *p++; if (c == L('\0')) /* [... (unterminated) loses. */ return PR_FNM_NOMATCH; if (!(flags & PR_FNM_NOESCAPE) && c == L('\\')) { if (*p == L('\0')) return PR_FNM_NOMATCH; /* XXX 1003.2d11 is unclear if this is right. */ ++p; } else if (c == L('[') && *p == L(':')) { int c1 = 0; const CHAR *startp = p; while (1) { c = *++p; if (++c1 == CHAR_CLASS_MAX_LENGTH) return PR_FNM_NOMATCH; if (*p == L(':') && p[1] == L(']')) break; if (c < L('a') || c >= L('z')) { p = startp; goto ignore_next; } } p += 2; c = *p++; } else if (c == L('[') && *p == L('=')) { c = *++p; if (c == L('\0')) return PR_FNM_NOMATCH; c = *++p; if (c != L('=') || p[1] != L(']')) return PR_FNM_NOMATCH; p += 2; c = *p++; } else if (c == L('[') && *p == L('.')) { ++p; while (1) { c = *++p; if (c == '\0') return PR_FNM_NOMATCH; if (*p == L('.') && p[1] == L(']')) break; } p += 2; c = *p++; } } while (c != L(']')); if (not) return PR_FNM_NOMATCH; } break; case L('+'): case L('@'): case L('!'): if (__builtin_expect (flags & PR_FNM_EXTMATCH, 0) && *p == '(') { int res; res = EXT (c, p, n, string_end, no_leading_period, flags); if (res != -1) return res; } goto normal_match; case L('/'): if (NO_LEADING_PERIOD (flags)) { if (n == string_end || c != (UCHAR) *n) return PR_FNM_NOMATCH; new_no_leading_period = 1; break; } /* FALLTHROUGH */ default: normal_match: if (n == string_end || c != FOLD ((UCHAR) *n)) return PR_FNM_NOMATCH; } no_leading_period = new_no_leading_period; ++n; } if (n == string_end) return 0; if ((flags & PR_FNM_LEADING_DIR) && n != string_end && *n == L('/')) /* The PR_FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */ return 0; return PR_FNM_NOMATCH; } static const CHAR * internal_function END (const CHAR *pattern) { const CHAR *p = pattern; while (1) if (*++p == L('\0')) /* This is an invalid pattern. */ return pattern; else if (*p == L('[')) { /* Handle brackets special. */ if (posixly_correct == 0) posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1; /* Skip the not sign. We have to recognize it because of a possibly following ']'. */ if (*++p == L('!') || (posixly_correct < 0 && *p == L('^'))) ++p; /* A leading ']' is recognized as such. */ if (*p == L(']')) ++p; /* Skip over all characters of the list. */ while (*p != L(']')) if (*p++ == L('\0')) /* This is no valid pattern. */ return pattern; } else if ((*p == L('?') || *p == L('*') || *p == L('+') || *p == L('@') || *p == L('!')) && p[1] == L('(')) p = END (p + 1); else if (*p == L(')')) break; return p + 1; } static int internal_function EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end, int no_leading_period, int flags) { const CHAR *startp; int level; struct patternlist { struct patternlist *next; CHAR str[0]; } *list = NULL; struct patternlist **lastp = &list; size_t pattern_len = STRLEN (pattern); const CHAR *p; const CHAR *rs; /* Parse the pattern. Store the individual parts in the list. */ level = 0; for (startp = p = pattern + 1; level >= 0; ++p) if (*p == L('\0')) /* This is an invalid pattern. */ return -1; else if (*p == L('[')) { /* Handle brackets special. */ if (posixly_correct == 0) posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1; /* Skip the not sign. We have to recognize it because of a possibly following ']'. */ if (*++p == L('!') || (posixly_correct < 0 && *p == L('^'))) ++p; /* A leading ']' is recognized as such. */ if (*p == L(']')) ++p; /* Skip over all characters of the list. */ while (*p != L(']')) if (*p++ == L('\0')) /* This is no valid pattern. */ return -1; } else if ((*p == L('?') || *p == L('*') || *p == L('+') || *p == L('@') || *p == L('!')) && p[1] == L('(')) /* Remember the nesting level. */ ++level; else if (*p == L(')')) { if (level-- == 0) { /* This means we found the end of the pattern. */ #define NEW_PATTERN \ struct patternlist *newp; \ \ if (opt == L('?') || opt == L('@')) \ newp = __alloca (sizeof (struct patternlist) \ + (pattern_len * sizeof (CHAR))); \ else \ newp = __alloca (sizeof (struct patternlist) \ + ((p - startp + 1) * sizeof (CHAR))); \ *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L('\0'); \ newp->next = NULL; \ *lastp = newp; \ lastp = &newp->next NEW_PATTERN; } } else if (*p == L('|')) { if (level == 0) { NEW_PATTERN; startp = p + 1; } } #undef NEW_PATTERN switch (opt) { case L('*'): if (FCT (p, string, string_end, no_leading_period, flags, NULL) == 0) return 0; /* FALLTHROUGH */ case L('+'): do { for (rs = string; rs <= string_end; ++rs) /* First match the prefix with the current pattern with the current pattern. */ if (FCT (list->str, string, rs, no_leading_period, flags & PR_FNM_FILE_NAME ? flags : flags & ~PR_FNM_PERIOD, NULL) == 0 /* This was successful. Now match the rest with the rest of the pattern. */ && (FCT (p, rs, string_end, rs == string ? no_leading_period : rs[-1] == '/' && NO_LEADING_PERIOD (flags) ? 1 : 0, flags & PR_FNM_FILE_NAME ? flags : flags & ~PR_FNM_PERIOD, NULL) == 0 /* This didn't work. Try the whole pattern. */ || (rs != string && FCT (pattern - 1, rs, string_end, rs == string ? no_leading_period : (rs[-1] == '/' && NO_LEADING_PERIOD (flags) ? 1 : 0), flags & PR_FNM_FILE_NAME ? flags : flags & ~PR_FNM_PERIOD, NULL) == 0))) /* It worked. Signal success. */ return 0; } while ((list = list->next) != NULL); /* None of the patterns lead to a match. */ return PR_FNM_NOMATCH; case L('?'): if (FCT (p, string, string_end, no_leading_period, flags, NULL) == 0) return 0; /* FALLTHROUGH */ case L('@'): do /* I cannot believe it but `strcat' is actually acceptable here. Match the entire string with the prefix from the pattern list and the rest of the pattern following the pattern list. */ if (FCT (STRCAT (list->str, p), string, string_end, no_leading_period, flags & PR_FNM_FILE_NAME ? flags : flags & ~PR_FNM_PERIOD, NULL) == 0) /* It worked. Signal success. */ return 0; while ((list = list->next) != NULL); /* None of the patterns lead to a match. */ return PR_FNM_NOMATCH; case L('!'): for (rs = string; rs <= string_end; ++rs) { struct patternlist *runp; for (runp = list; runp != NULL; runp = runp->next) if (FCT (runp->str, string, rs, no_leading_period, flags & PR_FNM_FILE_NAME ? flags : flags & ~PR_FNM_PERIOD, NULL) == 0) break; /* If none of the patterns matched see whether the rest does. */ if (runp == NULL && (FCT (p, rs, string_end, rs == string ? no_leading_period : rs[-1] == '/' && NO_LEADING_PERIOD (flags) ? 1 : 0, flags & PR_FNM_FILE_NAME ? flags : flags & ~PR_FNM_PERIOD, NULL) == 0)) /* This is successful. */ return 0; } /* None of the patterns together with the rest of the pattern lead to a match. */ return PR_FNM_NOMATCH; default: break; } return -1; } #undef FOLD #undef CHAR #undef UCHAR #undef INT #undef FCT #undef EXT #undef END #undef STRUCT #undef MEMPCPY #undef MEMCHR #undef STRCOLL #undef STRLEN #undef STRCAT #undef L #undef BTOWC proftpd-dfsg-1.3.5~rc3/lib/sstrncpy.c0000644000175000017500000000372411661363757017371 0ustar frankiefrankie/* * ProFTPD - FTP server daemon * Copyright (c) 1997, 1998 Public Flood Software * Copyright (c) 1999, 2000 MacGyver aka Habeeb J. Dihu * Copyright (c) 2001-2011 The ProFTPD Project team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * As a special exemption, Public Flood Software/MacGyver aka Habeeb J. Dihu * and other respective copyright holders give permission to link this program * with OpenSSL, and distribute the resulting executable, without including * the source code for OpenSSL in the source distribution. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #ifdef HAVE_STRING_H # include #endif #include "libsupp.h" /* "safe" strncpy, saves room for \0 at end of dest, and refuses to copy * more than "n" bytes. */ char *sstrncpy(char *dst, const char *src, size_t n) { #ifndef HAVE_STRLCPY register char *d = dst; #endif /* HAVE_STRLCPY */ if (dst == NULL) { errno = EINVAL; return NULL; } if (src == NULL) { errno = EINVAL; return NULL; } if (n == 0) return NULL; #ifdef HAVE_STRLCPY strlcpy(dst, src, n); #else if (src && *src) { for (; *src && n > 1; n--) *d++ = *src++; } *d = '\0'; #endif /* HAVE_STRLCPY */ return dst; } proftpd-dfsg-1.3.5~rc3/lib/getopt.c0000644000175000017500000007310311566546322016777 0ustar frankiefrankie/* Getopt for GNU. NOTE: getopt is now part of the C library, so if you don't know what "Keep this file name-space clean" means, talk to drepper@gnu.org before changing it! Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. */ /* This tells Alpha OSF/1 not to define a getopt prototype in . Ditto for AIX 3.2 and . */ #ifndef _NO_PROTO # define _NO_PROTO #endif #ifdef HAVE_CONFIG_H # include #endif #if !defined __STDC__ || !__STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ # ifndef const # define const # endif #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #define GETOPT_INTERFACE_VERSION 2 #if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 # include # if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION # define ELIDE_CODE # endif #endif #ifndef ELIDE_CODE /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ /* Don't include stdlib.h for non-GNU C libraries because some of them contain conflicting prototypes for getopt. */ # include # include #endif /* GNU C library. */ #ifdef VMS # include # if HAVE_STRING_H - 0 # include # endif #endif #if defined(PR_USE_NLS) && !defined(_) /* This is for other GNU distributions with internationalized messages. When compiling libc, the _ macro is predefined. */ # ifdef HAVE_LIBINTL_H # include # define _(msgid) gettext (msgid) # else # define _(msgid) (msgid) # endif #else # define _(msgid) (msgid) #endif /* This version of `getopt' appears to the caller like standard Unix `getopt' but it behaves differently for the user, since it allows the user to intersperse the options with the other arguments. As `getopt' works, it permutes the elements of ARGV so that, when it is done, all the options precede everything else. Thus all application programs are extended to handle flexible argument order. Setting the environment variable POSIXLY_CORRECT disables permutation. Then the behavior is completely standard. GNU application programs can use a third alternative mode in which they can distinguish the relative order of options and other arguments. */ #include "getopt.h" /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ char *optarg; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns -1, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ /* 1003.2 says this must be 1 before any call. */ int optind = 1; /* Formerly, initialization of getopt depended on optind==0, which causes problems with re-calling getopt as programs generally don't know that. */ int __getopt_initialized; /* The next char to be scanned in the option-element in which the last option character we returned was found. This allows us to pick up the scan where we left off. If this is zero, or a null string, it means resume the scan by advancing to the next ARGV-element. */ static char *nextchar; /* Callers store zero here to inhibit the error message for unrecognized options. */ int opterr = 1; /* Set to an option character which was unrecognized. This must be initialized on some systems to avoid linking in the system's own getopt implementation. */ int optopt = '?'; /* Describe how to deal with options that follow non-option ARGV-elements. If the caller did not specify anything, the default is REQUIRE_ORDER if the environment variable POSIXLY_CORRECT is defined, PERMUTE otherwise. REQUIRE_ORDER means don't recognize them as options; stop option processing when the first non-option is seen. This is what Unix does. This mode of operation is selected by either setting the environment variable POSIXLY_CORRECT, or using `+' as the first character of the list of option characters. PERMUTE is the default. We permute the contents of ARGV as we scan, so that eventually all the non-options are at the end. This allows options to be given in any order, even with programs that were not written to expect this. RETURN_IN_ORDER is an option available to programs that were written to expect options and other ARGV-elements in any order and that care about the ordering of the two. We describe each non-option ARGV-element as if it were the argument of an option with character code 1. Using `-' as the first character of the list of option characters selects this mode of operation. The special argument `--' forces an end of option-scanning regardless of the value of `ordering'. In the case of RETURN_IN_ORDER, only `--' can cause `getopt' to return -1 with `optind' != ARGC. */ static enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering; /* Value of POSIXLY_CORRECT environment variable. */ static char *posixly_correct; #ifdef __GNU_LIBRARY__ /* We want to avoid inclusion of string.h with non-GNU libraries because there are many ways it can cause trouble. On some systems, it contains special magic macros that don't work in GCC. */ # include # define my_index strchr #else # if HAVE_STRING_H # include # else # include # endif /* Avoid depending on library functions or files whose names are inconsistent. */ #ifndef getenv extern char *getenv (); #endif static char * my_index (str, chr) const char *str; int chr; { while (*str) { if (*str == chr) return (char *) str; str++; } return 0; } /* If using GCC, we can safely declare strlen this way. If not using GCC, it is ok not to declare it. */ #ifdef __GNUC__ /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. That was relevant to code that was here before. */ # if (!defined __STDC__ || !__STDC__) && !defined strlen /* gcc with -traditional declares the built-in strlen to return int, and has done so at least since version 2.4.5. -- rms. */ extern int strlen (const char *); # endif /* not __STDC__ */ #endif /* __GNUC__ */ #endif /* not __GNU_LIBRARY__ */ /* Handle permutation of arguments. */ /* Describe the part of ARGV that contains non-options that have been skipped. `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is the index after the last of them. */ static int first_nonopt; static int last_nonopt; #ifdef _LIBC /* Bash 2.0 gives us an environment variable containing flags indicating ARGV elements that should not be considered arguments. */ /* Defined in getopt_init.c */ extern char *__getopt_nonoption_flags; static int nonoption_flags_max_len; static int nonoption_flags_len; static int original_argc; static char *const *original_argv; /* Make sure the environment variable bash 2.0 puts in the environment is valid for the getopt call we must make sure that the ARGV passed to getopt is that one passed to the process. */ static void __attribute__ ((unused)) store_args_and_env (int argc, char *const *argv) { /* XXX This is no good solution. We should rather copy the args so that we can compare them later. But we must not use malloc(3). */ original_argc = argc; original_argv = argv; } # ifdef text_set_element text_set_element (__libc_subinit, store_args_and_env); # endif /* text_set_element */ # define SWAP_FLAGS(ch1, ch2) \ if (nonoption_flags_len > 0) \ { \ char __tmp = __getopt_nonoption_flags[ch1]; \ __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ __getopt_nonoption_flags[ch2] = __tmp; \ } #else /* !_LIBC */ # define SWAP_FLAGS(ch1, ch2) #endif /* _LIBC */ /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) which contains all the non-options that have been skipped so far. The other is elements [last_nonopt,optind), which contains all the options processed since those non-options were skipped. `first_nonopt' and `last_nonopt' are relocated so that they describe the new indices of the non-options in ARGV after they are moved. */ #if defined __STDC__ && __STDC__ static void exchange (char **); #endif static void exchange (argv) char **argv; { int bottom = first_nonopt; int middle = last_nonopt; int top = optind; char *tem; /* Exchange the shorter segment with the far end of the longer segment. That puts the shorter segment into the right place. It leaves the longer segment in the right place overall, but it consists of two parts that need to be swapped next. */ #ifdef _LIBC /* First make sure the handling of the `__getopt_nonoption_flags' string can work normally. Our top argument must be in the range of the string. */ if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) { /* We must extend the array. The user plays games with us and presents new arguments. */ char *new_str = malloc (top + 1); if (new_str == NULL) nonoption_flags_len = nonoption_flags_max_len = 0; else { memset (__mempcpy (new_str, __getopt_nonoption_flags, nonoption_flags_max_len), '\0', top + 1 - nonoption_flags_max_len); nonoption_flags_max_len = top + 1; __getopt_nonoption_flags = new_str; } } #endif while (top > middle && middle > bottom) { if (top - middle > middle - bottom) { /* Bottom segment is the short one. */ int len = middle - bottom; register int i; /* Swap it with the top part of the top segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[top - (middle - bottom) + i]; argv[top - (middle - bottom) + i] = tem; SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); } /* Exclude the moved bottom segment from further swapping. */ top -= len; } else { /* Top segment is the short one. */ int len = top - middle; register int i; /* Swap it with the bottom part of the bottom segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[middle + i]; argv[middle + i] = tem; SWAP_FLAGS (bottom + i, middle + i); } /* Exclude the moved top segment from further swapping. */ bottom += len; } } /* Update records for the slots the non-options now occupy. */ first_nonopt += (optind - last_nonopt); last_nonopt = optind; } /* Initialize the internal data when the first call is made. */ #if defined __STDC__ && __STDC__ static const char *_getopt_initialize (int, char *const *, const char *); #endif static const char * _getopt_initialize (argc, argv, optstring) int argc; char *const *argv; const char *optstring; { /* Start processing options with ARGV-element 1 (since ARGV-element 0 is the program name); the sequence of previously skipped non-option ARGV-elements is empty. */ first_nonopt = last_nonopt = optind; nextchar = NULL; posixly_correct = getenv ("POSIXLY_CORRECT"); /* Determine how to handle the ordering of options and nonoptions. */ if (optstring[0] == '-') { ordering = RETURN_IN_ORDER; ++optstring; } else if (optstring[0] == '+') { ordering = REQUIRE_ORDER; ++optstring; } else if (posixly_correct != NULL) ordering = REQUIRE_ORDER; else ordering = PERMUTE; #ifdef _LIBC if (posixly_correct == NULL && argc == original_argc && argv == original_argv) { if (nonoption_flags_max_len == 0) { if (__getopt_nonoption_flags == NULL || __getopt_nonoption_flags[0] == '\0') nonoption_flags_max_len = -1; else { const char *orig_str = __getopt_nonoption_flags; int len = nonoption_flags_max_len = strlen (orig_str); if (nonoption_flags_max_len < argc) nonoption_flags_max_len = argc; __getopt_nonoption_flags = (char *) malloc (nonoption_flags_max_len); if (__getopt_nonoption_flags == NULL) nonoption_flags_max_len = -1; else memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), '\0', nonoption_flags_max_len - len); } } nonoption_flags_len = nonoption_flags_max_len; } else nonoption_flags_len = 0; #endif return optstring; } /* Scan elements of ARGV (whose length is ARGC) for option characters given in OPTSTRING. If an element of ARGV starts with '-', and is not exactly "-" or "--", then it is an option element. The characters of this element (aside from the initial '-') are option characters. If `getopt' is called repeatedly, it returns successively each of the option characters from each of the option elements. If `getopt' finds another option character, it returns that character, updating `optind' and `nextchar' so that the next call to `getopt' can resume the scan with the following option character or ARGV-element. If there are no more option characters, `getopt' returns -1. Then `optind' is the index in ARGV of the first ARGV-element that is not an option. (The ARGV-elements have been permuted so that those that are not options now come last.) OPTSTRING is a string containing the legitimate option characters. If an option character is seen that is not listed in OPTSTRING, return '?' after printing an error message. If you set `opterr' to zero, the error message is suppressed but we still return '?'. If a char in OPTSTRING is followed by a colon, that means it wants an arg, so the following text in the same ARGV-element, or the text of the following ARGV-element, is returned in `optarg'. Two colons mean an option that wants an optional arg; if there is text in the current ARGV-element, it is returned in `optarg', otherwise `optarg' is set to zero. If OPTSTRING starts with `-' or `+', it requests different methods of handling the non-option ARGV-elements. See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. Long-named options begin with `--' instead of `-'. Their names may be abbreviated as long as the abbreviation is unique or is an exact match for some defined option. If they have an argument, it follows the option name in the same ARGV-element, separated from the option name by a `=', or else the in next ARGV-element. When `getopt' finds a long-named option, it returns 0 if that option's `flag' field is nonzero, the value of the option's `val' field if the `flag' field is zero. The elements of ARGV aren't really const, because we permute them. But we pretend they're const in the prototype to be compatible with other systems. LONGOPTS is a vector of `struct option' terminated by an element containing a name which is zero. LONGIND returns the index in LONGOPT of the long-named option found. It is only valid when a long-named option has been found by the most recent call. If LONG_ONLY is nonzero, '-' as well as '--' can introduce long-named options. */ int _getopt_internal (argc, argv, optstring, longopts, longind, long_only) int argc; char *const *argv; const char *optstring; const struct option *longopts; int *longind; int long_only; { int print_errors = opterr; if (optstring[0] == ':') print_errors = 0; optarg = NULL; if (optind == 0 || !__getopt_initialized) { if (optind == 0) optind = 1; /* Don't scan ARGV[0], the program name. */ optstring = _getopt_initialize (argc, argv, optstring); __getopt_initialized = 1; } /* Test whether ARGV[optind] points to a non-option argument. Either it does not have option syntax, or there is an environment flag from the shell indicating it is not an option. The later information is only used when the used in the GNU libc. */ #ifdef _LIBC # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ || (optind < nonoption_flags_len \ && __getopt_nonoption_flags[optind] == '1')) #else # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') #endif if (nextchar == NULL || *nextchar == '\0') { /* Advance to the next ARGV-element. */ /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been moved back by the user (who may also have changed the arguments). */ if (last_nonopt > optind) last_nonopt = optind; if (first_nonopt > optind) first_nonopt = optind; if (ordering == PERMUTE) { /* If we have just processed some options following some non-options, exchange them so that the options come first. */ if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (last_nonopt != optind) first_nonopt = optind; /* Skip any additional non-options and extend the range of non-options previously skipped. */ while (optind < argc && NONOPTION_P) optind++; last_nonopt = optind; } /* The special ARGV-element `--' means premature end of options. Skip it like a null option, then exchange with previous non-options as if it were an option, then skip everything else like a non-option. */ if (optind != argc && !strcmp (argv[optind], "--")) { optind++; if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (first_nonopt == last_nonopt) first_nonopt = optind; last_nonopt = argc; optind = argc; } /* If we have done all the ARGV-elements, stop the scan and back over any non-options that we skipped and permuted. */ if (optind == argc) { /* Set the next-arg-index to point at the non-options that we previously skipped, so the caller will digest them. */ if (first_nonopt != last_nonopt) optind = first_nonopt; return -1; } /* If we have come to a non-option and did not permute it, either stop the scan or describe it to the caller and pass it by. */ if (NONOPTION_P) { if (ordering == REQUIRE_ORDER) return -1; optarg = argv[optind++]; return 1; } /* We have found another option-ARGV-element. Skip the initial punctuation. */ nextchar = (argv[optind] + 1 + (longopts != NULL && argv[optind][1] == '-')); } /* Decode the current option-ARGV-element. */ /* Check whether the ARGV-element is a long option. If long_only and the ARGV-element has the form "-f", where f is a valid short option, don't consider it an abbreviated form of a long option that starts with f. Otherwise there would be no way to give the -f short option. On the other hand, if there's a long option "fubar" and the ARGV-element is "-fu", do consider that an abbreviation of the long option, just like "--fu", and not "-f" with arg "u". This distinction seems to be the most useful approach. */ if (longopts != NULL && (argv[optind][1] == '-' || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) { char *nameend; const struct option *p; const struct option *pfound = NULL; int exact = 0; int ambig = 0; int indfound = -1; int option_index; for (nameend = nextchar; *nameend && *nameend != '='; nameend++) /* Do nothing. */ ; /* Test all long options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp (p->name, nextchar, nameend - nextchar)) { if ((unsigned int) (nameend - nextchar) == (unsigned int) strlen (p->name)) { /* Exact match found. */ pfound = p; indfound = option_index; exact = 1; break; } else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else /* Second or later nonexact match found. */ ambig = 1; } if (ambig && !exact) { if (print_errors) fprintf (stderr, _("%s: option `%s' is ambiguous\n"), argv[0], argv[optind]); nextchar += strlen (nextchar); optind++; optopt = 0; return '?'; } if (pfound != NULL) { option_index = indfound; optind++; if (*nameend) { /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */ if (pfound->has_arg) optarg = nameend + 1; else { if (print_errors) { if (argv[optind - 1][1] == '-') /* --option */ fprintf (stderr, _("%s: option `--%s' doesn't allow an argument\n"), argv[0], pfound->name); else /* +option or -option */ fprintf (stderr, _("%s: option `%c%s' doesn't allow an argument\n"), argv[0], argv[optind - 1][0], pfound->name); } nextchar += strlen (nextchar); optopt = pfound->val; return '?'; } } else if (pfound->has_arg == 1) { if (optind < argc) optarg = argv[optind++]; else { if (print_errors) fprintf (stderr, _("%s: option `%s' requires an argument\n"), argv[0], argv[optind - 1]); nextchar += strlen (nextchar); optopt = pfound->val; return optstring[0] == ':' ? ':' : '?'; } } nextchar += strlen (nextchar); if (longind != NULL) *longind = option_index; if (pfound->flag) { *(pfound->flag) = pfound->val; return 0; } return pfound->val; } /* Can't find it as a long option. If this is not getopt_long_only, or the option starts with '--' or is not a valid short option, then it's an error. Otherwise interpret it as a short option. */ if (!long_only || argv[optind][1] == '-' || my_index (optstring, *nextchar) == NULL) { if (print_errors) { if (argv[optind][1] == '-') /* --option */ fprintf (stderr, _("%s: unrecognized option `--%s'\n"), argv[0], nextchar); else /* +option or -option */ fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), argv[0], argv[optind][0], nextchar); } nextchar = (char *) ""; optind++; optopt = 0; return '?'; } } /* Look at and handle the next short option-character. */ { char c = *nextchar++; char *temp = my_index (optstring, c); /* Increment `optind' when we start to process its last character. */ if (*nextchar == '\0') ++optind; if (temp == NULL || c == ':') { if (print_errors) { if (posixly_correct) /* 1003.2 specifies the format of this message. */ fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c); else fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c); } optopt = c; return '?'; } /* Convenience. Treat POSIX -W foo same as long option --foo */ if (temp[0] == 'W' && temp[1] == ';') { char *nameend; const struct option *p; const struct option *pfound = NULL; int exact = 0; int ambig = 0; int indfound = 0; int option_index; /* This is an option that requires an argument. */ if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ optind++; } else if (optind == argc) { if (print_errors) { /* 1003.2 specifies the format of this message. */ fprintf (stderr, _("%s: option requires an argument -- %c\n"), argv[0], c); } optopt = c; if (optstring[0] == ':') c = ':'; else c = '?'; return c; } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ optarg = argv[optind++]; /* optarg is now the argument, see if it's in the table of longopts. */ for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) /* Do nothing. */ ; /* Test all long options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp (p->name, nextchar, nameend - nextchar)) { if ((unsigned int) (nameend - nextchar) == strlen (p->name)) { /* Exact match found. */ pfound = p; indfound = option_index; exact = 1; break; } else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else /* Second or later nonexact match found. */ ambig = 1; } if (ambig && !exact) { if (print_errors) fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), argv[0], argv[optind]); nextchar += strlen (nextchar); optind++; return '?'; } if (pfound != NULL) { option_index = indfound; if (*nameend) { /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */ if (pfound->has_arg) optarg = nameend + 1; else { if (print_errors) fprintf (stderr, _("\ %s: option `-W %s' doesn't allow an argument\n"), argv[0], pfound->name); nextchar += strlen (nextchar); return '?'; } } else if (pfound->has_arg == 1) { if (optind < argc) optarg = argv[optind++]; else { if (print_errors) fprintf (stderr, _("%s: option `%s' requires an argument\n"), argv[0], argv[optind - 1]); nextchar += strlen (nextchar); return optstring[0] == ':' ? ':' : '?'; } } nextchar += strlen (nextchar); if (longind != NULL) *longind = option_index; if (pfound->flag) { *(pfound->flag) = pfound->val; return 0; } return pfound->val; } nextchar = NULL; return 'W'; /* Let the application handle it. */ } if (temp[1] == ':') { if (temp[2] == ':') { /* This is an option that accepts an argument optionally. */ if (*nextchar != '\0') { optarg = nextchar; optind++; } else optarg = NULL; nextchar = NULL; } else { /* This is an option that requires an argument. */ if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ optind++; } else if (optind == argc) { if (print_errors) { /* 1003.2 specifies the format of this message. */ fprintf (stderr, _("%s: option requires an argument -- %c\n"), argv[0], c); } optopt = c; if (optstring[0] == ':') c = ':'; else c = '?'; } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ optarg = argv[optind++]; nextchar = NULL; } } return c; } } int getopt (argc, argv, optstring) int argc; char *const *argv; const char *optstring; { return _getopt_internal (argc, argv, optstring, (const struct option *) 0, (int *) 0, 0); } #endif /* Not ELIDE_CODE. */ #ifdef TEST /* Compile with -DTEST to make an executable for use in testing the above definition of `getopt'. */ int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; c = getopt (argc, argv, "abc:d:0123456789"); if (c == -1) break; switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ proftpd-dfsg-1.3.5~rc3/lib/getopt.h0000644000175000017500000001351111566543471017003 0ustar frankiefrankie/* Declarations for getopt. Copyright (C) 1989,90,91,92,93,94,96,97,98 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. */ #ifndef PR_USE_SYSTEM_GETOPT #ifndef _GETOPT_H #ifndef __need_getopt # define _GETOPT_H 1 #endif #ifdef __cplusplus extern "C" { #endif /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ extern char *optarg; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns -1, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ extern int optind; /* Callers store zero here to inhibit the error message `getopt' prints for unrecognized options. */ extern int opterr; /* Set to an option character which was unrecognized. */ extern int optopt; #ifndef __need_getopt /* Describe the long-named options requested by the application. The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector of `struct option' terminated by an element containing a name which is zero. The field `has_arg' is: no_argument (or 0) if the option does not take an argument, required_argument (or 1) if the option requires an argument, optional_argument (or 2) if the option takes an optional argument. If the field `flag' is not NULL, it points to a variable that is set to the value given in the field `val' when the option is found, but left unchanged if the option is not found. To have a long-named option do something other than set an `int' to a compiled-in constant, such as set a value from `optarg', set the option's `flag' field to zero and its `val' field to a nonzero value (the equivalent single-letter option character, if there is one). For long options that have a zero `flag' field, `getopt' returns the contents of the `val' field. */ struct option { # if defined __STDC__ && __STDC__ const char *name; # else char *name; # endif /* has_arg can't be an enum because some compilers complain about type mismatches in all the code that assumes it is an int. */ int has_arg; int *flag; int val; }; /* Names for the values of the `has_arg' field of `struct option'. */ # define no_argument 0 # define required_argument 1 # define optional_argument 2 #endif /* need getopt */ /* Get definitions and prototypes for functions to process the arguments in ARGV (ARGC of them, minus the program name) for options given in OPTS. Return the option character from OPTS just read. Return -1 when there are no more options. For unrecognized options, or options missing arguments, `optopt' is set to the option letter, and '?' is returned. The OPTS string is a list of characters which are recognized option letters, optionally followed by colons, specifying that that letter takes an argument, to be placed in `optarg'. If a letter in OPTS is followed by two colons, its argument is optional. This behavior is specific to the GNU `getopt'. The argument `--' causes premature termination of argument scanning, explicitly telling `getopt' that there are no more options. If OPTS begins with `--', then non-option arguments are treated as arguments to the option '\0'. This behavior is specific to the GNU `getopt'. */ #if defined(__cplusplus) || (defined (__STDC__) && __STDC__) # ifdef __GNU_LIBRARY__ /* Many other libraries have conflicting prototypes for getopt, with differences in the consts, in stdlib.h. To avoid compilation errors, only prototype getopt for the GNU C library. */ extern int getopt (int __argc, char *const *__argv, const char *__shortopts); # else /* not __GNU_LIBRARY__ */ /*extern int getopt ();*/ # endif /* __GNU_LIBRARY__ */ # ifndef __need_getopt extern int getopt_long (int __argc, char *const *__argv, const char *__shortopts, const struct option *__longopts, int *__longind); extern int getopt_long_only (int __argc, char *const *__argv, const char *__shortopts, const struct option *__longopts, int *__longind); /* Internal only. Users should not call this directly. */ extern int _getopt_internal (int __argc, char *const *__argv, const char *__shortopts, const struct option *__longopts, int *__longind, int __long_only); # endif #else /* not __STDC__ */ extern int getopt (); # ifndef __need_getopt extern int getopt_long (); extern int getopt_long_only (); extern int _getopt_internal (); # endif #endif /* __STDC__ */ #ifdef __cplusplus } #endif /* Make sure we later can get all the definitions and declarations. */ #undef __need_getopt #endif /* getopt.h */ #endif /* !PR_USE_SYSTEM_GETOPT */ proftpd-dfsg-1.3.5~rc3/lib/Makefile.in0000644000175000017500000000435312156653653017401 0ustar frankiefrankie@SET_MAKE@ top_srcdir=@top_srcdir@ srcdir=@srcdir@ VPATH=@srcdir@ include ../Make.rules LIB_DEPS=@LIB_DEPS@ LIB_OBJS=@LIB_OBJS@ "": dummy: all: @echo "Running make from top level directory." cd ../ && $(MAKE) all Makefile: Makefile.in ../config.status cd ../ && ./config.status .c.o: $(CC) $(CPPFLAGS) $(CFLAGS) -c $< libltdl: dummy cd libltdl/ && $(MAKE) libsupp.a: $(LIB_OBJS) $(AR) rc libsupp.a $(LIB_OBJS) $(RANLIB) libsupp.a lib: libsupp.a $(LIB_DEPS) install: clean: rm -f *.o libsupp.a test -z $(LIB_DEPS) || (cd libltdl/ && $(MAKE) clean) depend: makedepend $(CPPFLAGS) -Y *.c 2>/dev/null makedepend $(CPPFLAGS) -Y -fMakefile.in *.c 2>/dev/null distclean: test -z $(LIB_DEPS) || (cd libltdl/ && $(MAKE) distclean) # DO NOT DELETE getopt1.o: ../config.h getopt.h getopt.o: ../config.h getopt.h glibc-glob.o: ../config.h ../include/options.h ../include/glibc-glob.h glibc-hstrerror.o: ../include/conf.h ../include/version.h ../config.h glibc-hstrerror.o: ../include/default_paths.h ../include/options.h glibc-hstrerror.o: ../include/libsupp.h ../include/glibc-glob.h glibc-mkstemp.o: ../include/conf.h ../include/version.h ../config.h glibc-mkstemp.o: ../include/default_paths.h ../include/options.h glibc-mkstemp.o: ../include/libsupp.h ../include/glibc-glob.h pr_fnmatch.o: ../config.h ../include/conf.h ../include/version.h pr_fnmatch.o: ../include/default_paths.h ../include/options.h pr_fnmatch.o: ../include/libsupp.h ../include/glibc-glob.h pr_fnmatch_loop.c pr_fnmatch_loop.o: ../config.h pr-syslog.o: ../include/conf.h ../include/version.h ../config.h pr-syslog.o: ../include/default_paths.h ../include/options.h pwgrent.o: ../include/conf.h ../include/version.h ../config.h pwgrent.o: ../include/default_paths.h ../include/options.h pwgrent.o: ../include/libsupp.h ../include/glibc-glob.h sstrncpy.o: ../config.h ../include/libsupp.h ../include/glibc-glob.h strsep.o: ../include/conf.h ../include/version.h ../config.h strsep.o: ../include/default_paths.h ../include/options.h strsep.o: ../include/libsupp.h ../include/glibc-glob.h tpl.o: ../include/tpl.h vsnprintf.o: ../include/conf.h ../include/version.h ../config.h vsnprintf.o: ../include/default_paths.h ../include/options.h vsnprintf.o: ../include/libsupp.h ../include/glibc-glob.h proftpd-dfsg-1.3.5~rc3/lib/getopt1.c0000644000175000017500000001071011566546322017053 0ustar frankiefrankie/* getopt_long and getopt_long_only entry points for GNU getopt. Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. */ #ifdef HAVE_CONFIG_H #include #endif #include "getopt.h" #if !defined __STDC__ || !__STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ #ifndef const #define const #endif #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #define GETOPT_INTERFACE_VERSION 2 #if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 #include #if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION #define ELIDE_CODE #endif #endif #ifndef ELIDE_CODE /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ #include #endif #ifndef NULL #define NULL 0 #endif int getopt_long (argc, argv, options, long_options, opt_index) int argc; char *const *argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal (argc, argv, options, long_options, opt_index, 0); } /* Like getopt_long, but '-' as well as '--' can indicate a long option. If an option that starts with '-' (not '--') doesn't match a long option, but does match a short option, it is parsed as a short option instead. */ int getopt_long_only (argc, argv, options, long_options, opt_index) int argc; char *const *argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal (argc, argv, options, long_options, opt_index, 1); } #endif /* Not ELIDE_CODE. */ #ifdef TEST #include int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; int option_index = 0; static struct option long_options[] = { {"add", 1, 0, 0}, {"append", 0, 0, 0}, {"delete", 1, 0, 0}, {"verbose", 0, 0, 0}, {"create", 0, 0, 0}, {"file", 1, 0, 0}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "abc:d:0123456789", long_options, &option_index); if (c == -1) break; switch (c) { case 0: printf ("option %s", long_options[option_index].name); if (optarg) printf (" with arg %s", optarg); printf ("\n"); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case 'd': printf ("option d with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ proftpd-dfsg-1.3.5~rc3/lib/glibc-gai_strerror.c0000644000175000017500000000713711566546322021261 0ustar frankiefrankie/* Copyright (C) 1997,2001,02 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Philip Blundell , 1997. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. */ #include /* It's possible that doesn't define EAI_ values. */ #ifndef EAI_BADFLAGS # define EAI_BADFLAGS -1 /* Invalid value for `ai_flags' field. */ #endif #ifndef EAI_NONAME # define EAI_NONAME -2 /* NAME or SERVICE is unknown. */ #endif #ifndef EAI_AGAIN # define EAI_AGAIN -3 /* Temporary failure in name resolution. */ #endif #ifndef EAI_FAIL # define EAI_FAIL -4 /* Non-recoverable failure in name res. */ #endif #ifndef EAI_NODATA # define EAI_NODATA -5 /* No address associated with NAME. */ #endif #ifndef EAI_FAMILY # define EAI_FAMILY -6 /* `ai_family' not supported. */ #endif #ifndef EAI_SOCKTYPE # define EAI_SOCKTYPE -7 /* `ai_socktype' not supported. */ #endif #ifndef EAI_SERVICE # define EAI_SERVICE -8 /* SERVICE not supported for `ai_socktype'. */ #endif #ifndef EAI_ADDRFAMILY # define EAI_ADDRFAMILY -9 /* Address family for NAME not supported. */ #endif #ifndef EAI_MEMORY # define EAI_MEMORY -10 /* Memory allocation failure. */ #endif #ifndef EAI_SYSTEM # define EAI_SYSTEM -11 /* System error returned in `errno'. */ #endif /* GNU-specific EAI values. */ #ifndef EAI_INPROGRESS # define EAI_INPROGRESS -100 /* Processing request in progress. */ #endif #ifndef EAI_CANCELED # define EAI_CANCELED -101 /* Request canceled. */ #endif #ifndef EAI_NOTCANCELED # define EAI_NOTCANCELED -102 /* Request not canceled. */ #endif #ifndef EAI_ALLDONE # define EAI_ALLDONE -103 /* All requests done. */ #endif #ifndef EAI_INTR # define EAI_INTR -104 /* Interrupted by a signal. */ #endif static struct { int code; const char *msg; } values[] = { { EAI_ADDRFAMILY, "Address family for hostname not supported" }, { EAI_AGAIN, "Temporary failure in name resolution" }, { EAI_BADFLAGS, "Bad value for ai_flags" }, { EAI_FAIL, "Non-recoverable failure in name resolution" }, { EAI_FAMILY, "ai_family not supported" }, { EAI_MEMORY, "Memory allocation failure" }, { EAI_NODATA, "No address associated with hostname" }, { EAI_NONAME, "Name or service not known" }, { EAI_SERVICE, "Servname not supported for ai_socktype" }, { EAI_SOCKTYPE, "ai_socktype not supported" }, { EAI_SYSTEM, "System error" }, { EAI_INPROGRESS, "Processing request in progress" }, { EAI_CANCELED, "Request canceled" }, { EAI_NOTCANCELED, "Request not canceled" }, { EAI_ALLDONE, "All requests done" }, { EAI_INTR, "Interrupted by a signal" } }; const char *pr_gai_strerror(int code) { register unsigned int i; for (i = 0; i < sizeof(values) / sizeof(values[0]); ++i) if (values[i].code == code) return values[i].msg; return "Unknown error"; } proftpd-dfsg-1.3.5~rc3/lib/libcap/0000755000175000017500000000000012156653653016561 5ustar frankiefrankieproftpd-dfsg-1.3.5~rc3/lib/libcap/cap_alloc.c0000644000175000017500000000676311046354271020645 0ustar frankiefrankie/* * $Id: cap_alloc.c,v 1.3 2008/08/06 17:00:41 castaglia Exp $ * * Copyright (c) 1997-8 Andrew G Morgan * * See end of file for Log. * * This file deals with allocation and deallocation of internal * capability sets as specified by POSIX.1e (formerlly, POSIX 6). */ #include "libcap.h" /* * This function duplicates an internal capability set (x3) with * Obtain a blank set of capabilities */ cap_t cap_init(void) { __u32 *raw_data; cap_t result; raw_data = malloc( sizeof(__u32) + sizeof(*result) ); if (raw_data == NULL) { _cap_debug("out of memory"); errno = ENOMEM; return NULL; } *raw_data = CAP_T_MAGIC; result = (cap_t) (raw_data + 1); memset(result, 0, sizeof(*result)); result->head.version = _LINUX_CAPABILITY_VERSION_1; return result; } /* * This is an internal library function to duplicate a string and * tag the result as something cap_free can handle. */ char *_libcap_strdup(const char *old) { __u32 *raw_data; if (old == NULL) { errno = EINVAL; return NULL; } raw_data = malloc( sizeof(__u32) + strlen(old) + 1 ); if (raw_data == NULL) { errno = ENOMEM; return NULL; } *(raw_data++) = CAP_S_MAGIC; strcpy((char *) raw_data, old); return ((char *) raw_data); } /* * This function duplicates an internal capability set with * malloc()'d memory. It is the responsibility of the user to call * cap_free() to liberate it. */ cap_t cap_dup(cap_t cap_d) { cap_t result; if (!good_cap_t(cap_d)) { _cap_debug("bad argument"); errno = EINVAL; return NULL; } result = cap_init(); if (result == NULL) { _cap_debug("out of memory"); return NULL; } memcpy(result, cap_d, sizeof(*cap_d)); return result; } /* * Scrub and then liberate an internal capability set. */ int cap_free(void *data_p) { if ( good_cap_t(data_p) ) { data_p = -1 + (__u32 *) data_p; memset(data_p, 0, sizeof(__u32) + sizeof(struct _cap_struct)); free(data_p); data_p = NULL; return 0; } if ( good_cap_string(data_p) ) { int length = strlen(data_p) + sizeof(__u32); data_p = -1 + (__u32 *) data_p; memset(data_p, 0, length); free(data_p); data_p = NULL; return 0; } _cap_debug("don't recognize what we're supposed to liberate"); errno = EINVAL; return -1; } /* * $Log: cap_alloc.c,v $ * Revision 1.3 2008/08/06 17:00:41 castaglia * * Bug#3096 - libcap version errors on newer Linux kernel. Newer Linux kernels * have a _LINUX_CAPABILITY_VERSION_2 macro, and redefine the old * _LINUX_CAPABILITY_VERSION macro. To play better with such kernels, redefine * the bundled libcap to use _LINUX_CAPABILITY_VERSION_1. * * Revision 1.2 2003/05/15 00:49:13 castaglia * * Bug#2000 - mod_cap should not use bundled libcap. This patch updates the * bundled libcap; I won't be closing the bug report just yet. * * Revision 1.1 2003/01/03 02:16:17 jwm * * Turning mod_linuxprivs into a core module, mod_cap. This is by no means * complete. * * Revision 1.2 1999/09/07 23:14:19 macgyver * Updated capabilities library and model. * * Revision 1.1.1.1 1999/04/17 22:16:31 morgan * release 1.0 of libcap * * Revision 1.3 1998/05/24 22:54:09 morgan * updated for 2.1.104 * * Revision 1.2 1997/04/28 00:57:11 morgan * fixes and zefram's patches * * Revision 1.1 1997/04/21 04:32:52 morgan * Initial revision * */ proftpd-dfsg-1.3.5~rc3/lib/libcap/Makefile0000644000175000017500000000350307660562011020211 0ustar frankiefrankie## This libcap (for proftpd) is originally from libcap-1.10, ## at ftp://linux.kernel.org/pub/libs/security/linux-privs. ## This interface is SPECIFIC TO THE LINUX 2.2 KERNEL!!! IT IS NOT GUARANTEED ## TO WORK ON ANY PRIOR OR LATER VERSION (ie: 2.1.x or 2.3.x). ## If this library stops working, please contact core@proftpd.org. # # defines # topdir=$(shell pwd)/.. include ../../Make.rules # # Library version # LIBNAME=libcap.a # FILES=cap_alloc cap_proc cap_extint cap_flag cap_text cap_sys # for later when there is filesystem support for cap's: #FILES += cap_file INCLS=libcap.h cap_names.h $(INCS) OBJS=$(addsuffix .o, $(FILES)) all: $(LIBNAME) _makenames: _makenames.c cap_names.sed $(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ cap_names.h: _makenames ./_makenames > cap_names.h cap_names.sed: Makefile /usr/include/linux/capability.h @echo "=> making cap_names.c from " @sed -ne '/^#define[ \t]CAP[_A-Z]\+[ \t]\+[0-9]\+/{s/^#define \([^ \t]*\)[ \t]*\([^ \t]*\)/ \{ \2, \"\1\" \},/;y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/;p;}' < /usr/include/linux/capability.h | fgrep -v 0x > cap_names.sed # @sed -ne '/^#define[ \t]CAP[_A-Z]\+[ \t]\+[0-9]\+/{s/^#define CAP_\([^ \t]*\)[ \t]*\([^ \t]*\)/ \{ \2, \"\1\" \},/;y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/;p;}' < /usr/include/linux/capability.h | fgrep -v 0x > cap_names.sed $(LIBNAME): $(OBJS) ar rcu $@ $(OBJS) %.o: %.c $(INCLS) $(CC) $(CFLAGS) -c $< -o $@ install: all mkdir -p -m 0755 $(INCDIR)/sys install -m 0644 include/sys/capability.h $(INCDIR)/sys mkdir -p -m 0755 $(LIBDIR) install -m 0644 $(MINLIBNAME) $(LIBDIR)/$(MINLIBNAME) ln -sf $(MINLIBNAME) $(LIBDIR)/$(MAJLIBNAME) ln -sf $(MAJLIBNAME) $(LIBDIR)/$(LIBNAME) -/sbin/ldconfig clean: $(LOCALCLEAN) rm -f $(OBJS) $(LIBNAME)* rm -f cap_names.h cap_names.sed _makenames proftpd-dfsg-1.3.5~rc3/lib/libcap/cap_sys.c0000644000175000017500000000203710175517157020365 0ustar frankiefrankie/* * $Id: cap_sys.c,v 1.2 2005/01/25 19:30:55 castaglia Exp $ * * Copyright (c) 1997-8 Andrew G. Morgan * * This file contains the system calls for getting and setting * capabilities */ #include "libcap.h" #define __LIBRARY__ #include /* * $Log: cap_sys.c,v $ * Revision 1.2 2005/01/25 19:30:55 castaglia * * Bug#2503 - Bundled libcap library does not compile on IA64 machine. * * Revision 1.1 2003/01/03 02:16:17 jwm * * Turning mod_linuxprivs into a core module, mod_cap. This is by no means * complete. * * Revision 1.3 1999/09/07 23:14:19 macgyver * Updated capabilities library and model. * * Revision 1.1.1.1 1999/04/17 22:16:31 morgan * release 1.0 of libcap * * Revision 1.4 1998/06/08 00:14:01 morgan * change to accommodate alpha (glibc?) * * Revision 1.3 1998/05/24 22:54:09 morgan * updated for 2.1.104 * * Revision 1.2 1997/04/28 00:57:11 morgan * fixes and zefram's patches * * Revision 1.1 1997/04/21 04:32:52 morgan * Initial revision * */ proftpd-dfsg-1.3.5~rc3/lib/libcap/cap_extint.c0000644000175000017500000000732307605171161021060 0ustar frankiefrankie/* * $Id: cap_extint.c,v 1.1 2003/01/03 02:16:17 jwm Exp $ * * Copyright (c) 1997-8 Andrew G Morgan * * See end of file for Log. * * This file deals with exchanging internal and external * representations of capability sets. */ #include "libcap.h" /* * External representation for capabilities. (exported as a fixed * length (void *)) */ #define CAP_EXT_MAGIC "\220\302\001\121" #define CAP_EXT_MAGIC_SIZE 4 const static __u8 external_magic[CAP_EXT_MAGIC_SIZE+1] = CAP_EXT_MAGIC; struct cap_ext_struct { __u8 magic[CAP_EXT_MAGIC_SIZE]; __u8 length_of_capset; /* note, we arrange these so the caps are stacked with byte-size resolution */ __u8 bytes[CAP_SET_SIZE][NUMBER_OF_CAP_SETS]; }; /* * return size of external capability set */ ssize_t cap_size(cap_t caps) { return sizeof(struct cap_ext_struct); } /* * Copy the internal (cap_d) capability set into an external * representation. The external representation is portable to other * Linux architectures. */ ssize_t cap_copy_ext(void *cap_ext, cap_t cap_d, ssize_t length) { struct cap_ext_struct *result = (struct cap_ext_struct *) cap_ext; __u32 *from = (__u32 *) &(cap_d->set); int i; /* valid arguments? */ if (!good_cap_t(cap_d) || length < sizeof(struct cap_ext_struct) || cap_ext == NULL) { errno = EINVAL; return -1; } /* fill external capability set */ memcpy(&result->magic, external_magic, CAP_EXT_MAGIC_SIZE); result->length_of_capset = CAP_SET_SIZE; for (i=0; ibytes[j++][i] = val & 0xFF; result->bytes[j++][i] = (val >>= 8) & 0xFF; result->bytes[j++][i] = (val >>= 8) & 0xFF; result->bytes[j++][i] = (val >> 8) & 0xFF; } } /* All done: return length of external representation */ return (sizeof(struct cap_ext_struct)); } /* * Import an external representation to produce an internal rep. * the internal rep should be liberated with cap_free(). */ /* * XXX - need to take a little more care when importing small * capability sets. */ cap_t cap_copy_int(const void *cap_ext) { const struct cap_ext_struct *export = (const struct cap_ext_struct *) cap_ext; cap_t cap_d = NULL; int set, blen; __u32 * to = (__u32 *) &cap_d->set; /* Does the external representation make sense? */ if (export == NULL || !memcmp(export->magic, external_magic , CAP_EXT_MAGIC_SIZE)) { errno = EINVAL; return NULL; } /* Obtain a new internal capability set */ if (!(cap_d = cap_init())) return NULL; blen = export->length_of_capset; for (set=0; set<=NUMBER_OF_CAP_SETS; ++set) { int blk; int bno = 0; for (blk=0; blk<(CAP_SET_SIZE/4); ++blk) { __u32 val = 0; if (bno != blen) val = export->bytes[bno++][set]; if (bno != blen) val |= export->bytes[bno++][set] << 8; if (bno != blen) val |= export->bytes[bno++][set] << 16; if (bno != blen) val |= export->bytes[bno++][set] << 24; *to++ = val; } } /* all done */ return cap_d; } /* * $Log: cap_extint.c,v $ * Revision 1.1 2003/01/03 02:16:17 jwm * * Turning mod_linuxprivs into a core module, mod_cap. This is by no means * complete. * * Revision 1.3 1999/09/17 03:54:08 macgyver * Corrected gcc warning. * * Revision 1.2 1999/09/07 23:14:19 macgyver * Updated capabilities library and model. * * Revision 1.1.1.1 1999/04/17 22:16:31 morgan * release 1.0 of libcap * * Revision 1.3 1998/05/24 22:54:09 morgan * updated for 2.1.104 * * Revision 1.2 1997/04/28 00:57:11 morgan * fixes and zefram's patches * * Revision 1.1 1997/04/21 04:32:52 morgan * Initial revision * */ proftpd-dfsg-1.3.5~rc3/lib/libcap/cap_file.c0000644000175000017500000000541307605171161020462 0ustar frankiefrankie/* * $Id: cap_file.c,v 1.1 2003/01/03 02:16:17 jwm Exp $ * * Copyright (c) 1997 Andrew G Morgan * * See end of file for Log. * * This file deals with setting capabilities on files. */ #include "libcap.h" /* * Get the capabilities of an open file, as specified by its file * descriptor. */ cap_t cap_get_fd(int fildes) { cap_t result; /* allocate a new capability set */ result = cap_init(); if (result) { _cap_debug("getting fildes capabilities"); /* fill the capability sets via a system call */ if (_fgetfilecap(fildes, sizeof(struct __cap_s), &result->set[CAP_INHERITABLE], &result->set[CAP_PERMITTED], &result->set[CAP_EFFECTIVE] )) { cap_free(&result); } } return result; } /* * Set the capabilities on a named file. */ cap_t cap_get_file(const char *filename) { cap_t result; /* allocate a new capability set */ result = cap_init(); if (result) { _cap_debug("getting named file capabilities"); /* fill the capability sets via a system call */ if (_getfilecap(filename, sizeof(struct __cap_s), &result->set[CAP_INHERITABLE], &result->set[CAP_PERMITTED], &result->set[CAP_EFFECTIVE] )) cap_free(&result); } return result; } /* * Set the capabilities of an open file, as specified by its file * descriptor. */ int cap_set_fd(int fildes, cap_t cap_d) { if (!good_cap_t(cap_d)) { errno = EINVAL; return -1; } _cap_debug("setting fildes capabilities"); return _fsetfilecap(fildes, sizeof(struct __cap_s), &cap_d->set[CAP_INHERITABLE], &cap_d->set[CAP_PERMITTED], &cap_d->set[CAP_EFFECTIVE] ); } /* * Set the capabilities of a named file. */ int cap_set_file(const char *filename, cap_t cap_d) { if (!good_cap_t(cap_d)) { errno = EINVAL; return -1; } _cap_debug("setting filename capabilities"); return _setfilecap(filename, sizeof(struct __cap_s), &cap_d->set[CAP_INHERITABLE], &cap_d->set[CAP_PERMITTED], &cap_d->set[CAP_EFFECTIVE] ); } /* * $Log: cap_file.c,v $ * Revision 1.1 2003/01/03 02:16:17 jwm * * Turning mod_linuxprivs into a core module, mod_cap. This is by no means * complete. * * Revision 1.1 1999/09/07 23:14:19 macgyver * Updated capabilities library and model. * * Revision 1.1.1.1 1999/04/17 22:16:31 morgan * release 1.0 of libcap * * Revision 1.5 1998/05/24 22:54:09 morgan * updated for 2.1.104 * * Revision 1.4 1997/05/14 05:17:13 morgan * bug-fix from zefram (errno no set on success) * * Revision 1.3 1997/05/04 05:35:46 morgan * fixed errno setting. syscalls do this part * * Revision 1.2 1997/04/28 00:57:11 morgan * fixes and zefram's patches * * Revision 1.1 1997/04/21 04:32:52 morgan * Initial revision * */ proftpd-dfsg-1.3.5~rc3/lib/libcap/cap_flag.c0000644000175000017500000000556207605171161020461 0ustar frankiefrankie/* * $Id: cap_flag.c,v 1.1 2003/01/03 02:16:17 jwm Exp $ * * Copyright (c) 1997-8 Andrew G. Morgan * * See end of file for Log. * * This file deals with flipping of capabilities on internal * capability sets as specified by POSIX.1e (formerlly, POSIX 6). */ #include "libcap.h" /* * Return the state of a specified capability flag. The state is * returned as the contents of *raised. The capability is from one of * the sets stored in cap_d as specified by set and value */ int cap_get_flag(cap_t cap_d, cap_value_t value, cap_flag_t set, cap_flag_value_t *raised) { /* * Do we have a set and a place to store its value? * Is it a known capability? */ if (raised && good_cap_t(cap_d) && value >= 0 && value < __CAP_BITS && set >= 0 && set < NUMBER_OF_CAP_SETS) { __cap_s *cap_p = (__cap_s *) (set*CAP_SET_SIZE + (__u8 *) &cap_d->set); *raised = isset_cap(cap_p,value) ? CAP_SET:CAP_CLEAR; return 0; } else { _cap_debug("invalid arguments"); errno = EINVAL; return -1; } } /* * raise/lower a selection of capabilities */ int cap_set_flag(cap_t cap_d, cap_flag_t set, int no_values, cap_value_t *array_values, cap_flag_value_t raise) { /* * Do we have a set and a place to store its value? * Is it a known capability? */ if (good_cap_t(cap_d) && no_values > 0 && no_values <= __CAP_BITS && (set >= 0) && (set < NUMBER_OF_CAP_SETS) && (raise == CAP_SET || raise == CAP_CLEAR) ) { int i; for (i=0; i= __CAP_BITS) { _cap_debug("weird capability (%d) - skipped", array_values[i]); } else { int value = array_values[i]; __cap_s *cap_p = (__cap_s *) (set*CAP_SET_SIZE + (__u8 *) &cap_d->set); if (raise == CAP_SET) { cap_p->raise_cap(value); } else { cap_p->lower_cap(value); } } } return 0; } else { _cap_debug("invalid arguments"); errno = EINVAL; return -1; } } /* * Reset the capability to be empty (nothing raised) */ int cap_clear(cap_t cap_d) { if (good_cap_t(cap_d)) { memset(&(cap_d->set), 0, sizeof(cap_d->set)); return 0; } else { _cap_debug("invalid pointer"); errno = EINVAL; return -1; } } /* * $Log: cap_flag.c,v $ * Revision 1.1 2003/01/03 02:16:17 jwm * * Turning mod_linuxprivs into a core module, mod_cap. This is by no means * complete. * * Revision 1.2 1999/09/07 23:14:19 macgyver * Updated capabilities library and model. * * Revision 1.1.1.1 1999/04/17 22:16:31 morgan * release 1.0 of libcap * * Revision 1.4 1998/09/20 23:07:59 morgan * fixed lower bound check on 'set'. * * Revision 1.3 1998/05/24 22:54:09 morgan * updated for 2.1.104 * * Revision 1.2 1997/04/28 00:57:11 morgan * fixes and zefram's patches * * Revision 1.1 1997/04/21 04:32:52 morgan * Initial revision * */ proftpd-dfsg-1.3.5~rc3/lib/libcap/libcap.h0000644000175000017500000001246411053675314020164 0ustar frankiefrankie/* * $Id: libcap.h,v 1.5 2008/08/23 02:49:48 castaglia Exp $ * * Copyright (c) 1997 Andrew G Morgan * * See end of file for Log. * * This file contains internal definitions for the various functions in * this small capability library. */ #ifndef LIBCAP_H #define LIBCAP_H #include #include #include #include #include "include/sys/capability.h" #ifndef __u8 #define __u8 unsigned char #endif /* __8 */ #ifndef __u32 #define __u32 unsigned int #endif /* __u32 */ /* include the names for the caps and a definition of __CAP_BITS */ #include "cap_names.h" /* * This is a pointer to a struct containing three consecutive * capability sets in the order of the cap_flag_t type: the are * effective,inheritable and permitted. This is the type that the * user-space routines think of as 'internal' capabilities - this is * the type that is passed to the kernel with the system calls related * to processes. */ #define CAP_T_MAGIC 0xCA90D0 struct _cap_struct { struct __user_cap_header_struct head; struct __user_cap_data_struct set; }; /* string magic for cap_free */ #define CAP_S_MAGIC 0xCA95D0 /* Older Linux kernels only define _LINUX_CAPABILITY_VERSION. Newer Linux * kernels use _LINUX_CAPABILITY_VERSION_1 and _LINUX_CAPABILITY_VERSION_2, * and define _LINUX_CAPABILITY_VERSION to be _LINUX_CAPABILITY_VERSION_2. * This means that, for proper compilation and functioning on the newer * kernels, we need to use _LINUX_CAPABILITY_VERSION_1. But to make sure * we still compile on the older Linux kernels, we need to make define * our own _LINUX_CAPABILITY_VERSION_1 to be _LINUX_CAPABILITY_VERSION. */ #if !defined(_LINUX_CAPABILITY_VERSION_1) && \ defined(_LINUX_CAPABILITY_VERSION) # define _LINUX_CAPABILITY_VERSION_1 _LINUX_CAPABILITY_VERSION #endif /* * Do we match the local kernel? */ #if !defined(_LINUX_CAPABILITY_VERSION_1) || \ (_LINUX_CAPABILITY_VERSION_1 != 0x19980330) # error "Kernel does not match library" # error "file "libcap.h" --> fix and recompile libcap" #endif /* * kernel API cap set abstraction */ #define NUMBER_OF_CAP_SETS 3 /* effective, inheritable, permitted */ #define CAP_SET_SIZE (sizeof(struct __user_cap_data_struct)/NUMBER_OF_CAP_SETS) #define __CAP_BLKS (CAP_SET_SIZE/sizeof(__u32)) typedef struct { __u32 _blk[__CAP_BLKS]; } __cap_s; #define raise_cap(x) _blk[(x)>>5] |= (1<<((x)&31)) #define lower_cap(x) _blk[(x)>>5] &= ~(1<<((x)&31)) #define isset_cap(y,x) ((y)->_blk[(x)>>5] & (1<<((x)&31))) /* * Private definitions for internal use by the library. */ #define __libcap_check_magic(c,magic) ((c) && *(-1+(__u32 *)(c)) == (magic)) #define good_cap_t(c) __libcap_check_magic(c, CAP_T_MAGIC) #define good_cap_string(c) __libcap_check_magic(c, CAP_S_MAGIC) /* * library debugging */ #ifdef DEBUG #include # define _cap_debug(f, x...) { \ fprintf(stderr, __FUNCTION__ "(" __FILE__ ":%d): ", __LINE__); \ fprintf(stderr, f, ## x); \ fprintf(stderr, "\n"); \ } # define _cap_debugcap(s, c) \ fprintf(stderr, __FUNCTION__ "(" __FILE__ ":%d): " s \ "%08x\n", __LINE__, *(c)) #else /* !DEBUG */ # define _cap_debug(f, x...) # define _cap_debugcap(s, c) #endif /* DEBUG */ extern char *_libcap_strdup(const char *text); /* * These are semi-public prototypes, they will only be defined in * if _POSIX_SOURCE is not #define'd, so we * place them here too. */ extern int capset(cap_user_header_t header, cap_user_data_t data); extern int capget(cap_user_header_t header, const cap_user_data_t data); extern int capgetp(pid_t pid, cap_t cap_d); extern int capsetp(pid_t pid, cap_t cap_d); #endif /* LIBCAP_H */ /* * $Log: libcap.h,v $ * Revision 1.5 2008/08/23 02:49:48 castaglia * * Fix typo (missing backslash). * * Revision 1.4 2008/08/22 16:35:52 castaglia * * Try to handle the change in Linux capability version macro names for * older kernels (which don't define/use the new names). * * Revision 1.3 2008/08/06 17:00:41 castaglia * * Bug#3096 - libcap version errors on newer Linux kernel. Newer Linux kernels * have a _LINUX_CAPABILITY_VERSION_2 macro, and redefine the old * _LINUX_CAPABILITY_VERSION macro. To play better with such kernels, redefine * the bundled libcap to use _LINUX_CAPABILITY_VERSION_1. * * Revision 1.2 2003/05/15 00:49:13 castaglia * * Bug#2000 - mod_cap should not use bundled libcap. This patch updates the * bundled libcap; I won't be closing the bug report just yet. * * Revision 1.1 2003/01/03 02:16:17 jwm * * Turning mod_linuxprivs into a core module, mod_cap. This is by no means * complete. * * Revision 1.2 1999/09/07 23:14:19 macgyver * Updated capabilities library and model. * * Revision 1.2 1999/04/17 23:25:10 morgan * fixes from peeterj * * Revision 1.1.1.1 1999/04/17 22:16:31 morgan * release 1.0 of libcap * * Revision 1.5 1998/06/08 00:15:28 morgan * accommodate alpha (glibc?) * * Revision 1.4 1998/06/07 15:58:23 morgan * accommodate real kernel header files :*) * * Revision 1.3 1998/05/24 22:54:09 morgan * updated for 2.1.104 * * Revision 1.2 1997/04/28 00:57:11 morgan * zefram's replacement file with a number of bug fixes from AGM * * Revision 1.1 1997/04/21 04:32:52 morgan * Initial revision * */ proftpd-dfsg-1.3.5~rc3/lib/libcap/cap_proc.c0000644000175000017500000000573611046354271020515 0ustar frankiefrankie/* * $Id: cap_proc.c,v 1.2 2008/08/06 17:00:41 castaglia Exp $ * * Copyright (c) 1997-8 Andrew G Morgan * * See end of file for Log. * * This file deals with setting capabilities on processes. */ #include "libcap.h" cap_t cap_get_proc(void) { cap_t result; /* allocate a new capability set */ result = cap_init(); if (result) { _cap_debug("getting current process' capabilities"); /* fill the capability sets via a system call */ if (capget(&result->head, &result->set)) { cap_free(&result); } } return result; } int cap_set_proc(cap_t cap_d) { int retval; if (!good_cap_t(cap_d)) { errno = EINVAL; return -1; } _cap_debug("setting process capabilities"); retval = capset(&cap_d->head, &cap_d->set); cap_d->head.version = _LINUX_CAPABILITY_VERSION_1; return retval; } /* the following two functions are not required by POSIX */ /* read the caps on a specific process */ int capgetp(pid_t pid, cap_t cap_d) { int error; if (!good_cap_t(cap_d)) { errno = EINVAL; return -1; } _cap_debug("getting process capabilities for proc %d", pid); cap_d->head.pid = pid; error = capget(&cap_d->head, &cap_d->set); cap_d->head.version = _LINUX_CAPABILITY_VERSION_1; cap_d->head.pid = 0; return error; } /* set the caps on a specific process/pg etc.. */ int capsetp(pid_t pid, cap_t cap_d) { int error; if (!good_cap_t(cap_d)) { errno = EINVAL; return -1; } _cap_debug("setting process capabilities for proc %d", pid); cap_d->head.pid = pid; error = capset(&cap_d->head, &cap_d->set); cap_d->head.version = _LINUX_CAPABILITY_VERSION_1; cap_d->head.pid = 0; return error; } /* * $Log: cap_proc.c,v $ * Revision 1.2 2008/08/06 17:00:41 castaglia * * Bug#3096 - libcap version errors on newer Linux kernel. Newer Linux kernels * have a _LINUX_CAPABILITY_VERSION_2 macro, and redefine the old * _LINUX_CAPABILITY_VERSION macro. To play better with such kernels, redefine * the bundled libcap to use _LINUX_CAPABILITY_VERSION_1. * * Revision 1.1 2003/01/03 02:16:17 jwm * * Turning mod_linuxprivs into a core module, mod_cap. This is by no means * complete. * * Revision 1.2 1999/09/07 23:14:19 macgyver * Updated capabilities library and model. * * Revision 1.2 1999/04/18 20:50:01 morgan * reliable behavior when trying to talk with a kernel that has a more * modern capability implementation than the one the library was compiled * with. * * Revision 1.1.1.1 1999/04/17 22:16:31 morgan * release 1.0 of libcap * * Revision 1.5 1998/05/24 22:54:09 morgan * updated for 2.1.104 * * Revision 1.4 1997/05/14 05:17:13 morgan * bug-fix from zefram (errno no set on success) * * Revision 1.3 1997/05/04 05:35:46 morgan * fixed errno setting. syscalls do this part * * Revision 1.2 1997/04/28 00:57:11 morgan * fixes and zefram's patches * * Revision 1.1 1997/04/21 04:32:52 morgan * Initial revision * */ proftpd-dfsg-1.3.5~rc3/lib/libcap/cap_text.c0000644000175000017500000001767707660562011020545 0ustar frankiefrankie/* * $Id: cap_text.c,v 1.2 2003/05/15 00:49:13 castaglia Exp $ * * Copyright (c) 1997-8 Andrew G Morgan * Copyright (c) 1997 Andrew Main * * See end of file for Log. * * This file deals with exchanging internal and textual * representations of capability sets. */ #define LIBCAP_PLEASE_INCLUDE_ARRAY #include "libcap.h" #include #include /* Maximum output text length (16 per cap) */ #define CAP_TEXT_SIZE (16*__CAP_BITS) #define LIBCAP_EFF 01 #define LIBCAP_INH 02 #define LIBCAP_PER 04 /* * Parse a textual representation of capabilities, returning an internal * representation. */ #define setbits(A,B) _setbits((__cap_s *)A, (__cap_s *)B) static void _setbits(__cap_s *a, __cap_s *b) { int n; for (n = __CAP_BLKS; n--; ) a->_blk[n] |= b->_blk[n]; } #define clrbits(A,B) _clrbits((__cap_s *)A, (__cap_s *)B) static void _clrbits(__cap_s *a, __cap_s *b) { int n; for (n = __CAP_BLKS; n--; ) a->_blk[n] &= ~b->_blk[n]; } static char const *namcmp(char const *str, char const *nam) { while (*nam && tolower((unsigned char)*str) == *nam) { str++; nam++; } if (*nam || isalnum((unsigned char)*str) || *str == '_') return NULL; return str; } static int lookupname(char const **strp) { char const *str = *strp; if (isdigit(*str)) { unsigned long n = strtoul(str, (char **)&str, 0); if (n >= __CAP_BITS) return -1; *strp = str; return n; } else { char const *s; int n; for (n = __CAP_BITS; n--; ) if (_cap_names[n] && (s = namcmp(str, _cap_names[n]))) { *strp = s; return n; } return -1; } } cap_t cap_from_text(const char *str) { cap_t res; __cap_s allones; int n; if (str == NULL) { _cap_debug("bad argument"); errno = EINVAL; return NULL; } if (!(res = cap_init())) return NULL; for (n = __CAP_BLKS; n--; ) allones._blk[n] = -1; _cap_debug("%s", str); for (;;) { char op; int flags = 0, listed=0; __cap_s list = {{0}}; /* skip leading spaces */ while (isspace((unsigned char)*str)) str++; if (!*str) { _cap_debugcap("e = ", &res->set.effective); _cap_debugcap("i = ", &res->set.inheritable); _cap_debugcap("p = ", &res->set.permitted); return res; } /* identify caps specified by this clause */ if (isalnum((unsigned char)*str) || *str == '_') { for (;;) { if (namcmp(str, "all")) { str += 3; list = allones; } else { n = lookupname(&str); if (n == -1) goto bad; list.raise_cap(n); } if (*str != ',') break; if (!isalnum((unsigned char)*++str) && *str != '_') goto bad; } listed = 1; } else if (*str == '+' || *str == '-') goto bad; /* require a list of capabilities */ else list = allones; /* identify first operation on list of capabilities */ op = *str++; if (op == '=' && (*str == '+' || *str == '-')) { if (!listed) goto bad; op = (*str++ == '+' ? 'P':'M'); /* skip '=' and take next op */ } else if (op != '+' && op != '-' && op != '=') goto bad; /* cycle through list of actions */ do { _cap_debug("next char = `%c'", *str); if (*str && !isspace(*str)) { switch (*str++) { /* Effective, Inheritable, Permitted */ case 'e': flags |= LIBCAP_EFF; break; case 'i': flags |= LIBCAP_INH; break; case 'p': flags |= LIBCAP_PER; break; default: goto bad; } } else if (op != '=') { _cap_debug("only '=' can be followed by space"); goto bad; } _cap_debug("how to read?"); switch (op) { /* how do we interpret the caps? */ case '=': case 'P': /* =+ */ case 'M': /* =- */ clrbits(&res->set.effective, &list); clrbits(&res->set.inheritable, &list); clrbits(&res->set.permitted, &list); /* fall through */ if (op == 'M') goto minus; case '+': if (flags & LIBCAP_EFF) setbits(&res->set.effective, &list); if (flags & LIBCAP_INH) setbits(&res->set.inheritable, &list); if (flags & LIBCAP_PER) setbits(&res->set.permitted, &list); break; case '-': minus: if (flags & LIBCAP_EFF) clrbits(&res->set.effective, &list); if (flags & LIBCAP_INH) clrbits(&res->set.inheritable, &list); if (flags & LIBCAP_PER) clrbits(&res->set.permitted, &list); break; } /* new directive? */ if (*str == '+' || *str == '-') { if (!listed) { _cap_debug("for + & - must list capabilities"); goto bad; } flags = 0; /* reset the flags */ op = *str++; if (!isalpha(*str)) goto bad; } } while (*str && !isspace(*str)); _cap_debug("next clause"); } bad: cap_free(&res); errno = EINVAL; return NULL; } /* * Convert an internal representation to a textual one. The textual * representation is stored in static memory. It will be overwritten * on the next occasion that this function is called. */ static int getstateflags(cap_t caps, int capno) { int f = 0; if (isset_cap((__cap_s *)(&caps->set.effective),capno)) f |= LIBCAP_EFF; if (isset_cap((__cap_s *)(&caps->set.inheritable),capno)) f |= LIBCAP_INH; if (isset_cap((__cap_s *)(&caps->set.permitted),capno)) f |= LIBCAP_PER; return f; } #define CAP_TEXT_BUFFER_ZONE 100 char *cap_to_text(cap_t caps, ssize_t *length_p) { static char buf[CAP_TEXT_SIZE+CAP_TEXT_BUFFER_ZONE]; char *p; int histo[8] = {0}; int m, n, t; /* Check arguments */ if (!good_cap_t(caps)) { errno = EINVAL; return NULL; } _cap_debugcap("e = ", &caps->set.effective); _cap_debugcap("i = ", &caps->set.inheritable); _cap_debugcap("p = ", &caps->set.permitted); for (n = __CAP_BITS; n--; ) histo[getstateflags(caps, n)]++; for (m=t=7; t--; ) if (histo[t] > histo[m]) m = t; /* blank is not a valid capability set */ p = sprintf(buf, "=%s%s%s", (m & LIBCAP_EFF) ? "e" : "", (m & LIBCAP_INH) ? "i" : "", (m & LIBCAP_PER) ? "p" : "" ) + buf; for (t = 8; t--; ) if (t != m && histo[t]) { *p++ = ' '; for (n = 0; n != __CAP_BITS; n++) if (getstateflags(caps, n) == t) { if (_cap_names[n]) p += sprintf(p, "%s,", _cap_names[n]); else p += sprintf(p, "%d,", n); if (p - buf > CAP_TEXT_SIZE) { errno = ERANGE; return NULL; } } p--; n = t & ~m; if (n) p += sprintf(p, "+%s%s%s", (n & LIBCAP_EFF) ? "e" : "", (n & LIBCAP_INH) ? "i" : "", (n & LIBCAP_PER) ? "p" : ""); n = ~t & m; if (n) p += sprintf(p, "-%s%s%s", (n & LIBCAP_EFF) ? "e" : "", (n & LIBCAP_INH) ? "i" : "", (n & LIBCAP_PER) ? "p" : ""); if (p - buf > CAP_TEXT_SIZE) { errno = ERANGE; return NULL; } } _cap_debug("%s", buf); if (length_p) { *length_p = p - buf; } return (_libcap_strdup(buf)); } /* * $Log: cap_text.c,v $ * Revision 1.2 2003/05/15 00:49:13 castaglia * * Bug#2000 - mod_cap should not use bundled libcap. This patch updates the * bundled libcap; I won't be closing the bug report just yet. * * Revision 1.1 2003/01/03 02:16:17 jwm * * Turning mod_linuxprivs into a core module, mod_cap. This is by no means * complete. * * Revision 1.3 2000/07/11 13:36:52 macgyver * Minor updates and buffer cleanups. * * Revision 1.2 1999/09/07 23:14:19 macgyver * Updated capabilities library and model. * * Revision 1.2 1999/04/17 23:25:09 morgan * fixes from peeterj * * Revision 1.1.1.1 1999/04/17 22:16:31 morgan * release 1.0 of libcap * * Revision 1.4 1998/05/24 22:54:09 morgan * updated for 2.1.104 * * Revision 1.3 1997/05/04 05:37:00 morgan * case sensitvity to capability flags * * Revision 1.2 1997/04/28 00:57:11 morgan * zefram's replacement file with a number of bug fixes from AGM * * Revision 1.1 1997/04/21 04:32:52 morgan * Initial revision * */ proftpd-dfsg-1.3.5~rc3/lib/libcap/include/0000755000175000017500000000000012156653653020204 5ustar frankiefrankieproftpd-dfsg-1.3.5~rc3/lib/libcap/include/sys/0000755000175000017500000000000012156653653021022 5ustar frankiefrankieproftpd-dfsg-1.3.5~rc3/lib/libcap/include/sys/capability.h0000644000175000017500000000522707660562011023311 0ustar frankiefrankie/* * * * * Copyright (C) 1997 Aleph One * Copyright (C) 1997-8 Andrew G. Morgan * * defunct POSIX.1e Standard: 25.2 Capabilities */ #ifndef _SYS_CAPABILITY_H #define _SYS_CAPABILITY_H #ifdef __cplusplus extern "C" { #endif /* * This file complements the kernel file by providing prototype * information for the user library. */ #define _LINUX_FS_H #include #include /* * POSIX capability types */ /* * Opaque capability handle (defined internally by libcap) * internal capability representation */ typedef struct _cap_struct *cap_t; /* "external" capability representation is a (void *) */ /* * This is the type used to identify capabilities */ typedef int cap_value_t; /* * Set identifiers */ typedef enum { CAP_EFFECTIVE=0, /* Specifies the effective flag */ CAP_PERMITTED=1, /* Specifies the permitted flag */ CAP_INHERITABLE=2 /* Specifies the inheritable flag */ } cap_flag_t; /* * These are the states available to each capability */ typedef enum { CAP_CLEAR=0, /* The flag is cleared/disabled */ CAP_SET=1 /* The flag is set/enabled */ } cap_flag_value_t; /* * User-space capability manipulation routines */ /* libcap/cap_alloc.c */ cap_t cap_dup(cap_t); int cap_free(void *); cap_t cap_init(void); /* libcap/cap_flag.c */ int cap_get_flag(cap_t, cap_value_t, cap_flag_t, cap_flag_value_t *); int cap_set_flag(cap_t, cap_flag_t, int, cap_value_t *, cap_flag_value_t); int cap_clear(cap_t); /* libcap/cap_file.c */ cap_t cap_get_fd(int); cap_t cap_get_file(const char *); int cap_set_fd(int, cap_t); int cap_set_file(const char *, cap_t); /* libcap/cap_proc.c */ cap_t cap_get_proc(void); int cap_set_proc(cap_t); /* libcap/cap_extint.c */ ssize_t cap_size(cap_t); ssize_t cap_copy_ext(void *, cap_t, ssize_t); cap_t cap_copy_int(const void *); /* libcap/cap_text.c */ cap_t cap_from_text(const char *); char * cap_to_text(cap_t, ssize_t *); /* * Linux capability system calls: defined in libcap but only available * if the following _POSIX_SOURCE is _undefined_ */ #if !defined(_POSIX_SOURCE) extern int capset(cap_user_header_t header, cap_user_data_t data); extern int capget(cap_user_header_t header, const cap_user_data_t data); extern int capgetp(pid_t pid, cap_t cap_d); extern int capsetp(pid_t pid, cap_t cap_d); extern char const *_cap_names[]; #endif /* !defined(_POSIX_SOURCE) */ #ifdef __cplusplus } #endif #endif /* _SYS_CAPABILITY_H */ proftpd-dfsg-1.3.5~rc3/lib/libcap/_makenames.c0000644000175000017500000000441207605171161021016 0ustar frankiefrankie/* * $Id: _makenames.c,v 1.1 2003/01/03 02:16:17 jwm Exp $ * * Copyright (c) 1997-8 Andrew G. Morgan * * This is a file to make the capability <-> string mappings for * libcap. */ #include #include #include /* * #include 'sed' generated array */ struct { int index; const char *name; } const list[] = { #include "cap_names.sed" {-1, NULL} }; /* this should be more than big enough (factor of three at least) */ const char *pointers[8*sizeof(struct __user_cap_data_struct)]; int main(void) { int i, maxcaps=0; for ( i=0; list[i].index >= 0 && list[i].name; ++i ) { if (maxcaps <= list[i].index) { maxcaps = list[i].index + 1; } pointers[list[i].index] = list[i].name; } printf("/*\n" " * DO NOT EDIT: this file is generated automatically from\n" " *\n" " * \n" " */\n" "#define __CAP_BITS %d\n" "\n" "#ifdef LIBCAP_PLEASE_INCLUDE_ARRAY\n" " char const *_cap_names[__CAP_BITS] = {\n", maxcaps); for (i=0; i/src/tpl.h proftpd-/include/ # cp libtpl-/src/tpl.c proftpd-/lib/ The following edits were made to the copy of tpl.c, to fix compiler warnings: All occurrences of: #if __STDC_VERSION__ < 199901 in tpl.c are changed to: #if defined(__STDC_VERSION__) && __STDC_VERSION__ < 199901 since gcc does not always define the __STDC_VERSION macro. And the calc_field_addr() function in tpl.c was declared static, since the compiler was warning about no previous declarations of this function, and it is only ever called from within tpl.c. TJ Saunders, January 2011 proftpd-dfsg-1.3.5~rc3/lib/pwgrent.c0000644000175000017500000001217211661315554017157 0ustar frankiefrankie/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. */ /* Required to tell conf.h not to include the standard ProFTPD * header files */ #define __PROFTPD_SUPPORT_LIBRARY #include #include "libsupp.h" /* From log.c/log.h */ #define PR_LOG_ERR LOG_ERR extern void pr_log_pri(int, char *, ...); /* From support.c */ extern char *sstrncpy(char *dest, const char *src, size_t n); #define NPWDFIELDS 7 #define NGRPFIELDS 4 #ifndef BUFSIZ #define BUFSIZ PR_TUNABLE_BUFFER_SIZE #endif /* Provides fgetpwent()/fgetgrent() functions. Note that the format of the * files is probably NOT platform dependent, so use of these functions will * require a strict format: * * "username:password:uid:gid:gecos:home:shell" */ #ifndef HAVE_FGETPWENT static char pwdbuf[BUFSIZ]; static char *pwdfields[NPWDFIELDS]; static struct passwd pwent; static struct passwd *supp_getpwent(const char *buf) { register unsigned int i; register char *cp; char *ep = NULL, *buffer = NULL; char **fields = NULL; struct passwd *pwd = NULL; fields = pwdfields; buffer = pwdbuf; pwd = &pwent; sstrncpy(buffer, buf, BUFSIZ-1); buffer[BUFSIZ-1] = '\0'; for(cp = buffer, i = 0; i < NPWDFIELDS && cp; i++) { fields[i] = cp; while (*cp && *cp != ':') ++cp; if (*cp) *cp++ = '\0'; else cp = 0; } if (i != NPWDFIELDS || *fields[2] == '\0' || *fields[3] == '\0') return 0; pwd->pw_name = fields[0]; pwd->pw_passwd = fields[1]; if (fields[2][0] == '\0' || ((pwd->pw_uid = strtol(fields[2], &ep, 10)) == 0 && *ep)) return 0; if (fields[3][0] == '\0' || ((pwd->pw_gid = strtol(fields[3], &ep, 10)) == 0 && *ep)) return 0; pwd->pw_gecos = fields[4]; pwd->pw_dir = fields[5]; pwd->pw_shell = fields[6]; return pwd; } struct passwd *fgetpwent(FILE *fp) { char buf[BUFSIZ] = {'\0'}; while (fgets(buf, sizeof(buf), fp) != (char*) 0) { /* ignore empty and comment lines */ if (buf[0] == '\0' || buf[0] == '#') continue; buf[strlen(buf)-1] = '\0'; return supp_getpwent(buf); } return NULL; } #endif /* HAVE_FGETPWENT */ #ifndef HAVE_FGETGRENT #define MAXMEMBERS 4096 static char *grpbuf = NULL; static struct group grent; static char *grpfields[NGRPFIELDS]; static char *members[MAXMEMBERS+1]; static char *fgetbufline(char **buf, int *buflen, FILE *fp) { char *cp = *buf; while (fgets(cp, (*buflen) - (cp - *buf), fp) != NULL) { /* Is this a full line? */ if (strchr(cp, '\n')) return *buf; /* No -- allocate a larger buffer, doubling buflen. */ *buflen += *buflen; { char *new_buf; new_buf = realloc(*buf, *buflen); if (new_buf == NULL) break; *buf = new_buf; } cp = *buf + (cp - *buf); cp = strchr(cp, '\0'); } free(*buf); *buf = NULL; *buflen = 0; return NULL; } static char **supp_grplist(char *s) { int nmembers = 0; while (s && *s && nmembers < MAXMEMBERS) { members[nmembers++] = s; while (*s && *s != ',') s++; if (*s) *s++ = '\0'; } members[nmembers] = NULL; return members; } static struct group *supp_getgrent(const char *buf) { int i; char *cp; i = strlen(buf) + 1; if (!grpbuf) { grpbuf = malloc(i); } else { char *new_buf; new_buf = realloc(grpbuf, i); if (new_buf == NULL) return NULL; grpbuf = new_buf; } if (!grpbuf) return NULL; sstrncpy(grpbuf, buf, i); if ((cp = strrchr(grpbuf, '\n'))) *cp = '\0'; for (cp = grpbuf, i = 0; i < NGRPFIELDS && cp; i++) { grpfields[i] = cp; if ((cp = strchr(cp, ':'))) *cp++ = 0; } if (i < (NGRPFIELDS - 1)) { pr_log_pri(PR_LOG_ERR, "Malformed entry in group file: %s", buf); return NULL; } if (*grpfields[2] == '\0') return NULL; grent.gr_name = grpfields[0]; grent.gr_passwd = grpfields[1]; grent.gr_gid = atoi(grpfields[2]); grent.gr_mem = supp_grplist(grpfields[3]); return &grent; } struct group *fgetgrent(FILE *fp) { char *cp = NULL, *buf = malloc(BUFSIZ); int buflen = BUFSIZ; struct group *grp = NULL; if (!buf) return NULL; while (fgetbufline(&buf, &buflen, fp) != NULL) { /* ignore comment and empty lines */ if (buf[0] == '\0' || buf[0] == '#') continue; if ((cp = strchr(buf, '\n')) != NULL) *cp = '\0'; grp = supp_getgrent(buf); free(buf); return grp; } return NULL; } #endif /* HAVE_FGETGRENT */ proftpd-dfsg-1.3.5~rc3/lib/glibc-glob.c0000644000175000017500000011404511566546322017477 0ustar frankiefrankie/* Copyright (C) 1991-1999, 2000, 2001 Free Software Foundation, Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. */ /* AIX requires this to be the first thing in the file. */ #if defined _AIX && !defined __GNUC__ #pragma alloca #endif #include #include "options.h" /* Make alloca work the best possible way. */ #ifdef __GNUC__ #define alloca __builtin_alloca #else /* not __GNUC__ */ #if HAVE_ALLOCA_H #include #else /* not __GNUC__ or HAVE_ALLOCA_H */ #ifndef _AIX /* Already did AIX, up at the top. */ char *alloca (); #endif /* not _AIX */ #endif /* not HAVE_ALLOCA_H */ #endif /* not __GNUC__ */ #define MAX_RECURSION PR_TUNABLE_GLOBBING_MAX_RECURSION #define MAX_RESULTS PR_TUNABLE_GLOBBING_MAX_MATCHES /* Enable GNU extensions in glob.h. */ #ifndef _GNU_SOURCE # define _GNU_SOURCE 1 #endif #include #include #include /* Outcomment the following line for production quality code. */ /* #define NDEBUG 1 */ #include #include /* Needed on stupid SunOS for assert. */ /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ /* Proftpd modification: always undefine __GNU_LIBRARY__ because we are not * compiling as part of glibc. */ #undef __GNU_LIBRARY__ #define GLOB_INTERFACE_VERSION 1 #if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1 # include # if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION # define ELIDE_CODE # endif #endif #undef ELIDE_CODE #define __alloca alloca #define __readdir readdir #ifndef ELIDE_CODE #if !defined _LIBC || !defined GLOB_ONLY_P #if defined STDC_HEADERS || defined __GNU_LIBRARY__ # include #endif #if defined HAVE_UNISTD_H || defined _LIBC # include # ifndef POSIX # ifdef _POSIX_VERSION # define POSIX # endif # endif #endif #if !defined _AMIGA && !defined VMS && !defined WINDOWS32 # include #endif #if !defined __GNU_LIBRARY__ && !defined STDC_HEADERS extern int errno; #endif #ifndef __set_errno # define __set_errno(val) errno = (val) #endif #ifndef NULL # define NULL 0 #endif #if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__ # include # define NAMLEN(dirent) strlen((dirent)->d_name) #else # define dirent direct # define NAMLEN(dirent) (dirent)->d_namlen # ifdef HAVE_SYS_NDIR_H # include # endif # ifdef HAVE_SYS_DIR_H # include # endif # ifdef HAVE_NDIR_H # include # endif # ifdef HAVE_VMSDIR_H # include "vmsdir.h" # endif /* HAVE_VMSDIR_H */ #endif /* In GNU systems, defines this macro for us. */ #ifdef _D_NAMLEN # undef NAMLEN # define NAMLEN(d) _D_NAMLEN(d) #endif /* When used in the GNU libc the symbol _DIRENT_HAVE_D_TYPE is available if the `d_type' member for `struct dirent' is available. */ #ifdef _DIRENT_HAVE_D_TYPE # define HAVE_D_TYPE 1 #endif #ifdef _LIBC # define HAVE_DIRENT64 1 #endif /* If the system has the `struct dirent64' type we use it internally. */ #if defined HAVE_DIRENT64 && !defined COMPILE_GLOB64 # if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__ # define CONVERT_D_NAMLEN(d64, d32) # else # define CONVERT_D_NAMLEN(d64, d32) \ (d64)->d_namlen = (d32)->d_namlen; # endif # if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__ # define CONVERT_D_INO(d64, d32) # else # define CONVERT_D_INO(d64, d32) \ (d64)->d_ino = (d32)->d_ino; # endif # ifdef HAVE_D_TYPE # define CONVERT_D_TYPE(d64, d32) \ (d64)->d_type = (d32)->d_type; # else # define CONVERT_D_TYPE(d64, d32) # endif # define CONVERT_DIRENT_DIRENT64(d64, d32) \ memcpy ((d64)->d_name, (d32)->d_name, NAMLEN (d32) + 1); \ CONVERT_D_NAMLEN (d64, d32) \ CONVERT_D_INO (d64, d32) \ CONVERT_D_TYPE (d64, d32) #endif #if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__ /* Posix does not require that the d_ino field be present, and some systems do not provide it. */ # define REAL_DIR_ENTRY(dp) 1 #else # define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) #endif /* POSIX */ #if defined STDC_HEADERS || defined __GNU_LIBRARY__ # include # include # define ANSI_STRING #else /* No standard headers. */ extern char *getenv (); # ifdef HAVE_STRING_H # include # define ANSI_STRING # else # include # endif # ifdef HAVE_MEMORY_H # include # endif extern char *malloc (), *realloc (); extern void free (); extern void qsort (); extern void abort (), exit (); #endif /* Standard headers. */ #ifndef ANSI_STRING # ifndef bzero extern void bzero (); # endif # ifndef bcopy extern void bcopy (); # endif # define memcpy(d, s, n) bcopy ((s), (d), (n)) # define strrchr rindex /* memset is only used for zero here, but let's be paranoid. */ # define memset(s, better_be_zero, n) \ ((void) ((better_be_zero) == 0 ? (bzero((s), (n)), 0) : (abort(), 0))) #endif /* Not ANSI_STRING. */ #if !defined HAVE_STRCOLL && !defined _LIBC # define strcoll strcmp #endif #if !defined HAVE_MEMPCPY && defined __GLIBC__ && __GLIBC__ - 0 == 2 && __GLIBC_MINOR__ >= 1 # define HAVE_MEMPCPY 1 # undef mempcpy # define mempcpy(Dest, Src, Len) __mempcpy (Dest, Src, Len) #endif static unsigned long nbresults; #ifndef __GNU_LIBRARY__ # ifdef __GNUC__ __inline # endif # ifndef __SASC # ifdef WINDOWS32 static void * # else static char * # endif my_realloc (void *p, size_t n) { /* These casts are the for sake of the broken Ultrix compiler, which warns of illegal pointer combinations otherwise. */ if (p == NULL) return (char *) malloc (n); return (char *) realloc (p, n); } # define realloc my_realloc # endif /* __SASC */ #endif /* __GNU_LIBRARY__ */ #if !defined __alloca && !defined __GNU_LIBRARY__ # ifdef __GNUC__ # undef alloca # define alloca(n) __builtin_alloca (n) # else /* Not GCC. */ # ifdef HAVE_ALLOCA_H # include # else /* Not HAVE_ALLOCA_H. */ # ifndef _AIX # ifdef WINDOWS32 # include # else extern char *alloca (); # endif /* WINDOWS32 */ # endif /* Not _AIX. */ # endif /* sparc or HAVE_ALLOCA_H. */ # endif /* GCC. */ # define __alloca alloca #endif #ifdef IRIX6 #include #endif #ifndef __GNU_LIBRARY__ # define __stat stat # ifdef STAT_MACROS_BROKEN # undef S_ISDIR # endif # ifndef S_ISDIR # define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) # endif #endif #ifdef _LIBC # undef strdup # define strdup(str) __strdup (str) # define sysconf(id) __sysconf (id) # define closedir(dir) __closedir (dir) # define opendir(name) __opendir (name) # define readdir(str) __readdir64 (str) # define getpwnam_r(name, bufp, buf, len, res) \ __getpwnam_r (name, bufp, buf, len, res) # ifndef __stat64 # define __stat64(fname, buf) __xstat64 (_STAT_VER, fname, buf) # endif # define HAVE_STAT64 1 #endif #ifndef HAVE_STAT64 # define __stat64(fname, buf) __stat (fname, buf) /* This is the variable name we are using. */ # define st64 st #endif #if !(defined STDC_HEADERS || defined __GNU_LIBRARY__) # undef size_t # define size_t unsigned int #endif /* Some system header files erroneously define these. We want our own definitions from to take precedence. */ #ifndef __GNU_LIBRARY__ # undef FNM_PATHNAME # undef FNM_NOESCAPE # undef FNM_PERIOD #endif #include /* Some system header files erroneously define these. We want our own definitions from to take precedence. */ #ifndef __GNU_LIBRARY__ # undef GLOB_ERR # undef GLOB_MARK # undef GLOB_NOSORT # undef GLOB_DOOFFS # undef GLOB_NOCHECK # undef GLOB_APPEND # undef GLOB_NOESCAPE # undef GLOB_PERIOD #endif #include #ifdef HAVE_GETLOGIN_R extern int getlogin_r __P ((char *, size_t)); #else extern char *getlogin __P ((void)); #endif static #if __GNUC__ - 0 >= 2 inline #endif const char *next_brace_sub __P ((const char *begin)); #endif /* GLOB_ONLY_P */ static int glob_in_dir __P ((const char *pattern, const char *directory, int flags, int (*errfunc) (const char *, int), glob_t *pglob)); /* Prototype __glob_pattern_p to avoid compiler warning. */ #if !defined _LIBC || !defined NO_GLOB_PATTERN_P /* Return nonzero if PATTERN contains any metacharacters. Metacharacters can be quoted with backslashes if QUOTE is nonzero. */ static int __glob_pattern_p (const char *pattern, int quote); #endif /* NO_GLOB_PATTERN_P */ #if !defined _LIBC || !defined GLOB_ONLY_P static int prefix_array __P ((const char *prefix, char **array, size_t n)); static int collated_compare __P ((const __ptr_t, const __ptr_t)); /* Find the end of the sub-pattern in a brace expression. We define this as an inline function if the compiler permits. */ static #if __GNUC__ - 0 >= 2 inline #endif const char * next_brace_sub (const char *begin) { unsigned int depth = 0; const char *cp = begin; while (1) { if (depth == 0) { if (*cp != ',' && *cp != '}' && *cp != '\0') { if (*cp == '{') ++depth; ++cp; continue; } } else { while (*cp != '\0' && (*cp != '}' || depth > 0)) { if (*cp == '}') --depth; ++cp; } if (*cp == '\0') /* An incorrectly terminated brace expression. */ return NULL; continue; } break; } return cp; } #endif /* !GLOB_ONLY_P */ /* Do glob searching for PATTERN, placing results in PGLOB. The bits defined above may be set in FLAGS. If a directory cannot be opened or read and ERRFUNC is not nil, it is called with the pathname that caused the error, and the `errno' value from the failing call; if it returns non-zero `glob' returns GLOB_ABORTED; if it returns zero, the error is ignored. If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned. Otherwise, `glob' returns zero. */ static int glob_limited (unsigned int depth, const char *pattern, int flags, int (*errfunc) __P((const char *, int)), glob_t *pglob) { const char *filename; const char *dirname; size_t dirlen; int status; size_t oldcount; if (depth > MAX_RECURSION) { return GLOB_NOSPACE; } if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0) { __set_errno (EINVAL); return -1; } if (!(flags & GLOB_DOOFFS)) /* Have to do this so `globfree' knows where to start freeing. It also makes all the code that uses gl_offs simpler. */ pglob->gl_offs = 0; if (flags & GLOB_BRACE) { const char *begin = strchr (pattern, '{'); if (begin != NULL) { /* Allocate working buffer large enough for our work. Note that we have at least an opening and closing brace. */ size_t firstc; char *alt_start; const char *p; const char *next; const char *rest; size_t rest_len; #ifdef __GNUC__ char onealt[strlen (pattern) - 1]; #else char *onealt = (char *) malloc (strlen (pattern) - 1); if (onealt == NULL) { if (!(flags & GLOB_APPEND)) globfree (pglob); return GLOB_NOSPACE; } #endif /* We know the prefix for all sub-patterns. */ #ifdef HAVE_MEMPCPY alt_start = mempcpy (onealt, pattern, begin - pattern); #else memcpy (onealt, pattern, begin - pattern); alt_start = &onealt[begin - pattern]; #endif /* Find the first sub-pattern and at the same time find the rest after the closing brace. */ next = next_brace_sub (begin + 1); if (next == NULL) { /* It is an illegal expression. */ #ifndef __GNUC__ free (onealt); #endif return glob_limited (depth + 1U, pattern, flags & ~GLOB_BRACE, errfunc, pglob); } /* Now find the end of the whole brace expression. */ rest = next; while (*rest != '}') { rest = next_brace_sub (rest + 1); if (rest == NULL) { /* It is an illegal expression. */ #ifndef __GNUC__ free (onealt); #endif return glob_limited (depth + 1U, pattern, flags & ~GLOB_BRACE, errfunc, pglob); } } /* Please note that we now can be sure the brace expression is well-formed. */ rest_len = strlen (++rest) + 1; /* We have a brace expression. BEGIN points to the opening {, NEXT points past the terminator of the first element, and END points past the final }. We will accumulate result names from recursive runs for each brace alternative in the buffer using GLOB_APPEND. */ if (!(flags & GLOB_APPEND)) { /* This call is to set a new vector, so clear out the vector so we can append to it. */ pglob->gl_pathc = 0; pglob->gl_pathv = NULL; } firstc = pglob->gl_pathc; p = begin + 1; while (1) { int result; /* Construct the new glob expression. */ #ifdef HAVE_MEMPCPY mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len); #else memcpy (alt_start, p, next - p); memcpy (&alt_start[next - p], rest, rest_len); #endif result = glob_limited (depth + 1U, onealt, ((flags & ~(GLOB_NOCHECK|GLOB_NOMAGIC)) | GLOB_APPEND), errfunc, pglob); /* If we got an error, return it. */ if (result && result != GLOB_NOMATCH) { #ifndef __GNUC__ free (onealt); #endif if (!(flags & GLOB_APPEND)) globfree (pglob); return result; } if (*next == '}') /* We saw the last entry. */ break; p = next + 1; next = next_brace_sub (p); assert (next != NULL); } #ifndef __GNUC__ free (onealt); #endif if (pglob->gl_pathc != firstc) /* We found some entries. */ return 0; else if (!(flags & (GLOB_NOCHECK|GLOB_NOMAGIC))) return GLOB_NOMATCH; } } /* Find the filename. */ filename = strrchr (pattern, '/'); #if defined __MSDOS__ || defined WINDOWS32 /* The case of "d:pattern". Since `:' is not allowed in file names, we can safely assume that wherever it happens in pattern, it signals the filename part. This is so we could some day support patterns like "[a-z]:foo". */ if (filename == NULL) filename = strchr (pattern, ':'); #endif /* __MSDOS__ || WINDOWS32 */ if (filename == NULL) { /* This can mean two things: a simple name or "~name". The latter case is nothing but a notation for a directory. */ if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && pattern[0] == '~') { dirname = pattern; dirlen = strlen (pattern); /* Set FILENAME to NULL as a special flag. This is ugly but other solutions would require much more code. We test for this special case below. */ filename = NULL; } else { filename = pattern; #ifdef _AMIGA dirname = ""; #else dirname = "."; #endif dirlen = 0; } } else if (filename == pattern) { /* "/pattern". */ dirname = "/"; dirlen = 1; ++filename; } else { char *newp; dirlen = filename - pattern; #if defined __MSDOS__ || defined WINDOWS32 if (*filename == ':' || (filename > pattern + 1 && filename[-1] == ':')) { char *drive_spec; ++dirlen; drive_spec = (char *) __alloca (dirlen + 1); #ifdef HAVE_MEMPCPY *((char *) mempcpy (drive_spec, pattern, dirlen)) = '\0'; #else memcpy (drive_spec, pattern, dirlen); drive_spec[dirlen] = '\0'; #endif /* For now, disallow wildcards in the drive spec, to prevent infinite recursion in glob. */ if (__glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE))) return GLOB_NOMATCH; /* If this is "d:pattern", we need to copy `:' to DIRNAME as well. If it's "d:/pattern", don't remove the slash from "d:/", since "d:" and "d:/" are not the same.*/ } #endif newp = (char *) __alloca (dirlen + 1); #ifdef HAVE_MEMPCPY *((char *) mempcpy (newp, pattern, dirlen)) = '\0'; #else memcpy (newp, pattern, dirlen); newp[dirlen] = '\0'; #endif dirname = newp; ++filename; if (filename[0] == '\0' #if defined __MSDOS__ || defined WINDOWS32 && dirname[dirlen - 1] != ':' && (dirlen < 3 || dirname[dirlen - 2] != ':' || dirname[dirlen - 1] != '/') #endif && dirlen > 1) /* "pattern/". Expand "pattern", appending slashes. */ { int val = glob_limited (depth + 1U, dirname, flags | GLOB_MARK, errfunc, pglob); if (val == 0) pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK) | (flags & GLOB_MARK)); return val; } } if (!(flags & GLOB_APPEND)) { pglob->gl_pathc = 0; if (!(flags & GLOB_DOOFFS)) pglob->gl_pathv = NULL; else { size_t i; pglob->gl_pathv = (char **) malloc ((pglob->gl_offs + 1) * sizeof (char *)); if (pglob->gl_pathv == NULL) return GLOB_NOSPACE; for (i = 0; i <= pglob->gl_offs; ++i) pglob->gl_pathv[i] = NULL; } } oldcount = pglob->gl_pathc + pglob->gl_offs; #ifndef VMS if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~') { if (dirname[1] == '\0' || dirname[1] == '/') { /* Look up home directory. */ const char *home_dir = getenv ("HOME"); # ifdef _AMIGA if (home_dir == NULL || home_dir[0] == '\0') home_dir = "SYS:"; # else # ifdef WINDOWS32 if (home_dir == NULL || home_dir[0] == '\0') home_dir = "c:/users/default"; /* poor default */ # else if (home_dir == NULL || home_dir[0] == '\0') { int success; char *name; # if defined HAVE_GETLOGIN_R || defined _LIBC size_t buflen = sysconf (_SC_LOGIN_NAME_MAX) + 1; if (buflen == 0) /* `sysconf' does not support _SC_LOGIN_NAME_MAX. Try a moderate value. */ buflen = PR_TUNABLE_LOGIN_MAX+1; name = (char *) __alloca (buflen); success = getlogin_r (name, buflen) >= 0; # else success = (name = getlogin ()) != NULL; # endif if (success) { struct passwd *p; # if defined HAVE_GETPWNAM_R || defined _LIBC long int pwbuflen = sysconf (_SC_GETPW_R_SIZE_MAX); char *pwtmpbuf; struct passwd pwbuf; int save = errno; if (pwbuflen == -1) /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX. Try a moderate value. */ pwbuflen = 1024; pwtmpbuf = (char *) __alloca (pwbuflen); while (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p) != 0) { if (errno != ERANGE) { p = NULL; break; } pwbuflen *= 2; pwtmpbuf = (char *) __alloca (pwbuflen); __set_errno (save); } # else p = getpwnam (name); # endif if (p != NULL) home_dir = p->pw_dir; } } if (home_dir == NULL || home_dir[0] == '\0') { if (flags & GLOB_TILDE_CHECK) return GLOB_NOMATCH; else home_dir = "~"; /* No luck. */ } # endif /* WINDOWS32 */ # endif /* Now construct the full directory. */ if (dirname[1] == '\0') dirname = home_dir; else { char *newp; size_t home_len = strlen (home_dir); newp = (char *) __alloca (home_len + dirlen); # ifdef HAVE_MEMPCPY mempcpy (mempcpy (newp, home_dir, home_len), &dirname[1], dirlen); # else memcpy (newp, home_dir, home_len); memcpy (&newp[home_len], &dirname[1], dirlen); # endif dirname = newp; } } # if !defined _AMIGA && !defined WINDOWS32 else { char *end_name = strchr (dirname, '/'); const char *user_name; const char *home_dir; if (end_name == NULL) user_name = dirname + 1; else { char *newp; newp = (char *) __alloca (end_name - dirname); # ifdef HAVE_MEMPCPY *((char *) mempcpy (newp, dirname + 1, end_name - dirname)) = '\0'; # else memcpy (newp, dirname + 1, end_name - dirname); newp[end_name - dirname - 1] = '\0'; # endif user_name = newp; } /* Look up specific user's home directory. */ { struct passwd *p; # if defined HAVE_GETPWNAM_R || defined _LIBC long int buflen = sysconf (_SC_GETPW_R_SIZE_MAX); char *pwtmpbuf; struct passwd pwbuf; int save = errno; if (buflen == -1) /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX. Try a moderate value. */ buflen = 1024; pwtmpbuf = (char *) __alloca (buflen); while (getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) != 0) { if (errno != ERANGE) { p = NULL; break; } buflen *= 2; pwtmpbuf = __alloca (buflen); __set_errno (save); } # else p = getpwnam (user_name); # endif if (p != NULL) home_dir = p->pw_dir; else home_dir = NULL; } /* If we found a home directory use this. */ if (home_dir != NULL) { char *newp; size_t home_len = strlen (home_dir); size_t rest_len = end_name == NULL ? 0 : strlen (end_name); newp = (char *) __alloca (home_len + rest_len + 1); # ifdef HAVE_MEMPCPY *((char *) mempcpy (mempcpy (newp, home_dir, home_len), end_name, rest_len)) = '\0'; # else memcpy (newp, home_dir, home_len); memcpy (&newp[home_len], end_name, rest_len); newp[home_len + rest_len] = '\0'; # endif dirname = newp; } else if (flags & GLOB_TILDE_CHECK) /* We have to regard it as an error if we cannot find the home directory. */ return GLOB_NOMATCH; } # endif /* Not Amiga && not WINDOWS32. */ } #endif /* Not VMS. */ /* Now test whether we looked for "~" or "~NAME". In this case we can give the answer now. */ if (filename == NULL) { struct stat st; #ifdef HAVE_STAT64 struct stat64 st64; #endif /* Return the directory if we don't check for error or if it exists. */ if ((flags & GLOB_NOCHECK) || (((flags & GLOB_ALTDIRFUNC) ? ((*pglob->gl_stat) (dirname, &st) == 0 && S_ISDIR (st.st_mode)) : (__stat64 (dirname, &st64) == 0 && S_ISDIR (st64.st_mode))))) { int newcount = pglob->gl_pathc + pglob->gl_offs; char **new_buf; new_buf = (char **) realloc (pglob->gl_pathv, (newcount + 1 + 1) * sizeof (char *)); if (new_buf == NULL) return GLOB_NOSPACE; pglob->gl_pathv = new_buf; #if defined HAVE_STRDUP || defined _LIBC pglob->gl_pathv[newcount] = strdup (dirname); #else { size_t len = strlen (dirname) + 1; char *dircopy = malloc (len); if (dircopy != NULL) pglob->gl_pathv[newcount] = memcpy (dircopy, dirname, len); } #endif if (pglob->gl_pathv[newcount] == NULL) { free (pglob->gl_pathv); return GLOB_NOSPACE; } pglob->gl_pathv[++newcount] = NULL; ++pglob->gl_pathc; pglob->gl_flags = flags; return 0; } /* Not found. */ return GLOB_NOMATCH; } if (__glob_pattern_p (dirname, !(flags & GLOB_NOESCAPE))) { /* The directory name contains metacharacters, so we have to glob for the directory, and then glob for the pattern in each directory found. */ glob_t dirs; size_t i; if ((flags & GLOB_ALTDIRFUNC) != 0) { /* Use the alternative access functions also in the recursive call. */ dirs.gl_opendir = pglob->gl_opendir; dirs.gl_readdir = pglob->gl_readdir; dirs.gl_closedir = pglob->gl_closedir; dirs.gl_stat = pglob->gl_stat; dirs.gl_lstat = pglob->gl_lstat; } status = glob_limited (depth + 1U, dirname, ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE | GLOB_ALTDIRFUNC)) | GLOB_NOSORT | GLOB_ONLYDIR), errfunc, &dirs); if (status != 0) return status; /* We have successfully globbed the preceding directory name. For each name we found, call glob_in_dir on it and FILENAME, appending the results to PGLOB. */ for (i = 0; i < dirs.gl_pathc; ++i) { int old_pathc; #ifdef SHELL { /* Make globbing interruptible in the bash shell. */ extern int interrupt_state; if (interrupt_state) { globfree (&dirs); return GLOB_ABORTED; } } #endif /* SHELL. */ old_pathc = pglob->gl_pathc; status = glob_in_dir (filename, dirs.gl_pathv[i], ((flags | GLOB_APPEND) & ~GLOB_NOCHECK), errfunc, pglob); if (status == GLOB_NOMATCH) /* No matches in this directory. Try the next. */ continue; if (status != 0) { globfree (&dirs); globfree (pglob); return status; } /* Stick the directory on the front of each name. */ if (prefix_array (dirs.gl_pathv[i], &pglob->gl_pathv[old_pathc + pglob->gl_offs], pglob->gl_pathc - old_pathc)) { globfree (&dirs); globfree (pglob); return GLOB_NOSPACE; } } flags |= GLOB_MAGCHAR; /* We have ignored the GLOB_NOCHECK flag in the `glob_in_dir' calls. But if we have not found any matching entry and the GLOB_NOCHECK flag was set we must return the list consisting of the disrectory names followed by the filename. */ if (pglob->gl_pathc + pglob->gl_offs == oldcount) { /* No matches. */ if (flags & GLOB_NOCHECK) { size_t filename_len = strlen (filename) + 1; char **new_pathv, **new_buf; int newcount = pglob->gl_pathc + pglob->gl_offs; struct stat st; #ifdef HAVE_STAT64 struct stat64 st64; #endif /* This is an pessimistic guess about the size. */ new_buf = (char **) realloc (pglob->gl_pathv, (newcount + dirs.gl_pathc + 1) * sizeof (char *)); if (new_buf == NULL) { globfree (&dirs); return GLOB_NOSPACE; } pglob->gl_pathv = new_buf; for (i = 0; i < dirs.gl_pathc; ++i) { const char *dir = dirs.gl_pathv[i]; size_t dir_len = strlen (dir); /* First check whether this really is a directory. */ if (((flags & GLOB_ALTDIRFUNC) ? ((*pglob->gl_stat) (dir, &st) != 0 || !S_ISDIR (st.st_mode)) : (__stat64 (dir, &st64) != 0 || !S_ISDIR (st64.st_mode)))) /* No directory, ignore this entry. */ continue; pglob->gl_pathv[newcount] = malloc (dir_len + 1 + filename_len); if (pglob->gl_pathv[newcount] == NULL) { globfree (&dirs); globfree (pglob); return GLOB_NOSPACE; } #ifdef HAVE_MEMPCPY mempcpy (mempcpy (mempcpy (pglob->gl_pathv[newcount], dir, dir_len), "/", 1), filename, filename_len); #else memcpy (pglob->gl_pathv[newcount], dir, dir_len); pglob->gl_pathv[newcount][dir_len] = '/'; memcpy (&pglob->gl_pathv[newcount][dir_len + 1], filename, filename_len); #endif ++pglob->gl_pathc; ++newcount; } pglob->gl_pathv[newcount] = NULL; pglob->gl_flags = flags; /* Now we know how large the gl_pathv vector must be. */ new_pathv = (char **) realloc (pglob->gl_pathv, ((newcount + 1) * sizeof (char *))); if (new_pathv != NULL) pglob->gl_pathv = new_pathv; } else { globfree (&dirs); return GLOB_NOMATCH; } } globfree (&dirs); } else { int old_pathc = pglob->gl_pathc; status = glob_in_dir (filename, dirname, flags, errfunc, pglob); if (status != 0) return status; if (dirlen > 0) { /* Stick the directory on the front of each name. */ if (prefix_array (dirname, &pglob->gl_pathv[old_pathc + pglob->gl_offs], pglob->gl_pathc - old_pathc)) { globfree (pglob); return GLOB_NOSPACE; } } } if (flags & GLOB_MARK) { /* Append slashes to directory names. */ size_t i; struct stat st; #ifdef HAVE_STAT64 struct stat64 st64; #endif for (i = oldcount; i < pglob->gl_pathc + pglob->gl_offs; ++i) if ((((flags & GLOB_ALTDIRFUNC) && (pglob->gl_pathv != NULL)) ? ((*pglob->gl_stat) (pglob->gl_pathv[i], &st) == 0 && S_ISDIR (st.st_mode)) : (__stat64 (pglob->gl_pathv[i], &st64) == 0 && S_ISDIR (st64.st_mode)))) { size_t len = strlen (pglob->gl_pathv[i]) + 2; char *new = realloc (pglob->gl_pathv[i], len); if (new == NULL) { globfree (pglob); return GLOB_NOSPACE; } strcpy (&new[len - 2], "/"); pglob->gl_pathv[i] = new; } } if (!(flags & GLOB_NOSORT)) { /* Sort the vector. */ qsort ((__ptr_t) &pglob->gl_pathv[oldcount], pglob->gl_pathc + pglob->gl_offs - oldcount, sizeof (char *), collated_compare); } return 0; } int glob (const char *pattern, int flags, int (*errfunc) __P((const char *, int)), glob_t *pglob) { nbresults = 0UL; return glob_limited(0U, pattern, flags, errfunc, pglob); } #if !defined _LIBC || !defined GLOB_ONLY_P /* Free storage allocated in PGLOB by a previous `glob' call. */ void globfree (register glob_t *pglob) { if (pglob->gl_pathv != NULL) { size_t i; for (i = 0; i < pglob->gl_pathc; ++i) if (pglob->gl_pathv[pglob->gl_offs + i] != NULL) free ((__ptr_t) pglob->gl_pathv[pglob->gl_offs + i]); free ((__ptr_t) pglob->gl_pathv); } } /* Do a collated comparison of A and B. */ static int collated_compare (const __ptr_t a, const __ptr_t b) { const char *const s1 = *(const char *const * const) a; const char *const s2 = *(const char *const * const) b; if (s1 == s2) return 0; if (s1 == NULL) return 1; if (s2 == NULL) return -1; return strcoll (s1, s2); } /* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's elements in place. Return nonzero if out of memory, zero if successful. A slash is inserted between DIRNAME and each elt of ARRAY, unless DIRNAME is just "/". Each old element of ARRAY is freed. */ static int prefix_array (const char *dirname, char **array, size_t n) { register size_t i; size_t dirlen = strlen (dirname); #if defined __MSDOS__ || defined WINDOWS32 int sep_char = '/'; # define DIRSEP_CHAR sep_char #else # define DIRSEP_CHAR '/' #endif if (dirlen == 1 && dirname[0] == '/') /* DIRNAME is just "/", so normal prepending would get us "//foo". We want "/foo" instead, so don't prepend any chars from DIRNAME. */ dirlen = 0; #if defined __MSDOS__ || defined WINDOWS32 else if (dirlen > 1) { if (dirname[dirlen - 1] == '/' && dirname[dirlen - 2] == ':') /* DIRNAME is "d:/". Don't prepend the slash from DIRNAME. */ --dirlen; else if (dirname[dirlen - 1] == ':') { /* DIRNAME is "d:". Use `:' instead of `/'. */ --dirlen; sep_char = ':'; } } #endif for (i = 0; i < n; ++i) { size_t eltlen = strlen (array[i]) + 1; char *new = (char *) malloc (dirlen + 1 + eltlen); if (new == NULL) { while (i > 0) free ((__ptr_t) array[--i]); return 1; } #ifdef HAVE_MEMPCPY { char *endp = (char *) mempcpy (new, dirname, dirlen); *endp++ = DIRSEP_CHAR; mempcpy (endp, array[i], eltlen); } #else memcpy (new, dirname, dirlen); new[dirlen] = DIRSEP_CHAR; memcpy (&new[dirlen + 1], array[i], eltlen); #endif free ((__ptr_t) array[i]); array[i] = new; } return 0; } /* We must not compile this function twice. */ #if !defined _LIBC || !defined NO_GLOB_PATTERN_P /* Return nonzero if PATTERN contains any metacharacters. Metacharacters can be quoted with backslashes if QUOTE is nonzero. */ static int __glob_pattern_p (const char *pattern, int quote) { register const char *p; int open = 0; for (p = pattern; *p != '\0'; ++p) switch (*p) { case '?': case '*': return 1; case '\\': if (quote && p[1] != '\0') ++p; break; case '[': open = 1; break; case ']': if (open) return 1; break; } return 0; } # ifdef _LIBC weak_alias (__glob_pattern_p, glob_pattern_p) # endif #endif #endif /* !GLOB_ONLY_P */ /* Like `glob', but PATTERN is a final pathname component, and matches are searched for in DIRECTORY. The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done. The GLOB_APPEND flag is assumed to be set (always appends). */ static int glob_in_dir (const char *pattern, const char *directory, int flags, int (*errfunc) __P((const char *, int)), glob_t *pglob) { __ptr_t stream = NULL; struct globlink { struct globlink *next; char *name; }; struct globlink *names = NULL; size_t nfound; int meta; int save; meta = __glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE)); if (meta == 0 && (flags & (GLOB_NOCHECK|GLOB_NOMAGIC))) { /* We need not do any tests. The PATTERN contains no meta characters and we must not return an error therefore the result will always contain exactly one name. */ flags |= GLOB_NOCHECK; nfound = 0; } else if (meta == 0 && ((flags & GLOB_NOESCAPE) || strchr(pattern, '\\') == NULL)) { /* Since we use the normal file functions we can also use stat() to verify the file is there. */ struct stat st; # ifdef HAVE_STAT64 struct stat64 st64; # endif size_t patlen = strlen (pattern); size_t dirlen = strlen (directory); char *fullname = (char *) __alloca (dirlen + 1 + patlen + 1); # ifdef HAVE_MEMPCPY mempcpy (mempcpy (mempcpy (fullname, directory, dirlen), "/", 1), pattern, patlen + 1); # else memcpy (fullname, directory, dirlen); fullname[dirlen] = '/'; memcpy (&fullname[dirlen + 1], pattern, patlen + 1); # endif if (((flags & GLOB_ALTDIRFUNC) ? (*pglob->gl_stat) (fullname, &st) : __stat64 (fullname, &st64)) == 0) /* We found this file to be existing. Now tell the rest of the function to copy this name into the result. */ flags |= GLOB_NOCHECK; nfound = 0; } else { if (pattern[0] == '\0') { /* This is a special case for matching directories like in "*a/". */ names = (struct globlink *) __alloca (sizeof (struct globlink)); names->name = (char *) malloc (1); if (names->name == NULL) goto memory_error; names->name[0] = '\0'; names->next = NULL; nfound = 1; meta = 0; } else { stream = ((flags & GLOB_ALTDIRFUNC) ? (*pglob->gl_opendir) (directory) : (__ptr_t) opendir (directory)); if (stream == NULL) { if (errno != ENOTDIR && ((errfunc != NULL && (*errfunc) (directory, errno)) || (flags & GLOB_ERR))) return GLOB_ABORTED; nfound = 0; meta = 0; } else { int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0) | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0) #if defined _AMIGA || defined VMS | FNM_CASEFOLD #endif ); nfound = 0; flags |= GLOB_MAGCHAR; while (1) { const char *name; size_t len; #if defined HAVE_DIRENT64 && !defined COMPILE_GLOB64 struct dirent64 *d; struct dirent64 d64; if (flags & GLOB_ALTDIRFUNC) { struct dirent *d32 = (*pglob->gl_readdir) (stream); if (d32 != NULL) { CONVERT_DIRENT_DIRENT64 (&d64, d32); d = &d64; } else d = NULL; } else d = __readdir64 ((DIR *) stream); #else struct dirent *d = ((flags & GLOB_ALTDIRFUNC) ? ((struct dirent *) (*pglob->gl_readdir) (stream)) : __readdir ((DIR *) stream)); #endif if (d == NULL) break; if (nbresults > MAX_RESULTS) { break; } nbresults++; if (! REAL_DIR_ENTRY (d)) continue; #ifdef HAVE_D_TYPE /* If we shall match only directories use the information provided by the dirent call if possible. */ if ((flags & GLOB_ONLYDIR) && d->d_type != DT_UNKNOWN && d->d_type != DT_DIR) continue; #endif name = d->d_name; if (fnmatch (pattern, name, fnm_flags) == 0) { struct globlink *new = (struct globlink *) __alloca (sizeof (struct globlink)); len = NAMLEN (d); new->name = (char *) malloc (len + 1); if (new->name == NULL) goto memory_error; #ifdef HAVE_MEMPCPY *((char *) mempcpy ((__ptr_t) new->name, name, len)) = '\0'; #else memcpy ((__ptr_t) new->name, name, len); new->name[len] = '\0'; #endif new->next = names; names = new; ++nfound; } } } } } if (nfound == 0 && (flags & GLOB_NOCHECK)) { size_t len = strlen (pattern); nfound = 1; names = (struct globlink *) __alloca (sizeof (struct globlink)); names->next = NULL; names->name = (char *) malloc (len + 1); if (names->name == NULL) goto memory_error; #ifdef HAVE_MEMPCPY *((char *) mempcpy (names->name, pattern, len)) = '\0'; #else memcpy (names->name, pattern, len); names->name[len] = '\0'; #endif } if (nfound != 0) { char **new_buf; new_buf = (char **) realloc (pglob->gl_pathv, (pglob->gl_pathc + pglob->gl_offs + nfound + 1) * sizeof (char *)); if (new_buf == NULL) goto memory_error; pglob->gl_pathv = new_buf; for (; names != NULL; names = names->next) pglob->gl_pathv[pglob->gl_offs + pglob->gl_pathc++] = names->name; pglob->gl_pathv[pglob->gl_offs + pglob->gl_pathc] = NULL; pglob->gl_flags = flags; } save = errno; if (stream != NULL) { if (flags & GLOB_ALTDIRFUNC) (*pglob->gl_closedir) (stream); else closedir ((DIR *) stream); } __set_errno (save); return nfound == 0 ? GLOB_NOMATCH : 0; memory_error: { int my_save = errno; if (flags & GLOB_ALTDIRFUNC) (*pglob->gl_closedir) (stream); else closedir ((DIR *) stream); __set_errno (my_save); } while (names != NULL) { if (names->name != NULL) free ((__ptr_t) names->name); names = names->next; } return GLOB_NOSPACE; } #endif /* Not ELIDE_CODE. */ proftpd-dfsg-1.3.5~rc3/lib/strsep.c0000644000175000017500000000320511566546322017011 0ustar frankiefrankie/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. */ /* Required to tell conf.h not to include the standard ProFTPD * header files */ #define __PROFTPD_SUPPORT_LIBRARY #include #include #undef _LIBC #undef __GNU_LIBRARY__ #if defined (_LIBC) || !defined (__GNU_LIBRARY__) #if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS) extern int errno; #endif #ifndef HAVE_STRSEP /* Match STRING against the filename pattern PATTERN, returning zero if it matches, nonzero if not. */ char *strsep(char **stringp, const char *delim) { char *res; if (!stringp || !*stringp || !**stringp) return (char*)0; res = *stringp; while(**stringp && !strchr(delim, **stringp)) ++(*stringp); if (**stringp) { **stringp = '\0'; ++(*stringp); } return res; } #else void pr_os_already_has_strsep(void) { } #endif /* HAVE_STRSEP */ #endif /* _LIBC or not __GNU_LIBRARY__. */ proftpd-dfsg-1.3.5~rc3/lib/glibc-hstrerror.c0000644000175000017500000000621010166060334020565 0ustar frankiefrankie/* * Copyright (c) 1987, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Portions Copyright (c) 1996-1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ #define __PROFTPD_SUPPORT_LIBRARY #include #include #ifndef HAVE_HSTRERROR static const char *h_errlist[] = { "No error", "Unknown host", /* 1 HOST_NOT_FOUND */ "Host name lookup failure", /* 2 TRY_AGAIN */ "Unknown server error", /* 3 NO_RECOVERY */ "No address associated with name", /* 4 NO_ADDRESS */ }; static int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] }; /* * hstrerror -- * return the string associated with a given "host" errno value. */ const char * hstrerror(int err) { if (err < 0) return "Resolver internal error"; else if (err < h_nerr) return h_errlist[err]; return "Unknown resolver error"; } #else /* HAVE_STRERROR */ void pr_os_already_has_hstrerror(void) { } #endif /* HAVE_STRERROR */ proftpd-dfsg-1.3.5~rc3/lib/pr-syslog.c0000644000175000017500000002507611707724474017445 0ustar frankiefrankie/* * Copyright (c) 1983, 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* $Id: pr-syslog.c,v 1.26 2012/01/25 07:03:24 castaglia Exp $ */ #include "conf.h" #if defined(SOLARIS2) || defined(IRIX6) || defined(SYSV5UNIXWARE7) # define HAVE_DEV_LOG_STREAMS 1 #endif /* SOLARIS2 or IRIX6 or SYSV5UNIXWARE7 */ #ifdef HAVE_DEV_LOG_STREAMS # include #endif static int sock_type = SOCK_DGRAM; static int log_opts = 0; static const char *log_ident = NULL; static int log_facility = LOG_USER; static int log_mask = 0xff; #ifdef HAVE___PROGNAME extern char *__progname; #endif /* HAVE___PROGNAME */ #if defined(SOLARIS2_9) || defined(SOLARIS2_10) /* These tables are used for populating the stupid Solaris 9/10 syslog * "header". */ struct { int facility; const char *name; } syslog_facility_names[] = { { LOG_AUTHPRIV, "auth" }, #ifdef HAVE_LOG_FTP { LOG_FTP, "ftp" }, #endif #ifdef HAVE_LOG_CRON { LOG_CRON, "cron" }, #endif { LOG_DAEMON, "daemon" }, { LOG_KERN, "kern" }, { LOG_LOCAL0, "local0" }, { LOG_LOCAL1, "local1" }, { LOG_LOCAL2, "local2" }, { LOG_LOCAL3, "local3" }, { LOG_LOCAL4, "local4" }, { LOG_LOCAL5, "local5" }, { LOG_LOCAL6, "local6" }, { LOG_LOCAL7, "local7" }, { LOG_LPR, "lpr" }, { LOG_MAIL, "mail" }, { LOG_NEWS, "news" }, { LOG_USER, "user" }, { LOG_UUCP, "uucp" }, { 0, NULL } }; struct { int level; const char *name; } syslog_level_names[] = { { PR_LOG_EMERG, "emerg" }, { PR_LOG_ALERT, "alert" }, { PR_LOG_CRIT, "crit" }, { PR_LOG_ERR, "error" }, { PR_LOG_ERR, "error" }, { PR_LOG_WARNING, "warn" }, { PR_LOG_NOTICE, "notice" }, { PR_LOG_INFO, "info" }, { PR_LOG_DEBUG, "debug" }, { 0, NULL } }; #endif /* Solaris 9 or 10 */ static void pr_vsyslog(int sockfd, int pri, register const char *fmt, va_list ap) { time_t now; static char logbuf[PR_TUNABLE_BUFFER_SIZE] = {'\0'}; size_t buflen = 0; int saved_errno = errno; #ifdef HAVE_DEV_LOG_STREAMS struct strbuf ctl, dat; struct log_ctl lc; #else char *timestr = NULL; # ifdef HAVE_TZNAME char *saved_tzname[2]; # endif /* HAVE_TZNAME */ #endif /* Clear the buffer */ memset(logbuf, '\0', sizeof(logbuf)); /* Check for invalid bits. */ if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) pri &= LOG_PRIMASK|LOG_FACMASK; /* Check priority against setlogmask values. */ if ((LOG_MASK(pri & LOG_PRIMASK) & log_mask) == 0) return; /* Set default facility if none specified. */ if ((pri & LOG_FACMASK) == 0) pri |= log_facility; #ifndef HAVE_DEV_LOG_STREAMS snprintf(logbuf, sizeof(logbuf), "<%d>", pri); logbuf[sizeof(logbuf)-1] = '\0'; buflen = strlen(logbuf); # ifdef HAVE_TZNAME /* Preserve the old tzname setting. */ memcpy(saved_tzname, tzname, sizeof(saved_tzname)); # endif /* HAVE_TZNAME */ time(&now); timestr = ctime(&now); # ifdef HAVE_TZNAME /* Restore the old tzname setting, to prevent ctime(3) from inadvertently * affecting things, as when we're in a chroot, and ctime(3) loses the * timezone info. */ memcpy(tzname, saved_tzname, sizeof(saved_tzname)); # endif /* HAVE_TZNAME */ /* Remove the trailing newline from the time string returned by ctime(3). */ timestr[strlen(timestr)-1] = '\0'; /* Skip past the leading "day of week" prefix. */ timestr += 4; snprintf(&(logbuf[buflen]), sizeof(logbuf) - buflen, "%.15s ", timestr); logbuf[sizeof(logbuf)-1] = '\0'; buflen = strlen(logbuf); #endif time(&now); if (log_ident == NULL) #ifdef HAVE___PROGNAME log_ident = __progname; #else log_ident = "proftpd"; #endif /* HAVE___PROGNAME */ if (buflen < sizeof(logbuf) && log_ident != NULL) { snprintf(&(logbuf[buflen]), sizeof(logbuf) - buflen, "%s", log_ident); logbuf[sizeof(logbuf)-1] = '\0'; buflen = strlen(logbuf); } if (buflen < sizeof(logbuf)-1 && (log_opts & LOG_PID)) { snprintf(&(logbuf[buflen]), sizeof(logbuf) - buflen, "[%d]", (int)getpid()); logbuf[sizeof(logbuf)-1] = '\0'; buflen = strlen(logbuf); } if (buflen < sizeof(logbuf)-1 && log_ident != NULL) { snprintf(&(logbuf[buflen]), sizeof(logbuf) - buflen, ": "); logbuf[sizeof(logbuf)-1] = '\0'; buflen = strlen(logbuf); } #if defined(SOLARIS2_9) || defined(SOLARIS2_10) /* Add in the (IMHO stupid and nonportable) syslog "header" that was added * to the Solaris 9/10 libc syslog(3) function. Some sites apparently * think that trying to use this header to generate reports of logging * is a Good Idea; I'll have the last laugh when those sites try to move * to a different platform with different syslog logging. * * The header to be added looks like: * * "[ID %lu %s.%s]" * * where the ID is generated using STRLOG_MAKE_MSGID(), a macro defined * in , and the following two strings are the syslog * facility and level, respectively. */ if (buflen < sizeof(logbuf)) { register unsigned int i; uint32_t msgid; const char *facility_name = "unknown", *level_name = "unknown"; STRLOG_MAKE_MSGID(fmt, msgid); for (i = 0; syslog_facility_names[i].name; i++) { if (syslog_facility_names[i].facility == log_facility) { facility_name = syslog_facility_names[i].name; break; } } for (i = 0; syslog_level_names[i].name; i++) { if (syslog_level_names[i].level == (pri & LOG_PRIMASK)) { level_name = syslog_level_names[i].name; break; } } snprintf(&(logbuf[buflen]), sizeof(logbuf) - buflen, "[ID %lu %s.%s] ", (unsigned long) msgid, facility_name, level_name); logbuf[sizeof(logbuf)-1] = '\0'; buflen = strlen(logbuf); } #endif /* Solaris 9 or 10 */ /* Restore errno for %m format. */ errno = saved_errno; /* We have the header. Print the user's format into the buffer. */ if (buflen < sizeof(logbuf)) { vsnprintf(&(logbuf[buflen]), sizeof(logbuf) - buflen, fmt, ap); logbuf[sizeof(logbuf)-1] = '\0'; buflen = strlen(logbuf); } /* Always make sure the buffer is NUL-terminated */ logbuf[sizeof(logbuf)-1] = '\0'; /* If we have a SOCK_STREAM connection, also send ASCII NUL as a record * terminator. */ if (sock_type == SOCK_STREAM) ++buflen; #ifndef HAVE_DEV_LOG_STREAMS send(sockfd, logbuf, buflen, 0); #else /* Prepare the structs for use by putmsg(). As /dev/log is a STREAMS * device on Solaris (and possibly other platforms?), putmsg() is * used so that syslog facility and level are properly honored; write() * does not seem to work as desired. */ ctl.len = ctl.maxlen = sizeof(lc); ctl.buf = (char *) &lc; dat.len = dat.maxlen = buflen; dat.buf = logbuf; lc.level = 0; lc.flags = SL_CONSOLE; lc.pri = pri; putmsg(sockfd, &ctl, &dat, 0); #endif } void pr_syslog(int sockfd, int pri, const char *fmt, ...) { va_list ap; va_start(ap, fmt); pr_vsyslog(sockfd, pri, fmt, ap); va_end(ap); } #ifndef HAVE_DEV_LOG_STREAMS /* AF_UNIX address of local logger */ static struct sockaddr_un syslog_addr; #endif int pr_openlog(const char *ident, int opts, int facility) { int sockfd; if (ident != NULL) log_ident = ident; log_opts = opts; if (facility != 0 && (facility &~ LOG_FACMASK) == 0) log_facility = facility; #ifndef HAVE_DEV_LOG_STREAMS sockfd = -1; while (1) { socklen_t addrlen = 0; if (sockfd == -1) { syslog_addr.sun_family = AF_UNIX; sstrncpy(syslog_addr.sun_path, PR_PATH_LOG, sizeof(syslog_addr.sun_path)); syslog_addr.sun_path[sizeof(syslog_addr.sun_path)-1] = '\0'; addrlen = sizeof(syslog_addr); if (log_opts & LOG_NDELAY) { sockfd = socket(AF_UNIX, sock_type, 0); if (sockfd < 0) { return -1; } fcntl(sockfd, F_SETFD, 1); } } if (sockfd != -1) { int old_errno = errno; if (connect(sockfd, (struct sockaddr *) &syslog_addr, addrlen) == -1) { int saved_errno = errno; close(sockfd); sockfd = -1; if (sock_type == SOCK_DGRAM && saved_errno == EPROTOTYPE) { /* retry with next SOCK_STREAM */ sock_type = SOCK_STREAM; errno = old_errno; continue; } } } break; } #else sockfd = open(PR_PATH_LOG, O_WRONLY); # ifdef SOLARIS2 /* Workaround for a /dev/log bug (SunSolve bug #4817079) on Solaris. */ if (sockfd >= 0) { struct strioctl ic; ic.ic_cmd = I_ERRLOG; ic.ic_timout = 0; ic.ic_len = 0; ic.ic_dp = NULL; if (ioctl(sockfd, I_STR, &ic) < 0) fprintf(stderr, "error setting I_ERRLOG on " PR_PATH_LOG ": %s\n", strerror(errno)); } # endif /* SOLARIS2 */ #endif return sockfd; } void pr_closelog(int sockfd) { close(sockfd); sockfd = -1; /* Clear the identity prefix string. */ log_ident = NULL; /* default */ sock_type = SOCK_DGRAM; } /* setlogmask -- set the log mask level */ int pr_setlogmask(int new_mask) { int old_mask; old_mask = log_mask; if (new_mask != 0) log_mask = new_mask; return old_mask; } int pr_setlogfacility(int new_facility) { int old_facility; old_facility = log_facility; if (new_facility > 0) log_facility = new_facility; return old_facility; } proftpd-dfsg-1.3.5~rc3/src/0000755000175000017500000000000012156653653015350 5ustar frankiefrankieproftpd-dfsg-1.3.5~rc3/src/prxs0000644000175000017500000002120612156653650016265 0ustar frankiefrankie#!/usr/bin/env perl # --------------------------------------------------------------------------- # Copyright (C) 2008-2012 TJ Saunders # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. # # $Id: prxs.in,v 1.10 2012/09/19 00:11:39 castaglia Exp $ # --------------------------------------------------------------------------- use strict; use File::Basename qw(basename); use Getopt::Long; Getopt::Long::Configure("no_ignorecase"); my $prog = basename($0); my $compiler = q(gcc); my $cflags = q( -DLINUX -O2 -Wall -DPR_SHARED_MODULE); my $cppflags = q(); my $ltdl_ldflags = q(); my $sbindir = q(/usr/local/sbin); my $includedir = q(/usr/local/include); my $installer = q(/usr/bin/install -c); my $install_strip = q(-s); my $libexecdir = q(/usr/local/libexec); my $libtool = 'libtool'; if (!defined($ENV{LIBTOOL})) { if ($^O eq 'darwin') { $libtool = 'glibtool'; } } else { $libtool = $ENV{LIBTOOL}; } my $opts = {}; GetOptions($opts, 'c|compile', 'i|install', 'd|clean', 'h|help', 'name=s', 'D=s@', 'I=s@', 'L=s@', 'l=s@', 'W=s@'); if ($opts->{h}) { usage(); exit 0; } # Make sure we can query proftpd to find out its list of installed modules. # Unless we see mod_dso listed, there's no point in compiling a shared # module for proftpd to use. my $proftpd = "$sbindir/proftpd"; unless (-x $proftpd) { print STDERR "$proftpd not found or not executable\n"; exit 1; } unless (grep /mod_dso/, `$proftpd -l`) { print STDERR "\nYour installed proftpd does not support shared modules/DSOs.\n"; print STDERR "Make sure the --enable-dso configure option is used when\n"; print STDERR "compiling proftpd.\n\n"; exit 1; } # If the libtool-specific linker flags are empty, it means that the # script was generated by a configure script lacking the --enable-dso option. unless (length($ltdl_ldflags) > 0) { print STDERR "\nMissing the required libtool flags.\n"; print STDERR "Make sure the --enable-dso configure option is used when\n"; print STDERR "compiling proftpd.\n\n"; exit 1; } # Now, depending on the requested mode (compile/install/clean), build up # and execute the commands. my $mod_name = get_module_name(); if (defined($opts->{c})) { my $srcs = []; my $objs = []; my $configure_script; foreach my $file (@ARGV) { if ($file =~ /\.c$/) { push(@$srcs, $file); if ($file =~ /\/?mod_[^\/]+\.c$/) { $configure_script = $file; $configure_script =~ s/\/?mod_[^\/]+\.c$/\/configure/; } my $obj = $file; $obj =~ s/\.c$/\.lo/; # Handle an argument such as 'contrib/mod_sql_sqlite.c' by keeping # just the name portion of the path. $obj =~ s/^(.*)\///g; push(@$objs, $obj); } else { print STDERR "Cannot compile non-.c file $file, aborting\n"; exit 1; } } if (defined($configure_script)) { # Check for any configure script for this module. If present, error out # for now. if (-f $configure_script) { print STDERR "Cannot compile $mod_name using prxs; use $configure_script instead\n"; exit 1; } } foreach my $def (@{ $opts->{D} }) { if ($def =~ /^(\S+)=(\S+)$/) { $cflags .= " -D'$1=$2'"; } else { $cflags .= " -D$def"; } } $cflags .= " -I. -I$includedir/proftpd"; foreach my $incdir (@{ $opts->{I} }) { $cflags .= " -I$incdir"; } my $cmds = []; foreach my $src (@$srcs) { push(@$cmds, "$libtool --mode=compile $compiler $cflags -c $src"); } run_cmds($cmds); my $objlist = ''; foreach my $obj (@$objs) { $objlist .= " $obj"; } my $ldflags .= " $ltdl_ldflags"; foreach my $libdir (@{ $opts->{L} }) { $ldflags .= " -L$libdir"; } # Scan through the .c files, looking for the $Libraries$ hint that # proftpd's build system uses. foreach my $src (@$srcs) { if (open(my $fh, "< $src")) { while (my $line = <$fh>) { chomp($line); if ($line =~ /\$Libraries:\s+(.*)?\$/) { my $hint = $1; # Assume that the library hint list is space-separated; add them # to the $opts hashref. Don't forget to strip of the '-l' prefix; # that is added back later in the handling of $opts. my $libs = [split(/\s+/, $hint)]; foreach my $lib (@$libs) { $lib =~ s/^\-l//; push(@{ $opts->{l} }, $lib); } last; } } close($fh); } else { print STDERR "Unable to scan $src for \$Libraries\$ hint: $!\n"; } } my $libs = ""; foreach my $lib (@{ $opts->{l} }) { $libs .= " -l$lib"; } $cmds = []; push(@$cmds, "$libtool --mode=link $compiler -o $mod_name.la -rpath $libexecdir $ldflags $objlist $libs"); run_cmds($cmds); } if (defined($opts->{i})) { my $cmds = []; push(@$cmds, "$libtool --mode=install $installer $install_strip $mod_name.la $ENV{DESTDIR}$libexecdir"); run_cmds($cmds); # Don't forget to remind the user to manually edit their proftpd.conf # and add the LoadModule to load the just-installed module. my $load_mod_name = $mod_name; $load_mod_name =~ s/^(.*)\///; print STDOUT "\nTo load your newly installed module into proftpd, be sure\n"; print STDOUT "to edit your proftpd.conf and add the following:\n\n"; print STDOUT " \n"; print STDOUT " LoadModule $load_mod_name.c\n"; print STDOUT " \n\n"; print STDOUT "and then restart your proftpd server, so that the config change\n"; print STDOUT "becomes live.\n\n"; } if (defined($opts->{d})) { my $cmds = []; push(@$cmds, "$libtool --mode=clean rm -f $mod_name.la *.lo"); run_cmds($cmds); } if (!defined($opts->{c}) && !defined($opts->{i}) && !defined($opts->{d})) { print STDERR "No compile, install, or clean mode requested, exiting\n"; exit 1; } exit 0; sub get_module_name { # Determine the name of the module (e.g. "mod_foo") being operated upon. if (defined($opts->{n})) { return $opts->{n}; } foreach my $file (@ARGV) { # Handle an argument such as 'contrib/mod_sql_sqlite.c' by keeping # just the name portion of the path. if ($file =~ /\/?mod_([^\/]+)\.(c|la)$/) { return "mod_$1"; } } return "mod_unknown"; } sub run_cmds { my $cmds = shift; foreach my $cmd (@$cmds) { print STDOUT "$cmd\n"; my $res = system($cmd); if ($res) { print STDERR "$prog: error executing command (", $res >> 8, ")\n"; exit 1; } } } sub usage { my $prog = basename($0); print STDOUT < Actions: -c, --compile Compiles the listed .c source files into a proftpd DSO module. -i, --install Installs a compiled proftpd DSO module into the directory where proftpd expects to find loadable DSO modules. -d, --clean Removes any generated files, returning the build directory to a clean state. Options: -h, --help Displays this message. -n, --name Tells prxs the name of the module being compiled. By default, prxs determines the module name from the list of .c files listed, expecting to see a "mod_\$name.c" file. -D key Passes these macros through to the compilation step. -D key=value Note that the space before the key is important. -I includedir Specify additional include file search directories. Note that the space before the directory is important. -L libdir Specify additional library file search directories. Note that the space before the directory is important. -l library Specify additional libraries for linking. Note that the space before the library name is important. At least one of the above actions must be specified when using prxs. More than one action can be specified at the same time. To use prxs all in one step, you could do: prxs -c -i -d mod_custom.c EOU } proftpd-dfsg-1.3.5~rc3/src/rlimit.c0000644000175000017500000001016512154170143017001 0ustar frankiefrankie/* * ProFTPD - FTP server daemon * Copyright (c) 2013 The ProFTPD Project team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * As a special exemption, The ProFTPD Project team and other respective * copyright holders give permission to link this program with OpenSSL, and * distribute the resulting executable, without including the source code for * OpenSSL in the source distribution. */ /* Resource limits implementation * $Id: rlimit.c,v 1.4 2013/06/06 20:26:11 castaglia Exp $ */ #include "conf.h" static int get_rlimit(int resource, rlim_t *current, rlim_t *max) { struct rlimit rlim; int res; if (current == NULL && max == NULL) { errno = EINVAL; return -1; } res = getrlimit(resource, &rlim); if (res < 0) { return res; } if (current != NULL) { *current = rlim.rlim_cur; } if (max != NULL) { *max = rlim.rlim_max; } return 0; } static int set_rlimit(int resource, rlim_t current, rlim_t max) { struct rlimit rlim; int res; rlim.rlim_cur = current; rlim.rlim_max = max; res = setrlimit(resource, &rlim); return res; } int pr_rlimit_get_core(rlim_t *current, rlim_t *max) { #if defined(RLIMIT_CORE) return get_rlimit(RLIMIT_CORE, current, max); #else errno = ENOSYS; return -1; #endif /* No RLIMIT_CORE */ } int pr_rlimit_set_core(rlim_t current, rlim_t max) { #if defined(RLIMIT_CORE) return set_rlimit(RLIMIT_CORE, current, max); #else errno = ENOSYS; return -1; #endif /* No RLIMIT_CORE */ } int pr_rlimit_get_cpu(rlim_t *current, rlim_t *max) { #if defined(RLIMIT_CPU) return get_rlimit(RLIMIT_CPU, current, max); #else errno = ENOSYS; return -1; #endif /* No RLIMIT_CPU */ } int pr_rlimit_set_cpu(rlim_t current, rlim_t max) { #if defined(RLIMIT_CPU) return set_rlimit(RLIMIT_CPU, current, max); #else errno = ENOSYS; return -1; #endif /* No RLIMIT_CPU */ } int pr_rlimit_get_files(rlim_t *current, rlim_t *max) { #if defined(RLIMIT_NOFILE) return get_rlimit(RLIMIT_NOFILE, current, max); #elif defined(RLIMIT_OFILE) return get_rlimit(RLIMIT_OFILE, current, max); #else errno = ENOSYS; return -1; #endif /* No RLIMIT_NOFILE or RLIMIT_OFILE */ } int pr_rlimit_set_files(rlim_t current, rlim_t max) { #if defined(RLIMIT_NOFILE) return set_rlimit(RLIMIT_NOFILE, current, max); #elif defined(RLIMIT_OFILE) return set_rlimit(RLIMIT_OFILE, current, max); #else errno = ENOSYS; return -1; #endif /* No RLIMIT_NOFILE or RLIMIT_OFILE */ } int pr_rlimit_get_memory(rlim_t *current, rlim_t *max) { #if defined(RLIMIT_AS) return get_rlimit(RLIMIT_AS, current, max); #elif defined(RLIMIT_DATA) return get_rlimit(RLIMIT_DATA, current, max); #elif defined(RLIMIT_VMEM) return get_rlimit(RLIMIT_VMEM, current, max); #else errno = ENOSYS; return -1; #endif /* No RLIMIT_AS, RLIMIT_DATA, or RLIMIT_VMEM. */ } int pr_rlimit_set_memory(rlim_t current, rlim_t max) { #if defined(RLIMIT_AS) return set_rlimit(RLIMIT_AS, current, max); #elif defined(RLIMIT_DATA) return set_rlimit(RLIMIT_DATA, current, max); #else errno = ENOSYS; return -1; #endif /* No RLIMIT_AS or RLIMIT_DATA */ } int pr_rlimit_get_nproc(rlim_t *current, rlim_t *max) { #if defined(RLIMIT_NPROC) return get_rlimit(RLIMIT_NPROC, current, max); #else errno = ENOSYS; return -1; #endif /* No RLIMIT_NPROC */ } int pr_rlimit_set_nproc(rlim_t current, rlim_t max) { #if defined(RLIMIT_NPROC) return set_rlimit(RLIMIT_NPROC, current, max); #else errno = ENOSYS; return -1; #endif /* No RLIMIT_NPROC */ } proftpd-dfsg-1.3.5~rc3/src/display.c0000644000175000017500000003044712107234565017162 0ustar frankiefrankie/* * ProFTPD - FTP server daemon * Copyright (c) 2004-2013 The ProFTPD Project team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * As a special exemption, The ProFTPD Project team and other respective * copyright holders give permission to link this program with OpenSSL, and * distribute the resulting executable, without including the source code for * OpenSSL in the source distribution. */ /* Display of files * $Id: display.c,v 1.29 2013/02/14 19:22:29 castaglia Exp $ */ #include "conf.h" static int first_msg_sent = FALSE; static const char *first_msg = NULL; static const char *prev_msg = NULL; static void format_size_str(char *buf, size_t buflen, off_t size) { char units[] = {'K', 'M', 'G', 'T', 'P'}; register unsigned int i = 0; /* Determine the appropriate units label to use. */ while (size > 1024) { size /= 1024; i++; } /* Now, prepare the buffer. */ snprintf(buf, buflen, "%.3" PR_LU "%cB", (pr_off_t) size, units[i]); } static int display_add_line(pool *p, const char *resp_code, const char *resp_msg) { /* Handle the case where the data to Display might contain only one line. */ if (first_msg_sent == FALSE && first_msg == NULL) { first_msg = pstrdup(p, resp_msg); return 0; } if (first_msg != NULL) { pr_response_send_raw("%s-%s", resp_code, first_msg); first_msg = NULL; first_msg_sent = TRUE; prev_msg = pstrdup(p, resp_msg); return 0; } if (prev_msg != NULL) { if (session.multiline_rfc2228) { pr_response_send_raw("%s-%s", resp_code, prev_msg); } else { pr_response_send_raw(" %s", prev_msg); } } prev_msg = pstrdup(p, resp_msg); return 0; } static int display_flush_lines(pool *p, const char *resp_code, int flags) { if (first_msg != NULL) { if (session.auth_mech != NULL) { if (flags & PR_DISPLAY_FL_NO_EOM) { pr_response_send_raw("%s-%s", resp_code, first_msg); } else { pr_response_send_raw("%s %s", resp_code, first_msg); } } else { /* There is a special case if the client has not yet authenticated; it * means we are handling a DisplayConnect file. The server will send * a banner as well, so we need to treat this is the start of a multiline * response. */ pr_response_send_raw("%s-%s", resp_code, first_msg); } } else { if (prev_msg) { if (session.multiline_rfc2228) { pr_response_send_raw("%s-%s", resp_code, prev_msg); } else { if (flags & PR_DISPLAY_FL_NO_EOM) { pr_response_send_raw(" %s", prev_msg); } else { pr_response_send_raw("%s %s", resp_code, prev_msg); } } } } /* Reset state for the next set of lines. */ first_msg_sent = FALSE; first_msg = NULL; prev_msg = NULL; return 0; } static int display_fh(pr_fh_t *fh, const char *fs, const char *code, int flags) { struct stat st; char buf[PR_TUNABLE_BUFFER_SIZE] = {'\0'}; int len, res; unsigned int *current_clients = NULL; unsigned int *max_clients = NULL; off_t fs_size = 0; pool *p; void *v; xaset_t *s; config_rec *c = NULL; const char *serverfqdn = main_server->ServerFQDN; char *outs, mg_size[12] = {'\0'}, mg_size_units[12] = {'\0'}, mg_max[12] = "unlimited"; char total_files_in[12] = {'\0'}, total_files_out[12] = {'\0'}, total_files_xfer[12] = {'\0'}; char mg_class_limit[12] = {'\0'}, mg_cur[12] = {'\0'}, mg_xfer_bytes[12] = {'\0'}, mg_cur_class[12] = {'\0'}; char mg_xfer_units[12] = {'\0'}, *user; const char *mg_time; char *rfc1413_ident = NULL; /* Stat the opened file to determine the optimal buffer size for IO. */ memset(&st, 0, sizeof(st)); pr_fsio_fstat(fh, &st); fh->fh_iosz = st.st_blksize; res = pr_fs_fgetsize(fh->fh_fd, &fs_size); if (res < 0 && errno != ENOSYS) { (void) pr_log_debug(DEBUG7, "error getting filesystem size for '%s': %s", fh->fh_path, strerror(errno)); fs_size = 0; } snprintf(mg_size, sizeof(mg_size), "%" PR_LU, (pr_off_t) fs_size); format_size_str(mg_size_units, sizeof(mg_size_units), fs_size); p = make_sub_pool(session.pool); pr_pool_tag(p, "Display Pool"); s = (session.anon_config ? session.anon_config->subset : main_server->conf); mg_time = pr_strtime(time(NULL)); max_clients = get_param_ptr(s, "MaxClients", FALSE); v = pr_table_get(session.notes, "client-count", NULL); if (v) { current_clients = v; } snprintf(mg_cur, sizeof(mg_cur), "%u", current_clients ? *current_clients: 1); if (session.conn_class != NULL && session.conn_class->cls_name != NULL) { unsigned int *class_clients = NULL; config_rec *maxc = NULL; unsigned int maxclients = 0; v = pr_table_get(session.notes, "class-client-count", NULL); if (v) { class_clients = v; } snprintf(mg_cur_class, sizeof(mg_cur_class), "%u", class_clients ? *class_clients : 0); /* For the %z variable, first we scan through the MaxClientsPerClass, * and use the first applicable one. If none are found, look for * any MaxClients set. */ maxc = find_config(main_server->conf, CONF_PARAM, "MaxClientsPerClass", FALSE); while (maxc) { pr_signals_handle(); if (strcmp(maxc->argv[0], session.conn_class->cls_name) != 0) { maxc = find_config_next(maxc, maxc->next, CONF_PARAM, "MaxClientsPerClass", FALSE); continue; } maxclients = *((unsigned int *) maxc->argv[1]); break; } if (maxclients == 0) { maxc = find_config(main_server->conf, CONF_PARAM, "MaxClients", FALSE); if (maxc) maxclients = *((unsigned int *) maxc->argv[0]); } snprintf(mg_class_limit, sizeof(mg_class_limit), "%u", maxclients); } else { snprintf(mg_class_limit, sizeof(mg_class_limit), "%u", max_clients ? *max_clients : 0); snprintf(mg_cur_class, sizeof(mg_cur_class), "%u", 0); } snprintf(mg_xfer_bytes, sizeof(mg_xfer_bytes), "%" PR_LU, (pr_off_t) session.total_bytes >> 10); snprintf(mg_xfer_units, sizeof(mg_xfer_units), "%" PR_LU "B", (pr_off_t) session.total_bytes); if (session.total_bytes >= 10240) { snprintf(mg_xfer_units, sizeof(mg_xfer_units), "%" PR_LU "kB", (pr_off_t) session.total_bytes >> 10); } else if ((session.total_bytes >> 10) >= 10240) { snprintf(mg_xfer_units, sizeof(mg_xfer_units), "%" PR_LU "MB", (pr_off_t) session.total_bytes >> 20); } else if ((session.total_bytes >> 20) >= 10240) { snprintf(mg_xfer_units, sizeof(mg_xfer_units), "%" PR_LU "GB", (pr_off_t) session.total_bytes >> 30); } snprintf(mg_max, sizeof(mg_max), "%u", max_clients ? *max_clients : 0); user = pr_table_get(session.notes, "mod_auth.orig-user", NULL); if (user == NULL) user = ""; c = find_config(main_server->conf, CONF_PARAM, "MasqueradeAddress", FALSE); if (c) { pr_netaddr_t *masq_addr = (pr_netaddr_t *) c->argv[0]; serverfqdn = pr_netaddr_get_dnsstr(masq_addr); } /* "Stringify" the file number for this session. */ snprintf(total_files_in, sizeof(total_files_in), "%u", session.total_files_in); total_files_in[sizeof(total_files_in)-1] = '\0'; snprintf(total_files_out, sizeof(total_files_out), "%u", session.total_files_out); total_files_out[sizeof(total_files_out)-1] = '\0'; snprintf(total_files_xfer, sizeof(total_files_xfer), "%u", session.total_files_xfer); total_files_xfer[sizeof(total_files_xfer)-1] = '\0'; rfc1413_ident = pr_table_get(session.notes, "mod_ident.rfc1413-ident", NULL); if (rfc1413_ident == NULL) { rfc1413_ident = "UNKNOWN"; } while (pr_fsio_gets(buf, sizeof(buf), fh) != NULL) { char *tmp; pr_signals_handle(); buf[sizeof(buf)-1] = '\0'; len = strlen(buf); while (len && (buf[len-1] == '\r' || buf[len-1] == '\n')) { buf[len-1] = '\0'; len--; } /* Check for any Variable-type strings. */ tmp = strstr(buf, "%{"); while (tmp) { char *key, *tmp2; const char *val; pr_signals_handle(); tmp2 = strchr(tmp, '}'); if (!tmp2) { tmp = strstr(tmp + 1, "%{"); continue; } key = pstrndup(p, tmp, tmp2 - tmp + 1); /* There are a couple of special-case keys to watch for: * * env:$var * time:$fmt * * The Var API does not easily support returning values for keys * where part of the value depends on part of the key. That's why * these keys are handled here, instead of in pr_var_get(). */ if (strncmp(key, "%{time:", 7) == 0) { char time_str[128], *fmt; time_t now; struct tm *time_info; fmt = pstrndup(p, key + 7, strlen(key) - 8); now = time(NULL); time_info = pr_localtime(NULL, &now); memset(time_str, 0, sizeof(time_str)); strftime(time_str, sizeof(time_str), fmt, time_info); val = pstrdup(p, time_str); } else if (strncmp(key, "%{env:", 6) == 0) { char *env_var; env_var = pstrndup(p, key + 6, strlen(key) - 7); val = pr_env_get(p, env_var); if (val == NULL) { pr_trace_msg("var", 4, "no value set for environment variable '%s', using \"(none)\"", env_var); val = "(none)"; } } else { val = pr_var_get(key); if (val == NULL) { pr_trace_msg("var", 4, "no value set for name '%s', using \"(none)\"", key); val = "(none)"; } } outs = sreplace(p, buf, key, val, NULL); sstrncpy(buf, outs, sizeof(buf)); tmp = strstr(outs, "%{"); } outs = sreplace(p, buf, "%C", (session.cwd[0] ? session.cwd : "(none)"), "%E", main_server->ServerAdmin, "%F", mg_size, "%f", mg_size_units, "%i", total_files_in, "%K", mg_xfer_bytes, "%k", mg_xfer_units, "%L", serverfqdn, "%M", mg_max, "%N", mg_cur, "%o", total_files_out, "%R", (session.c && session.c->remote_name ? session.c->remote_name : "(unknown)"), "%T", mg_time, "%t", total_files_xfer, "%U", user, "%u", rfc1413_ident, "%V", main_server->ServerName, "%x", session.conn_class ? session.conn_class->cls_name : "(unknown)", "%y", mg_cur_class, "%z", mg_class_limit, NULL); sstrncpy(buf, outs, sizeof(buf)); if (flags & PR_DISPLAY_FL_SEND_NOW) { /* Normally we use pr_response_add(), and let the response code * automatically handle all of the multiline response formatting. * However, some of the Display files are at times waiting for the * response chains to be flushed, which won't work (i.e. DisplayConnect * and DisplayQuit). */ display_add_line(p, code, outs); } else { pr_response_add(code, "%s", outs); } } if (flags & PR_DISPLAY_FL_SEND_NOW) { display_flush_lines(p, code, flags); } destroy_pool(p); return 0; } int pr_display_fh(pr_fh_t *fh, const char *fs, const char *code, int flags) { if (!fh || !code) { errno = EINVAL; return -1; } return display_fh(fh, fs, code, flags); } int pr_display_file(const char *path, const char *fs, const char *code, int flags) { pr_fh_t *fh = NULL; int res, xerrno; struct stat st; if (path == NULL || code == NULL) { errno = EINVAL; return -1; } fh = pr_fsio_open_canon(path, O_RDONLY); if (fh == NULL) { return -1; } res = pr_fsio_fstat(fh, &st); if (res < 0) { pr_fsio_close(fh); return -1; } if (S_ISDIR(st.st_mode)) { pr_fsio_close(fh); errno = EISDIR; return -1; } res = display_fh(fh, fs, code, flags); xerrno = errno; pr_fsio_close(fh); errno = xerrno; return res; } proftpd-dfsg-1.3.5~rc3/src/memcache.c0000644000175000017500000012502312101351201017227 0ustar frankiefrankie/* * ProFTPD - FTP server daemon * Copyright (c) 2010-2013 The ProFTPD Project team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * As a special exemption, The ProFTPD Project team and other respective * copyright holders give permission to link this program with OpenSSL, and * distribute the resulting executable, without including the source code for * OpenSSL in the source distribution. */ /* Memcache management * $Id: memcache.c,v 1.26 2013/01/28 01:21:05 castaglia Exp $ */ #include "conf.h" #ifdef PR_USE_MEMCACHE #include #if defined(LIBMEMCACHED_VERSION_HEX) # if LIBMEMCACHED_VERSION_HEX < 0x00041000 # error "libmemcached-0.41 or later required" # endif /* LIBMEMCACHED_VERSION_HEX too old */ #else # error "Unable to determine libmemcached version" #endif /* LIBMEMCACHED_VERSION_HEX */ /* libmemcached-0.41 and later included this header file. */ #include extern tpl_hook_t tpl_hook; struct mcache_rec { pool *pool; module *owner; memcached_st *mc; /* For tracking the number of "opens"/"closes" on a shared mcache_rec, * as the same struct might be used by multiple modules in the same * session, each module doing a conn_get()/conn_close(). */ unsigned int refcount; /* Table mapping modules to their namespaces */ pr_table_t *namespace_tab; }; static memcached_server_st *configured_server_list = NULL; static pr_memcache_t *sess_mcache = NULL; static uint64_t memcache_sess_conn_failures = 0; static unsigned long memcache_sess_flags = 0; static uint64_t memcache_sess_nreplicas = 0; static unsigned long memcache_conn_millis = 500; static unsigned long memcache_rcv_millis = 500; static unsigned long memcache_snd_millis = 500; static unsigned long memcache_ejected_sec = 0; #if 0 /* XXX Unused, for now. */ static unsigned long memcache_ping_interval = 0; #endif static const char *trace_channel = "memcache"; static int mcache_set_options(pr_memcache_t *mcache, unsigned long flags, uint64_t nreplicas) { memcached_return res; uint64_t val; val = memcached_behavior_get(mcache->mc, MEMCACHED_BEHAVIOR_TCP_NODELAY); if (val != 1) { res = memcached_behavior_set(mcache->mc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1); if (res != MEMCACHED_SUCCESS) { pr_trace_msg(trace_channel, 4, "error setting TCP_NODELAY behavior on connection: %s", memcached_strerror(mcache->mc, res)); } } /* Enable caching of DNS lookups. */ val = memcached_behavior_get(mcache->mc, MEMCACHED_BEHAVIOR_CACHE_LOOKUPS); if (val != 1) { res = memcached_behavior_set(mcache->mc, MEMCACHED_BEHAVIOR_CACHE_LOOKUPS, 1); if (res != MEMCACHED_SUCCESS) { pr_trace_msg(trace_channel, 4, "error setting CACHE_LOOKUPS behavior on connection: %s", memcached_strerror(mcache->mc, res)); } } /* Verify that all keys are correct. */ val = memcached_behavior_get(mcache->mc, MEMCACHED_BEHAVIOR_VERIFY_KEY); if (val != 1) { res = memcached_behavior_set(mcache->mc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1); if (res != MEMCACHED_SUCCESS) { pr_trace_msg(trace_channel, 4, "error setting VERIFY_KEY behavior on connection: %s", memcached_strerror(mcache->mc, res)); } } /* We always want consistent hashing, to minimize cache churn when * servers are added/removed from the list. */ val = memcached_behavior_get(mcache->mc, MEMCACHED_BEHAVIOR_DISTRIBUTION); if (val != MEMCACHED_DISTRIBUTION_CONSISTENT) { res = memcached_behavior_set(mcache->mc, MEMCACHED_BEHAVIOR_DISTRIBUTION, MEMCACHED_DISTRIBUTION_CONSISTENT); if (res != MEMCACHED_SUCCESS) { pr_trace_msg(trace_channel, 4, "error setting DISTRIBUTION_CONSISTENT behavior on connection: %s", memcached_strerror(mcache->mc, res)); } } /* Use blocking IO */ val = memcached_behavior_get(mcache->mc, MEMCACHED_BEHAVIOR_NO_BLOCK); if (val != 0) { res = memcached_behavior_set(mcache->mc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0); if (res != MEMCACHED_SUCCESS) { pr_trace_msg(trace_channel, 4, "error setting NO_BLOCK behavior on connection: %s", memcached_strerror(mcache->mc, res)); } } val = memcached_behavior_get(mcache->mc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT); if (memcache_sess_conn_failures > 0) { res = memcached_behavior_set(mcache->mc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, memcache_sess_conn_failures); if (res != MEMCACHED_SUCCESS) { pr_trace_msg(trace_channel, 4, "error setting SERVER_FAILURE_LIMIT behavior on connection: %s", memcached_strerror(mcache->mc, res)); } else { /* Automatically eject hosts which have reached this failure limit; * keeping them around in the memcached_st struct only causes * confusion. Note that this requires that an ejected timeout value * be configured. */ if (memcache_ejected_sec > 0) { res = memcached_behavior_set(mcache->mc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, memcache_ejected_sec); if (res != MEMCACHED_SUCCESS) { pr_trace_msg(trace_channel, 4, "error setting RETRY_TIMEOUT behavior on connection to %lu ms: %s", memcache_ejected_sec, memcached_strerror(mcache->mc, res)); } res = memcached_behavior_set(mcache->mc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS, 1); if (res != MEMCACHED_SUCCESS) { pr_trace_msg(trace_channel, 4, "error setting AUTO_EJECT_HOSTS behavior on connection: %s", memcached_strerror(mcache->mc, res)); } } } } /* Use the binary protocol by default, unless explicitly requested not to. */ val = memcached_behavior_get(mcache->mc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL); if (val != 1) { if (!(flags & PR_MEMCACHE_FL_NO_BINARY_PROTOCOL)) { res = memcached_behavior_set(mcache->mc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1); if (res != MEMCACHED_SUCCESS) { pr_trace_msg(trace_channel, 4, "error setting BINARY_PROTOCOL behavior on connection: %s", memcached_strerror(mcache->mc, res)); } } } /* Configure the timeouts. */ res = memcached_behavior_set(mcache->mc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, memcache_conn_millis); if (res != MEMCACHED_SUCCESS) { pr_trace_msg(trace_channel, 4, "error setting CONNECT_TIMEOUT behavior on connection to %lu ms: %s", memcache_conn_millis, memcached_strerror(mcache->mc, res)); } res = memcached_behavior_set(mcache->mc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, memcache_rcv_millis); if (res != MEMCACHED_SUCCESS) { pr_trace_msg(trace_channel, 4, "error setting RCV_TIMEOUT behavior on connection to %lu ms: %s", memcache_rcv_millis, memcached_strerror(mcache->mc, res)); } res = memcached_behavior_set(mcache->mc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, memcache_snd_millis); if (res != MEMCACHED_SUCCESS) { pr_trace_msg(trace_channel, 4, "error setting SND_TIMEOUT behavior on connection to %lu ms: %s", memcache_snd_millis, memcached_strerror(mcache->mc, res)); } /* Make sure that the requested number of replicas does not exceed the * server count. */ if (nreplicas > memcached_server_count(mcache->mc)) { nreplicas = memcached_server_count(mcache->mc); } /* XXX Some caveats about libmemcached replication: * * 1. Replication is enabled only if the binary protocol is used. * 2. Replication occurs only for 'delete', 'get, 'set' operations, NOT * 'add', 'cas', 'incr', 'decr', etc. */ if (nreplicas > 0 && !(flags & PR_MEMCACHE_FL_NO_BINARY_PROTOCOL)) { res = memcached_behavior_set(mcache->mc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, nreplicas); if (res != MEMCACHED_SUCCESS) { pr_trace_msg(trace_channel, 4, "error setting NUMBER_OF_REPLICAS behavior on connection: %s", memcached_strerror(mcache->mc, res)); } else { pr_trace_msg(trace_channel, 9, "storing %lu %s", (unsigned long) nreplicas, nreplicas != 1 ? "replicas" : "replica"); } } /* Use randomized reads from replicas by default, unless explicitly * requested not to. */ val = memcached_behavior_get(mcache->mc, MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ); if (val != 1) { if (!(flags & PR_MEMCACHE_FL_NO_RANDOM_REPLICA_READ)) { res = memcached_behavior_set(mcache->mc, MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ, 1); if (res != MEMCACHED_SUCCESS) { pr_trace_msg(trace_channel, 4, "error setting RANDOMIZE_REPLICA_READ behavior on connection: %s", memcached_strerror(mcache->mc, res)); } } } return 0; } static int mcache_ping_servers(pr_memcache_t *mcache) { memcached_server_st *alive_server_list; memcached_return res; memcached_st *clone; uint32_t server_count; register unsigned int i; /* We always start with the configured list of servers. */ clone = memcached_clone(NULL, mcache->mc); if (clone == NULL) { errno = ENOMEM; return -1; } memcached_servers_reset(clone); memcached_server_push(clone, configured_server_list); server_count = memcached_server_count(clone); pr_trace_msg(trace_channel, 16, "pinging %lu memcached %s", (unsigned long) server_count, server_count != 1 ? "servers" : "server"); alive_server_list = NULL; for (i = 0; i < server_count; i++) { memcached_server_instance_st server; server = memcached_server_instance_by_position(clone, i); pr_trace_msg(trace_channel, 17, "pinging server %s:%d", memcached_server_name(server), memcached_server_port(server)); if (libmemcached_util_ping(memcached_server_name(server), memcached_server_port(server), &res) == FALSE) { pr_trace_msg(trace_channel, 4, "error pinging %s:%d: %s", memcached_server_name(server), memcached_server_port(server), memcached_strerror(clone, res)); } else { pr_trace_msg(trace_channel, 17, "server %s:%d is alive", memcached_server_name(server), memcached_server_port(server)); alive_server_list = memcached_server_list_append(alive_server_list, memcached_server_name(server), memcached_server_port(server), &res); if (alive_server_list == NULL) { pr_trace_msg(trace_channel, 1, "error appending server %s:%d to list: %s", memcached_server_name(server), memcached_server_port(server), memcached_strerror(clone, res)); memcached_free(clone); errno = EPERM; return -1; } } } if (alive_server_list != NULL) { memcached_servers_reset(mcache->mc); res = memcached_server_push(mcache->mc, alive_server_list); if (res != MEMCACHED_SUCCESS) { unsigned int count; count = memcached_server_list_count(alive_server_list); pr_trace_msg(trace_channel, 2, "error adding %u alive memcached %s to connection: %s", count, count != 1 ? "servers" : "server", memcached_strerror(mcache->mc, res)); memcached_free(clone); errno = EPERM; return -1; } else { unsigned int count; count = memcached_server_list_count(alive_server_list); pr_trace_msg(trace_channel, 9, "now using %d alive memcached %s", count, count != 1 ? "servers" : "server"); memcached_server_list_free(alive_server_list); } } memcached_free(clone); return 0; } static int mcache_stat_servers(pr_memcache_t *mcache) { memcached_stat_st *mst; memcached_return res; mst = memcached_stat(mcache->mc, NULL, &res); if (mst != NULL) { if (res == MEMCACHED_SUCCESS) { register unsigned int i; const char *stat_keys[] = { "version", "uptime", "curr_connections", "curr_items", "bytes", "limit_maxbytes", NULL }; /* Log some of the stats about the memcached servers to which we just * connected. */ for (i = 0; stat_keys[i] != NULL; i++) { char *info; info = memcached_stat_get_value(mcache->mc, mst, stat_keys[i], &res); if (info != NULL) { pr_trace_msg(trace_channel, 9, "memcached server stats: %s = %s", stat_keys[i], info); free(info); } else { pr_trace_msg(trace_channel, 6, "unable to obtain '%s' stat: %s", stat_keys[i], memcached_strerror(mcache->mc, res)); } } } else { switch (res) { case MEMCACHED_ERRNO: if (errno != EINPROGRESS) { pr_trace_msg(trace_channel, 3, "error requesting memcached stats: system error: %s", strerror(errno)); break; } else { /* We know that we're not using nonblocking IO; this value usually * means that libmemcached could not connect to the configured * memcached servers. So set the value to something more * indicative, and fall through. */ res = MEMCACHED_CONNECTION_FAILURE; } case MEMCACHED_SOME_ERRORS: case MEMCACHED_SERVER_MARKED_DEAD: case MEMCACHED_CONNECTION_FAILURE: { memcached_server_instance_st server; server = memcached_server_get_last_disconnect(mcache->mc); if (server != NULL) { pr_trace_msg(trace_channel, 3, "unable to connect to %s:%d", memcached_server_name(server), memcached_server_port(server)); } } default: pr_trace_msg(trace_channel, 6, "error requesting memcached stats: %s", memcached_strerror(mcache->mc, res)); break; } } memcached_stat_free(mcache->mc, mst); } return 0; } pr_memcache_t *pr_memcache_conn_get(void) { if (sess_mcache != NULL) { sess_mcache->refcount++; return sess_mcache; } return pr_memcache_conn_new(session.pool, NULL, memcache_sess_flags, memcache_sess_nreplicas); } pr_memcache_t *pr_memcache_conn_new(pool *p, module *m, unsigned long flags, uint64_t nreplicas) { pr_memcache_t *mcache; pool *sub_pool; memcached_st *mc; memcached_return res; if (p == NULL) { errno = EINVAL; return NULL; } if (configured_server_list == NULL) { pr_trace_msg(trace_channel, 9, "%s", "unable to create new memcache connection: No servers configured"); errno = EPERM; return NULL; } mc = memcached_create(NULL); if (mc == NULL) { errno = ENOMEM; return NULL; } res = memcached_server_push(mc, configured_server_list); if (res != MEMCACHED_SUCCESS) { unsigned int count; count = memcached_server_list_count(configured_server_list); pr_trace_msg(trace_channel, 2, "error adding %u memcached %s to connection: %s", count, count != 1 ? "servers" : "server", memcached_strerror(mc, res)); memcached_free(mc); errno = EPERM; return NULL; } sub_pool = pr_pool_create_sz(p, 128); pr_pool_tag(sub_pool, "Memcache connection pool"); mcache = palloc(sub_pool, sizeof(pr_memcache_t)); mcache->pool = sub_pool; mcache->owner = m; mcache->mc = mc; mcache->refcount = 1; /* The namespace table is null; it will be created if/when callers * configure namespace prefixes. */ mcache->namespace_tab = NULL; /* Set some of the desired behavior flags on the connection */ if (mcache_set_options(mcache, flags, nreplicas) < 0) { int xerrno = errno; pr_memcache_conn_close(mcache); destroy_pool(mcache->pool); errno = xerrno; return NULL; } /* Check that all of the configured servers are alive and usable. */ if (mcache_ping_servers(mcache) < 0) { int xerrno = errno; pr_memcache_conn_close(mcache); destroy_pool(mcache->pool); errno = xerrno; return NULL; } /* Make sure we are connected to the configured servers by querying * some stats/info from them. */ if (mcache_stat_servers(mcache) < 0) { int xerrno = errno; pr_memcache_conn_close(mcache); destroy_pool(mcache->pool); errno = xerrno; return NULL; } if (sess_mcache == NULL) { sess_mcache = mcache; } return mcache; } int pr_memcache_conn_close(pr_memcache_t *mcache) { if (mcache == NULL) { errno = EINVAL; return -1; } mcache->refcount--; if (mcache->refcount == 0) { memcached_free(mcache->mc); if (mcache->namespace_tab != NULL) { (void) pr_table_empty(mcache->namespace_tab); (void) pr_table_free(mcache->namespace_tab); mcache->namespace_tab = NULL; } } return 0; } static int modptr_cmp_cb(const void *k1, size_t ksz1, const void *k2, size_t ksz2) { /* Return zero to indicate a match, non-zero otherwise. */ return (((module *) k1) == ((module *) k2) ? 0 : 1); } static unsigned int modptr_hash_cb(const void *k, size_t ksz) { unsigned int key = 0; /* XXX Yes, this is a bit hacky for "hashing" a pointer value. */ memcpy(&key, k, sizeof(key)); key ^= (key >> 16); return key; } int pr_memcache_conn_set_namespace(pr_memcache_t *mcache, module *m, const char *prefix) { if (mcache == NULL || m == NULL) { errno = EINVAL; return -1; } if (mcache->namespace_tab == NULL) { pr_table_t *tab; tab = pr_table_alloc(mcache->pool, 0); if (pr_table_ctl(tab, PR_TABLE_CTL_SET_KEY_CMP, modptr_cmp_cb) < 0) { pr_trace_msg(trace_channel, 4, "error setting key comparison callback for namespace table: %s", strerror(errno)); } if (pr_table_ctl(tab, PR_TABLE_CTL_SET_KEY_HASH, modptr_hash_cb) < 0) { pr_trace_msg(trace_channel, 4, "error setting key hash callback for namespace table: %s", strerror(errno)); } mcache->namespace_tab = tab; } if (prefix != NULL) { int count; size_t prefix_len; prefix_len = strlen(prefix); count = pr_table_kexists(mcache->namespace_tab, m, sizeof(module *)); if (count <= 0) { if (pr_table_kadd(mcache->namespace_tab, m, sizeof(module *), pstrndup(mcache->pool, prefix, prefix_len), prefix_len) < 0) { pr_trace_msg(trace_channel, 7, "error adding namespace prefix '%s' for module 'mod_%s.c': %s", prefix, m->name, strerror(errno)); } } else { if (pr_table_kset(mcache->namespace_tab, m, sizeof(module *), pstrndup(mcache->pool, prefix, prefix_len), prefix_len) < 0) { pr_trace_msg(trace_channel, 7, "error setting namespace prefix '%s' for module 'mod_%s.c': %s", prefix, m->name, strerror(errno)); } } } else { /* A NULL prefix means the caller is removing their namespace maping. */ (void) pr_table_kremove(mcache->namespace_tab, m, sizeof(module *), NULL); } return 0; } int pr_memcache_add(pr_memcache_t *mcache, module *m, const char *key, void *value, size_t valuesz, time_t expires, uint32_t flags) { int res; /* XXX Should we allow null values to be added, thus allowing use of keys * as sentinels? */ if (mcache == NULL || m == NULL || key == NULL || value == NULL) { errno = EINVAL; return -1; } res = pr_memcache_kadd(mcache, m, key, strlen(key), value, valuesz, expires, flags); if (res < 0) { int xerrno = errno; pr_trace_msg(trace_channel, 2, "error adding key '%s', value (%lu bytes): %s", key, (unsigned long) valuesz, strerror(xerrno)); errno = xerrno; return -1; } return 0; } int pr_memcache_decr(pr_memcache_t *mcache, module *m, const char *key, uint32_t decr, uint64_t *value) { int res; /* XXX Should we allow null values to be added, thus allowing use of keys * as sentinels? */ if (mcache == NULL || m == NULL || key == NULL || decr == 0) { errno = EINVAL; return -1; } res = pr_memcache_kdecr(mcache, m, key, strlen(key), decr, value); if (res < 0) { int xerrno = errno; pr_trace_msg(trace_channel, 2, "error decrementing key '%s' by %lu: %s", key, (unsigned long) decr, strerror(xerrno)); errno = xerrno; return -1; } return 0; } void *pr_memcache_get(pr_memcache_t *mcache, module *m, const char *key, size_t *valuesz, uint32_t *flags) { void *ptr = NULL; if (mcache == NULL || m == NULL || key == NULL || valuesz == NULL || flags == NULL) { errno = EINVAL; return NULL; } ptr = pr_memcache_kget(mcache, m, key, strlen(key), valuesz, flags); if (ptr == NULL) { int xerrno = errno; pr_trace_msg(trace_channel, 2, "error getting data for key '%s': %s", key, strerror(xerrno)); xerrno = errno; return NULL; } return ptr; } char *pr_memcache_get_str(pr_memcache_t *mcache, module *m, const char *key, uint32_t *flags) { char *ptr = NULL; if (mcache == NULL || m == NULL || key == NULL || flags == NULL) { errno = EINVAL; return NULL; } ptr = pr_memcache_kget_str(mcache, m, key, strlen(key), flags); if (ptr == NULL) { int xerrno = errno; pr_trace_msg(trace_channel, 2, "error getting data for key '%s': %s", key, strerror(xerrno)); errno = xerrno; return NULL; } return ptr; } int pr_memcache_incr(pr_memcache_t *mcache, module *m, const char *key, uint32_t incr, uint64_t *value) { int res; /* XXX Should we allow null values to be added, thus allowing use of keys * as sentinels? */ if (mcache == NULL || m == NULL || key == NULL || incr == 0) { errno = EINVAL; return -1; } res = pr_memcache_kincr(mcache, m, key, strlen(key), incr, value); if (res < 0) { int xerrno = errno; pr_trace_msg(trace_channel, 2, "error incrementing key '%s' by %lu: %s", key, (unsigned long) incr, strerror(xerrno)); errno = xerrno; return -1; } return 0; } int pr_memcache_remove(pr_memcache_t *mcache, module *m, const char *key, time_t expires) { int res; if (mcache == NULL || m == NULL || key == NULL) { errno = EINVAL; return -1; } res = pr_memcache_kremove(mcache, m, key, strlen(key), expires); if (res < 0) { int xerrno = errno; pr_trace_msg(trace_channel, 2, "error removing key '%s': %s", key, strerror(xerrno)); errno = xerrno; return -1; } return 0; } int pr_memcache_set(pr_memcache_t *mcache, module *m, const char *key, void *value, size_t valuesz, time_t expires, uint32_t flags) { int res; /* XXX Should we allow null values to be added, thus allowing use of keys * as sentinels? */ if (mcache == NULL || m == NULL || key == NULL || value == NULL) { errno = EINVAL; return -1; } res = pr_memcache_kset(mcache, m, key, strlen(key), value, valuesz, expires, flags); if (res < 0) { int xerrno = errno; pr_trace_msg(trace_channel, 2, "error setting key '%s', value (%lu bytes): %s", key, (unsigned long) valuesz, strerror(xerrno)); errno = xerrno; return -1; } return 0; } static void mcache_set_module_namespace(pr_memcache_t *mcache, module *m) { memcached_return res = MEMCACHED_SUCCESS; if (m == NULL) { res = memcached_callback_set(mcache->mc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL); } else { if (mcache->namespace_tab != NULL) { void *v; v = pr_table_kget(mcache->namespace_tab, m, sizeof(module *), NULL); if (v) { pr_trace_msg(trace_channel, 25, "using namespace prefix '%s' for module 'mod_%s.c'", (const char *) v, m->name); res = memcached_callback_set(mcache->mc, MEMCACHED_CALLBACK_PREFIX_KEY, v); } } else { res = MEMCACHED_SUCCESS; } } if (res != MEMCACHED_SUCCESS) { pr_trace_msg(trace_channel, 9, "unable to set MEMCACHED_CALLBACK_PREFIX_KEY for module 'mod_%s.c': %s", m->name, memcached_strerror(mcache->mc, res)); } } int pr_memcache_kadd(pr_memcache_t *mcache, module *m, const char *key, size_t keysz, void *value, size_t valuesz, time_t expires, uint32_t flags) { memcached_return res; /* XXX Should we allow null values to be added, thus allowing use of keys * as sentinels? */ if (mcache == NULL || m == NULL || key == NULL || value == NULL) { errno = EINVAL; return -1; } mcache_set_module_namespace(mcache, m); res = memcached_add(mcache->mc, key, keysz, value, valuesz, expires, flags); mcache_set_module_namespace(mcache, NULL); switch (res) { case MEMCACHED_SUCCESS: return 0; case MEMCACHED_ERRNO: if (errno != EINPROGRESS) { int xerrno = errno; pr_trace_msg(trace_channel, 3, "error adding key (%lu bytes), value (%lu bytes): system error: %s", (unsigned long) keysz, (unsigned long) valuesz, strerror(xerrno)); errno = xerrno; break; } else { /* We know that we're not using nonblocking IO; this value usually * means that libmemcached could not connect to the configured * memcached servers. So set the value to something more * indicative, and fall through. */ res = MEMCACHED_CONNECTION_FAILURE; } case MEMCACHED_SERVER_MARKED_DEAD: case MEMCACHED_CONNECTION_FAILURE: { memcached_server_instance_st server; server = memcached_server_get_last_disconnect(mcache->mc); if (server != NULL) { pr_trace_msg(trace_channel, 3, "unable to connect to %s:%d", memcached_server_name(server), memcached_server_port(server)); } } default: pr_trace_msg(trace_channel, 2, "error adding key (%lu bytes), value (%lu bytes): %s", (unsigned long) keysz, (unsigned long) valuesz, memcached_strerror(mcache->mc, res)); errno = EPERM; } return -1; } int pr_memcache_kdecr(pr_memcache_t *mcache, module *m, const char *key, size_t keysz, uint32_t decr, uint64_t *value) { memcached_return res; if (mcache == NULL || m == NULL || key == NULL || decr == 0) { errno = EINVAL; return -1; } mcache_set_module_namespace(mcache, m); res = memcached_decrement(mcache->mc, key, keysz, decr, value); mcache_set_module_namespace(mcache, NULL); switch (res) { case MEMCACHED_SUCCESS: return 0; case MEMCACHED_ERRNO: if (errno != EINPROGRESS) { int xerrno = errno; pr_trace_msg(trace_channel, 3, "error decrementing key (%lu bytes) by %lu: system error: %s", (unsigned long) keysz, (unsigned long) decr, strerror(xerrno)); errno = xerrno; break; } else { /* We know that we're not using nonblocking IO; this value usually * means that libmemcached could not connect to the configured * memcached servers. So set the value to something more * indicative, and fall through. */ res = MEMCACHED_CONNECTION_FAILURE; } case MEMCACHED_SERVER_MARKED_DEAD: case MEMCACHED_CONNECTION_FAILURE: { memcached_server_instance_st server; server = memcached_server_get_last_disconnect(mcache->mc); if (server != NULL) { pr_trace_msg(trace_channel, 3, "unable to connect to %s:%d", memcached_server_name(server), memcached_server_port(server)); } } default: pr_trace_msg(trace_channel, 2, "error decrementing key (%lu bytes) by %lu: %s", (unsigned long) keysz, (unsigned long) decr, memcached_strerror(mcache->mc, res)); errno = EPERM; } return -1; } void *pr_memcache_kget(pr_memcache_t *mcache, module *m, const char *key, size_t keysz, size_t *valuesz, uint32_t *flags) { char *data = NULL; void *ptr = NULL; memcached_return res; if (mcache == NULL || m == NULL || key == NULL || valuesz == NULL || flags == NULL) { errno = EINVAL; return NULL; } mcache_set_module_namespace(mcache, m); data = memcached_get(mcache->mc, key, keysz, valuesz, flags, &res); mcache_set_module_namespace(mcache, NULL); if (data == NULL) { switch (res) { case MEMCACHED_NOTFOUND: pr_trace_msg(trace_channel, 8, "no data found for key (%lu bytes)", (unsigned long) keysz); errno = ENOENT; break; case MEMCACHED_ERRNO: if (errno != EINPROGRESS) { int xerrno = errno; pr_trace_msg(trace_channel, 3, "no data found for key (%lu bytes): system error: %s", (unsigned long) keysz, strerror(xerrno)); errno = xerrno; break; } else { /* We know that we're not using nonblocking IO; this value usually * means that libmemcached could not connect to the configured * memcached servers. So set the value to something more * indicative, and fall through. */ res = MEMCACHED_CONNECTION_FAILURE; } case MEMCACHED_SERVER_MARKED_DEAD: case MEMCACHED_CONNECTION_FAILURE: { memcached_server_instance_st server; server = memcached_server_get_last_disconnect(mcache->mc); if (server != NULL) { pr_trace_msg(trace_channel, 3, "unable to connect to %s:%d", memcached_server_name(server), memcached_server_port(server)); } } default: pr_trace_msg(trace_channel, 6, "error getting data for key (%lu bytes): [%d] %s", (unsigned long) keysz, res, memcached_strerror(mcache->mc, res)); errno = EPERM; break; } return NULL; } /* Create a duplicate of the returned data from the mcache's pool, so that * we can call free(3) on the data returned by libmemcached. */ ptr = palloc(mcache->pool, *valuesz); memcpy(ptr, data, *valuesz); free(data); return ptr; } char *pr_memcache_kget_str(pr_memcache_t *mcache, module *m, const char *key, size_t keysz, uint32_t *flags) { char *data = NULL, *ptr = NULL; size_t valuesz = 0; memcached_return res; if (mcache == NULL || m == NULL || key == NULL || flags == NULL) { errno = EINVAL; return NULL; } mcache_set_module_namespace(mcache, m); data = memcached_get(mcache->mc, key, keysz, &valuesz, flags, &res); mcache_set_module_namespace(mcache, NULL); if (data == NULL) { switch (res) { case MEMCACHED_NOTFOUND: pr_trace_msg(trace_channel, 8, "no data found for key (%lu bytes)", (unsigned long) keysz); errno = ENOENT; break; case MEMCACHED_ERRNO: if (errno != EINPROGRESS) { int xerrno = errno; pr_trace_msg(trace_channel, 3, "no data found for key (%lu bytes): system error: %s", (unsigned long) keysz, strerror(xerrno)); errno = xerrno; break; } else { /* We know that we're not using nonblocking IO; this value usually * means that libmemcached could not connect to the configured * memcached servers. So set the value to something more * indicative, and fall through. */ res = MEMCACHED_CONNECTION_FAILURE; } case MEMCACHED_SERVER_MARKED_DEAD: case MEMCACHED_CONNECTION_FAILURE: { memcached_server_instance_st server; server = memcached_server_get_last_disconnect(mcache->mc); if (server != NULL) { pr_trace_msg(trace_channel, 3, "unable to connect to %s:%d", memcached_server_name(server), memcached_server_port(server)); } } default: pr_trace_msg(trace_channel, 6, "error getting data for key (%lu bytes): [%d] %s", (unsigned long) keysz, res, memcached_strerror(mcache->mc, res)); errno = EPERM; break; } return NULL; } /* Create a duplicate of the returned data from the mcache's pool, so that * we can call free(3) on the data returned by libmemcached. */ ptr = pcalloc(mcache->pool, valuesz + 1); memcpy(ptr, data, valuesz); free(data); return ptr; } int pr_memcache_kincr(pr_memcache_t *mcache, module *m, const char *key, size_t keysz, uint32_t incr, uint64_t *value) { memcached_return res; if (mcache == NULL || m == NULL || key == NULL || incr == 0) { errno = EINVAL; return -1; } mcache_set_module_namespace(mcache, m); res = memcached_increment(mcache->mc, key, keysz, incr, value); mcache_set_module_namespace(mcache, NULL); if (res == MEMCACHED_NOTFOUND) { /* Automatically create a value for this key, with the given increment. */ pr_trace_msg(trace_channel, 18, "unable to increment nonexistent key (%lu bytes), automatically " "creating one", (unsigned long) keysz); return pr_memcache_kset(mcache, m, key, keysz, &incr, sizeof(uint32_t), 0, 0); } switch (res) { case MEMCACHED_SUCCESS: return 0; case MEMCACHED_ERRNO: if (errno != EINPROGRESS) { int xerrno = errno; pr_trace_msg(trace_channel, 3, "error incrementing key (%lu bytes) by %lu: system error: %s", (unsigned long) keysz, (unsigned long) incr, strerror(xerrno)); errno = xerrno; break; } else { /* We know that we're not using nonblocking IO; this value usually * means that libmemcached could not connect to the configured * memcached servers. So set the value to something more * indicative, and fall through. */ res = MEMCACHED_CONNECTION_FAILURE; } case MEMCACHED_SERVER_MARKED_DEAD: case MEMCACHED_CONNECTION_FAILURE: { memcached_server_instance_st server; server = memcached_server_get_last_disconnect(mcache->mc); if (server != NULL) { pr_trace_msg(trace_channel, 3, "unable to connect to %s:%d", memcached_server_name(server), memcached_server_port(server)); } } default: pr_trace_msg(trace_channel, 2, "error incrementing key (%lu bytes) by %lu: %s", (unsigned long) keysz, (unsigned long) incr, memcached_strerror(mcache->mc, res)); errno = EPERM; } return -1; } int pr_memcache_kremove(pr_memcache_t *mcache, module *m, const char *key, size_t keysz, time_t expires) { memcached_return res; if (mcache == NULL || m == NULL || key == NULL) { errno = EINVAL; return -1; } mcache_set_module_namespace(mcache, m); res = memcached_delete(mcache->mc, key, keysz, expires); mcache_set_module_namespace(mcache, NULL); switch (res) { case MEMCACHED_SUCCESS: return 0; case MEMCACHED_ERRNO: if (errno != EINPROGRESS) { int xerrno = errno; pr_trace_msg(trace_channel, 3, "error removing key (%lu bytes): system error: %s", (unsigned long) keysz, strerror(xerrno)); errno = xerrno; break; } else { /* We know that we're not using nonblocking IO; this value usually * means that libmemcached could not connect to the configured * memcached servers. So set the value to something more * indicative, and fall through. */ res = MEMCACHED_CONNECTION_FAILURE; } case MEMCACHED_SERVER_MARKED_DEAD: case MEMCACHED_CONNECTION_FAILURE: { memcached_server_instance_st server; server = memcached_server_get_last_disconnect(mcache->mc); if (server != NULL) { pr_trace_msg(trace_channel, 3, "unable to connect to %s:%d", memcached_server_name(server), memcached_server_port(server)); } } default: pr_trace_msg(trace_channel, 2, "error removing key (%lu bytes): %s", (unsigned long) keysz, memcached_strerror(mcache->mc, res)); errno = EPERM; } return -1; } int pr_memcache_kset(pr_memcache_t *mcache, module *m, const char *key, size_t keysz, void *value, size_t valuesz, time_t expires, uint32_t flags) { memcached_return res; /* XXX Should we allow null values to be added, thus allowing use of keys * as sentinels? */ if (mcache == NULL || m == NULL || key == NULL || value == NULL) { errno = EINVAL; return -1; } mcache_set_module_namespace(mcache, m); res = memcached_set(mcache->mc, key, keysz, value, valuesz, expires, flags); mcache_set_module_namespace(mcache, NULL); switch (res) { case MEMCACHED_SUCCESS: return 0; case MEMCACHED_ERRNO: if (errno != EINPROGRESS) { int xerrno = errno; pr_trace_msg(trace_channel, 3, "error setting key (%lu bytes), value (%lu bytes): system error: %s", (unsigned long) keysz, (unsigned long) valuesz, strerror(xerrno)); errno = xerrno; break; } else { /* We know that we're not using nonblocking IO; this value usually * means that libmemcached could not connect to the configured * memcached servers. So set the value to something more * indicative, and fall through. */ res = MEMCACHED_CONNECTION_FAILURE; } case MEMCACHED_SERVER_MARKED_DEAD: case MEMCACHED_CONNECTION_FAILURE: { memcached_server_instance_st server; server = memcached_server_get_last_disconnect(mcache->mc); if (server != NULL) { pr_trace_msg(trace_channel, 3, "unable to connect to %s:%d", memcached_server_name(server), memcached_server_port(server)); } } default: pr_trace_msg(trace_channel, 2, "error setting key (%lu bytes), value (%lu bytes): %s", (unsigned long) keysz, (unsigned long) valuesz, memcached_strerror(mcache->mc, res)); errno = EPERM; } return -1; } unsigned long memcache_get_sess_flags(void) { return memcache_sess_flags; } int memcache_set_sess_connect_failures(uint64_t count) { memcache_sess_conn_failures = count; return 0; } int memcache_set_sess_flags(unsigned long flags) { memcache_sess_flags = flags; return 0; } int memcache_set_sess_replicas(uint64_t count) { if (count < 1) { errno = EINVAL; return -1; } memcache_sess_nreplicas = count; return 0; } int memcache_set_servers(void *server_list) { if (server_list == NULL) { errno = EINVAL; return -1; } configured_server_list = server_list; return 0; } int memcache_set_timeouts(unsigned long conn_millis, unsigned long read_millis, unsigned long write_millis, unsigned long ejected_sec) { memcache_conn_millis = conn_millis; memcache_rcv_millis = read_millis; memcache_snd_millis = write_millis; memcache_ejected_sec = ejected_sec; return 0; } static int memcache_tpl_oops(const char *fmt, ...) { va_list ap; va_start(ap, fmt); pr_trace_vmsg(trace_channel, 1, fmt, ap); va_end(ap); /* XXX Does tpl check the return value of its oops() hook? */ return 0; } static void memcache_tpl_fatal(char *fmt, ...) { va_list ap; va_start(ap, fmt); pr_trace_vmsg(trace_channel, 1, fmt, ap); va_end(ap); _exit(1); } int memcache_clear(void) { if (sess_mcache != NULL) { pr_memcache_conn_close(sess_mcache); sess_mcache = NULL; } return 0; } int memcache_init(void) { /* Set the tpl callbacks */ tpl_hook.oops = memcache_tpl_oops; tpl_hook.fatal = memcache_tpl_fatal; return 0; } #else pr_memcache_t *pr_memcache_conn_get(void) { errno = ENOSYS; return NULL; } pr_memcache_t *pr_memcache_conn_new(pool *p, module *m, unsigned long flags, uint64_t nreplicas) { errno = ENOSYS; return NULL; } int pr_memcache_conn_close(pr_memcache_t *mcache) { errno = ENOSYS; return -1; } int pr_memcache_conn_set_namespace(pr_memcache_t *mcache, module *m, const char *prefix) { errno = ENOSYS; return -1; } int pr_memcache_add(pr_memcache_t *mcache, module *m, const char *key, void *value, size_t valuesz, time_t expires, uint32_t flags) { errno = ENOSYS; return -1; } int pr_memcache_decr(pr_memcache_t *mcache, module *m, const char *key, uint32_t decr, uint64_t *value) { errno = ENOSYS; return -1; } void *pr_memcache_get(pr_memcache_t *mcache, module *m, const char *key, size_t *valuesz, uint32_t *flags) { errno = ENOSYS; return NULL; } char *pr_memcache_get_str(pr_memcache_t *mcache, module *m, const char *key, uint32_t *flags) { errno = ENOSYS; return NULL; } int pr_memcache_incr(pr_memcache_t *mcache, module *m, const char *key, uint32_t incr, uint64_t *value) { errno = ENOSYS; return -1; } int pr_memcache_remove(pr_memcache_t *mcache, module *m, const char *key, time_t expires) { errno = ENOSYS; return -1; } int pr_memcache_set(pr_memcache_t *mcache, module *m, const char *key, void *value, size_t valuesz, time_t expires, uint32_t flags) { errno = ENOSYS; return -1; } int pr_memcache_kadd(pr_memcache_t *mcache, module *m, const char *key, size_t keysz, void *value, size_t valuesz, time_t expires, uint32_t flags) { errno = ENOSYS; return -1; } void *pr_memcache_kget(pr_memcache_t *mcache, module *m, const char *key, size_t keysz, size_t *valuesz, uint32_t *flags) { errno = ENOSYS; return NULL; } char *pr_memcache_kget_str(pr_memcache_t *mcache, module *m, const char *key, size_t keysz, uint32_t *flags) { errno = ENOSYS; return NULL; } int pr_memcache_kremove(pr_memcache_t *mcache, module *m, const char *key, size_t keysz, time_t expires) { errno = ENOSYS; return -1; } int pr_memcache_kset(pr_memcache_t *mcache, module *m, const char *key, size_t keysz, void *value, size_t valuesz, time_t expires, uint32_t flags) { errno = ENOSYS; return -1; } unsigned long memcache_get_sess_flags(void) { return 0; } int memcache_set_sess_connect_failures(uint64_t count) { errno = ENOSYS; return -1; } int memcache_set_sess_flags(unsigned long flags) { errno = ENOSYS; return -1; } int memcache_set_sess_replicas(uint64_t count) { errno = ENOSYS; return -1; } int memcache_set_servers(void *server_list) { errno = ENOSYS; return -1; } int memcache_set_timeouts(unsigned long conn_millis, unsigned long read_millis, unsigned long write_millis, unsigned long ejected_sec) { errno = ENOSYS; return -1; } int memcache_clear(void) { errno = ENOSYS; return -1; } int memcache_init(void) { errno = ENOSYS; return -1; } #endif /* PR_USE_MEMCACHE */ proftpd-dfsg-1.3.5~rc3/src/ctrls.c0000644000175000017500000014255312151215512016634 0ustar frankiefrankie/* * ProFTPD - FTP server daemon * Copyright (c) 2001-2013 The ProFTPD Project team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * As a special exemption, The ProFTPD Project team and other respective * copyright holders give permission to link this program with OpenSSL, and * distribute the resulting executable, without including the source code for * OpenSSL in the source distribution. */ /* Controls API routines * $Id: ctrls.c,v 1.40 2013/05/28 21:02:02 castaglia Exp $ */ #include "conf.h" #include "privs.h" #ifdef HAVE_UCRED_H # include #endif /* !HAVE_UCRED_H */ #ifdef HAVE_SYS_UCRED_H # include #endif /* !HAVE_SYS_UCRED_H */ #ifdef HAVE_SYS_UIO_H # include #endif /* !HAVE_SYS_UIO_H */ #ifdef PR_USE_CTRLS #include "mod_ctrls.h" /* Maximum length of a single request argument. */ #define CTRLS_MAX_REQARGLEN 256 typedef struct ctrls_act_obj { struct ctrls_act_obj *prev, *next; pool *pool; unsigned int id; const char *action; const char *desc; const module *module; volatile unsigned int flags; int (*action_cb)(pr_ctrls_t *, int, char **); } ctrls_action_t; static unsigned char ctrls_blocked = FALSE; static pool *ctrls_pool = NULL; static ctrls_action_t *ctrls_action_list = NULL; static pr_ctrls_t *ctrls_active_list = NULL; static pr_ctrls_t *ctrls_free_list = NULL; static int ctrls_use_isfifo = FALSE; static const char *trace_channel = "ctrls"; /* lookup/lookup_next indices */ static ctrls_action_t *action_lookup_next = NULL; static const char *action_lookup_action = NULL; static module *action_lookup_module = NULL; /* Logging */ static int ctrls_logfd = -1; /* necessary prototypes */ static ctrls_action_t *ctrls_action_new(void); static pr_ctrls_t *ctrls_new(void); static pr_ctrls_t *ctrls_lookup_action(module *, const char *, unsigned char); static pr_ctrls_t *ctrls_lookup_next_action(module *, unsigned char); static pr_ctrls_t *ctrls_prepare(ctrls_action_t *act) { pr_ctrls_t *ctrl = NULL; /* Sanity check */ if (!act) return NULL; pr_block_ctrls(); /* Get a blank ctrl object */ ctrl = ctrls_new(); /* Fill in the fields from the action object. */ ctrl->ctrls_id = act->id; ctrl->ctrls_module = act->module; ctrl->ctrls_action = act->action; ctrl->ctrls_desc = act->desc; ctrl->ctrls_cb = act->action_cb; ctrl->ctrls_flags = act->flags; /* Add this to the "in use" list */ ctrl->ctrls_next = ctrls_active_list; ctrls_active_list = ctrl; pr_unblock_ctrls(); return ctrl; } static void ctrls_free(pr_ctrls_t *ctrl) { /* Make sure that ctrls are blocked while we're doing this */ pr_block_ctrls(); /* Remove this object from the active list */ if (ctrl->ctrls_prev) ctrl->ctrls_prev->ctrls_next = ctrl->ctrls_next; else ctrls_active_list = ctrl->ctrls_next; if (ctrl->ctrls_next) ctrl->ctrls_next->ctrls_prev = ctrl->ctrls_prev; /* Clear its fields, and add it to the free list */ ctrl->ctrls_next = NULL; ctrl->ctrls_prev = NULL; ctrl->ctrls_id = 0; ctrl->ctrls_module = NULL; ctrl->ctrls_action = NULL; ctrl->ctrls_cb = NULL; ctrl->ctrls_cb_retval = 1; ctrl->ctrls_flags = 0; if (ctrl->ctrls_tmp_pool) { destroy_pool(ctrl->ctrls_tmp_pool); ctrl->ctrls_tmp_pool = NULL; } ctrl->ctrls_cb_args = NULL; ctrl->ctrls_cb_resps = NULL; ctrl->ctrls_data = NULL; ctrl->ctrls_next = ctrls_free_list; ctrls_free_list = ctrl; pr_unblock_ctrls(); return; } static ctrls_action_t *ctrls_action_new(void) { ctrls_action_t *act = NULL; pool *sub_pool = make_sub_pool(ctrls_pool); pr_pool_tag(sub_pool, "ctrls action subpool"); act = pcalloc(sub_pool, sizeof(ctrls_action_t)); act->pool = sub_pool; return act; } static pr_ctrls_t *ctrls_new(void) { pr_ctrls_t *ctrl = NULL; /* Check for a free ctrl first */ if (ctrls_free_list) { /* Take one from the top */ ctrl = ctrls_free_list; ctrls_free_list = ctrls_free_list->ctrls_next; if (ctrls_free_list) ctrls_free_list->ctrls_prev = NULL; } else { /* Have to allocate a new one. */ ctrl = (pr_ctrls_t *) pcalloc(ctrls_pool, sizeof(pr_ctrls_t)); /* It's important that a new ctrl object have the retval initialized * to 1; this tells the Controls layer that it is "pending", not yet * handled. */ ctrl->ctrls_cb_retval = 1; } return ctrl; } static char *ctrls_sep(char **str) { char *ret = NULL, *dst = NULL; unsigned char quoted = FALSE; /* Sanity checks */ if (!str || !*str || !**str) return NULL; while (**str && PR_ISSPACE(**str)) { (*str)++; } if (!**str) return NULL; ret = dst = *str; if (**str == '\"') { quoted = TRUE; (*str)++; } while (**str && (quoted ? (**str != '\"') : !PR_ISSPACE(**str))) { if (**str == '\\' && quoted) { /* Escaped char */ if (*((*str) + 1)) *dst = *(++(*str)); } *dst++ = **str; ++(*str); } if (**str) (*str)++; *dst = '\0'; return ret; } int pr_ctrls_register(const module *mod, const char *action, const char *desc, int (*cb)(pr_ctrls_t *, int, char **)) { ctrls_action_t *act = NULL, *acti = NULL; int act_id = -1; /* sanity checks */ if (!action || !desc || !cb) { errno = EINVAL; return -1; } pr_trace_msg("ctrls", 3, "module '%s' registering handler for ctrl action '%s' (at %p)", mod ? mod->name : "(none)", action, cb); /* Block ctrls while we're doing this */ pr_block_ctrls(); /* Get a ctrl action object */ act = ctrls_action_new(); /* Randomly generate a unique random ID for this object */ while (TRUE) { unsigned char have_id = FALSE; act_id = rand(); /* Check the list for this ID */ for (acti = ctrls_action_list; acti; acti = acti->next) { if (acti->id == act_id) { have_id = TRUE; break; } } if (!have_id) break; } act->next = NULL; act->id = act_id; act->action = pstrdup(ctrls_pool, action); act->desc = desc; act->module = mod; act->action_cb = cb; /* Add this to the list of "registered" actions */ if (ctrls_action_list) { act->next = ctrls_action_list; ctrls_action_list->prev = act; } ctrls_action_list = act; pr_unblock_ctrls(); return act_id; } int pr_ctrls_unregister(module *mod, const char *action) { ctrls_action_t *act = NULL; unsigned char have_action = FALSE; /* Make sure that ctrls are blocked while we're doing this */ pr_block_ctrls(); for (act = ctrls_action_list; act; act = act->next) { if ((action == NULL || strcmp(act->action, action) == 0) && (act->module == mod || mod == ANY_MODULE || mod == NULL)) { have_action = TRUE; /* Remove this object from the list of registered actions */ if (act->prev) { act->prev->next = act->next; } else { ctrls_action_list = act->next; } if (act->next) { act->next->prev = act->prev; } pr_trace_msg("ctrls", 3, "module '%s' unregistering handler for ctrl action '%s'", mod ? mod->name : "(none)", act->action); /* Destroy this action. */ destroy_pool(act->pool); } } pr_unblock_ctrls(); if (!have_action) { errno = ENOENT; return -1; } return 0; } int pr_ctrls_add_arg(pr_ctrls_t *ctrl, char *ctrls_arg, size_t ctrls_arglen) { register unsigned int i; /* Sanity checks */ if (ctrl == NULL || ctrls_arg == NULL) { errno = EINVAL; return -1; } /* Scan for non-printable characters. */ for (i = 0; i < ctrls_arglen; i++) { if (!isprint((int) ctrls_arg[i])) { errno = EPERM; return -1; } } /* Make sure the pr_ctrls_t has a temporary pool, from which the args will * be allocated. */ if (!ctrl->ctrls_tmp_pool) { ctrl->ctrls_tmp_pool = make_sub_pool(ctrls_pool); pr_pool_tag(ctrl->ctrls_tmp_pool, "ctrls tmp pool"); } if (!ctrl->ctrls_cb_args) { ctrl->ctrls_cb_args = make_array(ctrl->ctrls_tmp_pool, 0, sizeof(char *)); } /* Add the given argument */ *((char **) push_array(ctrl->ctrls_cb_args)) = pstrdup(ctrl->ctrls_tmp_pool, ctrls_arg); return 0; } int pr_ctrls_copy_args(pr_ctrls_t *src_ctrl, pr_ctrls_t *dst_ctrl) { /* Sanity checks */ if (!src_ctrl || !dst_ctrl) { errno = EINVAL; return -1; } /* If source ctrl has no ctrls_cb_args member, there's nothing to be * done. */ if (!src_ctrl->ctrls_cb_args) return 0; /* Make sure the pr_ctrls_t has a temporary pool, from which the args will * be allocated. */ if (!dst_ctrl->ctrls_tmp_pool) { dst_ctrl->ctrls_tmp_pool = make_sub_pool(ctrls_pool); pr_pool_tag(dst_ctrl->ctrls_tmp_pool, "ctrls tmp pool"); } /* Overwrite any existing dst_ctrl->ctrls_cb_args. This is OK, as * the ctrl will be reset (cleared) once it has been processed. */ dst_ctrl->ctrls_cb_args = copy_array(dst_ctrl->ctrls_tmp_pool, src_ctrl->ctrls_cb_args); return 0; } int pr_ctrls_copy_resps(pr_ctrls_t *src_ctrl, pr_ctrls_t *dst_ctrl) { /* sanity checks */ if (!src_ctrl || !dst_ctrl) { errno = EINVAL; return -1; } /* The source ctrl must have a ctrls_cb_resps member, and the destination * ctrl must not have a ctrls_cb_resps member. */ if (!src_ctrl->ctrls_cb_resps || dst_ctrl->ctrls_cb_resps) { errno = EINVAL; return -1; } dst_ctrl->ctrls_cb_resps = copy_array(dst_ctrl->ctrls_tmp_pool, src_ctrl->ctrls_cb_resps); return 0; } int pr_ctrls_add_response(pr_ctrls_t *ctrl, char *fmt, ...) { char buf[PR_TUNABLE_BUFFER_SIZE] = {'\0'}; va_list resp; /* Sanity check */ if (!ctrl || !fmt) { errno = EINVAL; return -1; } /* Make sure the pr_ctrls_t has a temporary pool, from which the responses * will be allocated */ if (!ctrl->ctrls_tmp_pool) { ctrl->ctrls_tmp_pool = make_sub_pool(ctrls_pool); pr_pool_tag(ctrl->ctrls_tmp_pool, "ctrls tmp pool"); } if (!ctrl->ctrls_cb_resps) ctrl->ctrls_cb_resps = make_array(ctrl->ctrls_tmp_pool, 0, sizeof(char *)); /* Affix the message */ va_start(resp, fmt); vsnprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), fmt, resp); va_end(resp); buf[sizeof(buf) - 1] = '\0'; /* add the given response */ *((char **) push_array(ctrl->ctrls_cb_resps)) = pstrdup(ctrl->ctrls_tmp_pool, buf); return 0; } int pr_ctrls_flush_response(pr_ctrls_t *ctrl) { /* Sanity check */ if (!ctrl) { errno = EINVAL; return -1; } /* Make sure the callback(s) added responses */ if (ctrl->ctrls_cb_resps) { if (pr_ctrls_send_msg(ctrl->ctrls_cl->cl_fd, ctrl->ctrls_cb_retval, ctrl->ctrls_cb_resps->nelts, (char **) ctrl->ctrls_cb_resps->elts) < 0) return -1; } return 0; } int pr_ctrls_parse_msg(pool *msg_pool, char *msg, unsigned int *msgargc, char ***msgargv) { char *tmp = msg, *str = NULL; pool *tmp_pool = NULL; array_header *msgs = NULL; /* Sanity checks */ if (!msg_pool || !msgargc || !msgargv) { errno = EINVAL; return -1; } tmp_pool = make_sub_pool(msg_pool); /* Allocate an array_header, and push each space-delimited string * (respecting quotes and escapes) into the array. Once done, * destroy the array. */ msgs = make_array(tmp_pool, 0, sizeof(char *)); while ((str = ctrls_sep(&tmp)) != NULL) *((char **) push_array(msgs)) = pstrdup(msg_pool, str); *msgargc = msgs->nelts; *msgargv = (char **) msgs->elts; destroy_pool(tmp_pool); return 0; } int pr_ctrls_recv_request(pr_ctrls_cl_t *cl) { pr_ctrls_t *ctrl = NULL, *next_ctrl = NULL; char reqaction[128] = {'\0'}, *reqarg = NULL; size_t reqargsz = 0; unsigned int nreqargs = 0, reqarglen = 0; int status = 0; register int i = 0; if (!cl) { errno = EINVAL; return -1; } if (cl->cl_fd < 0) { errno = EBADF; return -1; } /* No interruptions */ pr_signals_block(); /* Read in the incoming number of args, including the action. */ /* First, read the status (but ignore it). This is necessary because * the same function, pr_ctrls_send_msg(), is used to send requests * as well as responses, and the status is a necessary part of a response. */ if (read(cl->cl_fd, &status, sizeof(int)) < 0) { int xerrno = errno; pr_signals_unblock(); errno = xerrno; return -1; } /* Read in the args, length first, then string. */ if (read(cl->cl_fd, &nreqargs, sizeof(unsigned int)) < 0) { int xerrno = errno; pr_signals_unblock(); errno = xerrno; return -1; } /* Next, read in the requested number of arguments. The client sends * the arguments in pairs: first the length of the argument, then the * argument itself. The first argument is the action, so get the first * matching pr_ctrls_t (if present), and add the remaining arguments to it. */ if (read(cl->cl_fd, &reqarglen, sizeof(unsigned int)) < 0) { int xerrno = errno; pr_signals_unblock(); errno = xerrno; return -1; } if (reqarglen >= sizeof(reqaction)) { pr_signals_unblock(); errno = ENOMEM; return -1; } memset(reqaction, '\0', sizeof(reqaction)); if (read(cl->cl_fd, reqaction, reqarglen) < 0) { int xerrno = errno; pr_signals_unblock(); errno = xerrno; return -1; } reqaction[sizeof(reqaction)-1] = '\0'; nreqargs--; /* Find a matching action object, and use it to populate a ctrl object, * preparing the ctrl object for dispatching to the action handlers. */ ctrl = ctrls_lookup_action(NULL, reqaction, TRUE); if (ctrl == NULL) { pr_signals_unblock(); errno = EINVAL; return -1; } for (i = 0; i < nreqargs; i++) { memset(reqarg, '\0', reqargsz); if (read(cl->cl_fd, &reqarglen, sizeof(unsigned int)) < 0) { int xerrno = errno; pr_signals_unblock(); errno = xerrno; return -1; } if (reqarglen == 0) { /* Skip any zero-length arguments. */ continue; } if (reqarglen > CTRLS_MAX_REQARGLEN) { pr_signals_unblock(); errno = ENOMEM; return -1; } /* Make sure reqarg is large enough to handle the given argument. If * it is too small, allocate one of the necessary size. */ if (reqargsz < reqarglen) { reqargsz = reqarglen + 1; if (!ctrl->ctrls_tmp_pool) { ctrl->ctrls_tmp_pool = make_sub_pool(ctrls_pool); pr_pool_tag(ctrl->ctrls_tmp_pool, "ctrls tmp pool"); } reqarg = pcalloc(ctrl->ctrls_tmp_pool, reqargsz); } if (read(cl->cl_fd, reqarg, reqarglen) < 0) { int xerrno = errno; pr_signals_unblock(); errno = xerrno; return -1; } if (pr_ctrls_add_arg(ctrl, reqarg, reqarglen)) { int xerrno = errno; pr_signals_unblock(); errno = xerrno; return -1; } } /* Add this ctrls object to the client object. */ *((pr_ctrls_t **) push_array(cl->cl_ctrls)) = ctrl; /* Set the flag that this control is ready to go */ ctrl->ctrls_flags |= PR_CTRLS_REQUESTED; ctrl->ctrls_cl = cl; /* Copy the populated ctrl object args to ctrl objects for all other * matching action objects. */ next_ctrl = ctrls_lookup_next_action(NULL, TRUE); while (next_ctrl) { if (pr_ctrls_copy_args(ctrl, next_ctrl)) { return -1; } /* Add this ctrl object to the client object. */ *((pr_ctrls_t **) push_array(cl->cl_ctrls)) = next_ctrl; /* Set the flag that this control is ready to go. */ next_ctrl->ctrls_flags |= PR_CTRLS_REQUESTED; next_ctrl->ctrls_cl = cl; next_ctrl = ctrls_lookup_next_action(NULL, TRUE); } pr_signals_unblock(); return 0; } int pr_ctrls_recv_response(pool *resp_pool, int ctrls_sockfd, int *status, char ***respargv) { register int i = 0; array_header *resparr = NULL; unsigned int respargc = 0, resparglen = 0; char response[PR_TUNABLE_BUFFER_SIZE] = {'\0'}; /* Sanity checks */ if (!resp_pool || ctrls_sockfd < 0 || !status) { errno = EINVAL; return -1; } resparr = make_array(resp_pool, 0, sizeof(char *)); /* No interruptions. */ pr_signals_block(); /* First, read the status, which is the return value of the control handler. */ if (read(ctrls_sockfd, status, sizeof(int)) != sizeof(int)) { pr_signals_unblock(); return -1; } /* Next, read the number of responses to be received */ if (read(ctrls_sockfd, &respargc, sizeof(unsigned int)) != sizeof(unsigned int)) { pr_signals_unblock(); return -1; } /* Read each response, and add it to the array */ for (i = 0; i < respargc; i++) { int bread = 0, blen = 0; if (read(ctrls_sockfd, &resparglen, sizeof(unsigned int)) != sizeof(unsigned int)) { pr_signals_unblock(); return -1; } /* Make sure resparglen is not too big */ if (resparglen >= sizeof(response)) { pr_signals_unblock(); errno = ENOMEM; return -1; } memset(response, '\0', sizeof(response)); bread = read(ctrls_sockfd, response, resparglen); while (bread != resparglen) { if (bread < 0) { pr_signals_unblock(); return -1; } blen += bread; bread = read(ctrls_sockfd, response + blen, resparglen - blen); } /* Always make sure the buffer is zero-terminated */ response[sizeof(response)-1] = '\0'; *((char **) push_array(resparr)) = pstrdup(resp_pool, response); } if (respargv) { *respargv = ((char **) resparr->elts); } pr_signals_unblock(); return respargc; } int pr_ctrls_send_msg(int sockfd, int msgstatus, unsigned int msgargc, char **msgargv) { register int i = 0; unsigned int msgarglen = 0; /* Sanity checks */ if (sockfd < 0) { errno = EINVAL; return -1; } if (msgargc < 1) { return 0; } if (msgargv == NULL) { return 0; } /* No interruptions */ pr_signals_block(); /* Send the message status first */ if (write(sockfd, &msgstatus, sizeof(int)) != sizeof(int)) { pr_signals_unblock(); return -1; } /* Send the strings, one argument at a time. First, send the number * of arguments to be sent; then send, for each argument, first the * length of the argument string, then the argument itself. */ if (write(sockfd, &msgargc, sizeof(unsigned int)) != sizeof(unsigned int)) { pr_signals_unblock(); return -1; } for (i = 0; i < msgargc; i++) { int res = 0; msgarglen = strlen(msgargv[i]); while (TRUE) { res = write(sockfd, &msgarglen, sizeof(unsigned int)); if (res != sizeof(unsigned int)) { if (errno == EAGAIN) { continue; } pr_signals_unblock(); return -1; } break; } while (TRUE) { res = write(sockfd, msgargv[i], msgarglen); if (res != msgarglen) { if (errno == EAGAIN) { continue; } pr_signals_unblock(); return -1; } break; } } pr_signals_unblock(); return 0; } static pr_ctrls_t *ctrls_lookup_action(module *mod, const char *action, unsigned char skip_disabled) { /* (Re)set the current indices */ action_lookup_next = ctrls_action_list; action_lookup_action = action; action_lookup_module = mod; /* Wrapper around ctrls_lookup_next_action() */ return ctrls_lookup_next_action(mod, skip_disabled); } static pr_ctrls_t *ctrls_lookup_next_action(module *mod, unsigned char skip_disabled) { ctrls_action_t *act = NULL; /* Sanity check */ if (!action_lookup_action) { errno = EINVAL; return NULL; } if (mod != action_lookup_module) return ctrls_lookup_action(mod, action_lookup_action, skip_disabled); for (act = action_lookup_next; act; act = act->next) { if (skip_disabled && (act->flags & PR_CTRLS_ACT_DISABLED)) continue; if (strcmp(act->action, action_lookup_action) == 0 && (act->module == mod || mod == ANY_MODULE || mod == NULL)) { action_lookup_next = act->next; /* Use this action object to prepare a ctrl object. */ return ctrls_prepare(act); } } return NULL; } int pr_get_registered_actions(pr_ctrls_t *ctrl, int flags) { ctrls_action_t *act = NULL; /* Are ctrls blocked? */ if (ctrls_blocked) { errno = EPERM; return -1; } for (act = ctrls_action_list; act; act = act->next) { switch (flags) { case CTRLS_GET_ACTION_ALL: pr_ctrls_add_response(ctrl, "%s (mod_%s.c)", act->action, act->module->name); break; case CTRLS_GET_ACTION_ENABLED: if (act->flags & PR_CTRLS_ACT_DISABLED) break; pr_ctrls_add_response(ctrl, "%s (mod_%s.c)", act->action, act->module->name); break; case CTRLS_GET_DESC: pr_ctrls_add_response(ctrl, "%s: %s", act->action, act->desc); break; } } return 0; } int pr_set_registered_actions(module *mod, const char *action, unsigned char skip_disabled, unsigned int flags) { ctrls_action_t *act = NULL; unsigned char have_action = FALSE; /* Is flags a valid combination of settable flags? */ if (flags && flags != PR_CTRLS_ACT_DISABLED) { errno = EINVAL; return -1; } /* Are ctrls blocked? */ if (ctrls_blocked) { errno = EPERM; return -1; } for (act = ctrls_action_list; act; act = act->next) { if (skip_disabled && (act->flags & PR_CTRLS_ACT_DISABLED)) continue; if ((!action || strncmp(action, "all", 4) == 0 || strcmp(act->action, action) == 0) && (act->module == mod || mod == ANY_MODULE || mod == NULL)) { have_action = TRUE; act->flags = flags; } } if (!have_action) { errno = ENOENT; return -1; } return 0; } #if !defined(SO_PEERCRED) && !defined(HAVE_GETPEEREID) && \ !defined(HAVE_GETPEERUCRED) && defined(LOCAL_CREDS) static int ctrls_connect_local_creds(int sockfd) { char buf[1] = {'\0'}; int res; /* The backend doesn't care what we send here, but it wants * exactly one character to force recvmsg() to block and wait * for us. */ res = write(sockfd, buf, 1); while (res < 0) { if (errno == EINTR) { pr_signals_handle(); res = write(sockfd, buf, 1); continue; } pr_trace_msg(trace_channel, 5, "error writing credentials byte for LOCAL_CREDS to fd %d: %s", sockfd, strerror(errno)); return -1; } return res; } #endif /* !SCM_CREDS */ int pr_ctrls_connect(const char *socket_file) { int sockfd = -1, len = 0; struct sockaddr_un cl_sock, ctrl_sock; /* No interruptions */ pr_signals_block(); /* Create a Unix domain socket */ sockfd = socket(AF_UNIX, SOCK_STREAM, 0); if (sockfd < 0) { int xerrno = errno; pr_signals_unblock(); errno = xerrno; return -1; } if (fcntl(sockfd, F_SETFD, FD_CLOEXEC) < 0) { int xerrno = errno; close(sockfd); errno = xerrno; return -1; } /* Fill in the socket address */ memset(&cl_sock, 0, sizeof(cl_sock)); /* This first part is clever. First, this process creates a socket in * the file system. It _then_ connect()s to the server. Upon accept()ing * the connection, the server examines the created socket to see that it * is indeed a socket, with the proper mode and time. Clever, but not * ideal. */ cl_sock.sun_family = AF_UNIX; snprintf(cl_sock.sun_path, sizeof(cl_sock.sun_path) - 1, "%s%05u", "/tmp/ftp.cl", (unsigned int) getpid()); len = sizeof(cl_sock); /* Make sure the file doesn't already exist */ unlink(cl_sock.sun_path); /* Make it a socket */ if (bind(sockfd, (struct sockaddr *) &cl_sock, len) < 0) { int xerrno = errno; unlink(cl_sock.sun_path); pr_signals_unblock(); errno = xerrno; return -1; } /* Set the proper mode */ if (chmod(cl_sock.sun_path, PR_CTRLS_CL_MODE) < 0) { int xerrno = errno; unlink(cl_sock.sun_path); pr_signals_unblock(); errno = xerrno; return -1; } /* Now connect to the real server */ memset(&ctrl_sock, 0, sizeof(ctrl_sock)); ctrl_sock.sun_family = AF_UNIX; sstrncpy(ctrl_sock.sun_path, socket_file, sizeof(ctrl_sock.sun_path)); len = sizeof(ctrl_sock); if (connect(sockfd, (struct sockaddr *) &ctrl_sock, len) < 0) { int xerrno = errno; unlink(cl_sock.sun_path); pr_signals_unblock(); errno = xerrno; return -1; } #if !defined(SO_PEERCRED) && !defined(HAVE_GETPEEREID) && \ !defined(HAVE_GETPEERUCRED) && defined(LOCAL_CREDS) if (ctrls_connect_local_creds(sockfd) < 0) { int xerrno = errno; unlink(cl_sock.sun_path); pr_signals_unblock(); errno = xerrno; return -1; } #endif /* LOCAL_CREDS */ pr_signals_unblock(); return sockfd; } int pr_ctrls_issock_unix(mode_t sock_mode) { if (ctrls_use_isfifo) { #ifdef S_ISFIFO if (S_ISFIFO(sock_mode)) { return 0; } #endif /* S_ISFIFO */ } else { #ifdef S_ISSOCK if (S_ISSOCK(sock_mode)) { return 0; } #endif /* S_ISSOCK */ } errno = ENOSYS; return -1; } #if defined(SO_PEERCRED) static int ctrls_get_creds_peercred(int sockfd, uid_t *uid, gid_t *gid, pid_t *pid) { struct ucred cred; socklen_t credlen = sizeof(cred); if (getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &cred, &credlen) < 0) { int xerrno = errno; pr_trace_msg(trace_channel, 2, "error obtaining peer credentials using SO_PEERCRED: %s", strerror(xerrno)); errno = EPERM; return -1; } if (uid) *uid = cred.uid; if (gid) *gid = cred.gid; if (pid) *pid = cred.pid; return 0; } #endif /* SO_PEERCRED */ #if !defined(SO_PEERCRED) && defined(HAVE_GETPEEREID) static int ctrls_get_creds_peereid(int sockfd, uid_t *uid, gid_t *gid) { if (getpeereid(sockfd, uid, gid) < 0) { int xerrno = errno; pr_trace_msg(trace_channel, 7, "error obtaining credentials using " "getpeereid(2) on fd %d: %s", sockfd, strerror(xerrno)); errno = xerrno; return -1; } return 0; } #endif /* !HAVE_GETPEEREID */ #if !defined(SO_PEERCRED) && !defined(HAVE_GETPEEREID) && \ defined(HAVE_GETPEERUCRED) static int ctrls_get_creds_peerucred(int sockfd, uid_t *uid, gid_t *gid) { ucred_t *cred = NULL; if (getpeerucred(sockfd, &cred) < 0) { int xerrno = errno; pr_trace_msg(trace_channel, 7, "error obtaining credentials using " "getpeerucred(3) on fd %d: %s", sockfd, strerror(xerrno)); errno = xerrno; return -1; } if (uid) *uid = ucred_getruid(cred); if (gid) *gid = ucred_getrgid(cred); ucred_free(cred); return 0; } #endif /* !HAVE_GETPEERUCRED */ #if !defined(SO_PEERCRED) && !defined(HAVE_GETPEEREID) && \ !defined(HAVE_GETPEERUCRED) && defined(LOCAL_CREDS) static int ctrls_get_creds_local(int sockfd, uid_t *uid, gid_t *gid, pid_t *pid) { int res; char buf[1]; struct iovec iov; struct msghdr msg; # if defined(SOCKCREDSIZE) # define MINCREDSIZE (sizeof(struct cmsghdr) + SOCKCREDSIZE(0)) # else # if defined(HAVE_STRUCT_CMSGCRED) # define MINCREDSIZE (sizeof(struct cmsghdr) + sizeof(struct cmsgcred)) # elif defined(HAVE_STRUCT_SOCKCRED) # define MINCREDSIZE (sizeof(struct cmsghdr) + sizeof(struct sockcred)) # endif # endif /* !SOCKCREDSIZE */ char control[MINCREDSIZE]; iov.iov_base = buf; iov.iov_len = 1; memset(&msg, 0, sizeof(msg)); msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = control; msg.msg_controllen = sizeof(control); msg.msg_flags = 0; res = recvmsg(sockfd, &msg, 0); while (res < 0) { int xerrno = errno; if (xerrno == EINTR) { pr_signals_handle(); res = recvmsg(sockfd, &msg, 0); continue; } pr_trace_msg(trace_channel, 6, "error calling recvmsg() on fd %d: %s", sockfd, strerror(xerrno)); errno = xerrno; return -1; } if (msg.msg_controllen > 0) { #if defined(HAVE_STRUCT_CMSGCRED) struct cmsgcred cred; #elif defined(HAVE_STRUCT_SOCKCRED) struct sockcred cred; #endif /* !CMSGCRED and !SOCKCRED */ struct cmsghdr *hdr = (struct cmsghdr *) control; if (hdr->cmsg_level != SOL_SOCKET) { pr_trace_msg(trace_channel, 5, "message received via recvmsg() on fd %d was not a SOL_SOCKET message", sockfd); errno = EINVAL; return -1; } if (hdr->cmsg_len < MINCREDSIZE) { pr_trace_msg(trace_channel, 5, "message received via recvmsg() on fd %d was not of proper " "length (%u bytes)", sockfd, MINCREDSIZE); errno = EINVAL; return -1; } if (hdr->cmsg_type != SCM_CREDS) { pr_trace_msg(trace_channel, 5, "message received via recvmsg() on fd %d was not of type SCM_CREDS", sockfd); errno = EINVAL; return -1; } #if defined(HAVE_STRUCT_CMSGCRED) memcpy(&cred, CMSG_DATA(hdr), sizeof(struct cmsgcred)); if (uid) *uid = cred.cmcred_uid; if (gid) *gid = cred.cmcred_gid; if (pid) *pid = cred.cmcred_pid; #elif defined(HAVE_STRUCT_SOCKCRED) memcpy(&cred, CMSG_DATA(hdr), sizeof(struct sockcred)); if (uid) *uid = cred.sc_uid; if (gid) *gid = cred.sc_gid; #endif return 0; } return -1; } #endif /* !SCM_CREDS */ static int ctrls_get_creds_basic(struct sockaddr_un *sock, int cl_fd, unsigned int max_age, uid_t *uid, gid_t *gid, pid_t *pid) { pid_t cl_pid = 0; char *tmp = NULL; time_t stale_time; struct stat st; /* Check the path -- hmmm... */ PRIVS_ROOT while (stat(sock->sun_path, &st) < 0) { int xerrno = errno; if (xerrno == EINTR) { pr_signals_handle(); continue; } PRIVS_RELINQUISH pr_trace_msg(trace_channel, 2, "error: unable to stat %s: %s", sock->sun_path, strerror(xerrno)); (void) close(cl_fd); errno = xerrno; return -1; } PRIVS_RELINQUISH /* Is it a socket? */ if (pr_ctrls_issock_unix(st.st_mode) < 0) { (void) close(cl_fd); errno = ENOTSOCK; return -1; } /* Are the perms _not_ rwx------? */ if (st.st_mode & (S_IRWXG|S_IRWXO) || ((st.st_mode & S_IRWXU) != PR_CTRLS_CL_MODE)) { pr_trace_msg(trace_channel, 3, "error: unable to accept connection: incorrect mode"); (void) close(cl_fd); errno = EPERM; return -1; } /* Is it new enough? */ stale_time = time(NULL) - max_age; if (st.st_atime < stale_time || st.st_ctime < stale_time || st.st_mtime < stale_time) { char *msg = "error: stale connection"; pr_trace_msg(trace_channel, 3, "unable to accept connection: stale connection"); /* Log the times being compared, to aid in debugging this situation. */ if (st.st_atime < stale_time) { time_t age = stale_time - st.st_atime; pr_trace_msg(trace_channel, 3, "last access time of '%s' is %lu secs old (must be less than %u secs)", sock->sun_path, (unsigned long) age, max_age); } if (st.st_ctime < stale_time) { time_t age = stale_time - st.st_ctime; pr_trace_msg(trace_channel, 3, "last change time of '%s' is %lu secs old (must be less than %u secs)", sock->sun_path, (unsigned long) age, max_age); } if (st.st_mtime < stale_time) { time_t age = stale_time - st.st_mtime; pr_trace_msg(trace_channel, 3, "last modified time of '%s' is %lu secs old (must be less than %u " "secs)", sock->sun_path, (unsigned long) age, max_age); } if (pr_ctrls_send_msg(cl_fd, -1, 1, &msg) < 0) { pr_trace_msg(trace_channel, 2, "error sending message: %s", strerror(errno)); } (void) close(cl_fd); errno = ETIMEDOUT; return -1; } /* Parse the PID out of the path */ tmp = sock->sun_path; tmp += strlen("/tmp/ftp.cl"); cl_pid = atol(tmp); /* Return the IDs of the caller */ if (uid) *uid = st.st_uid; if (gid) *gid = st.st_gid; if (pid) *pid = cl_pid; return 0; } int pr_ctrls_accept(int sockfd, uid_t *uid, gid_t *gid, pid_t *pid, unsigned int max_age) { socklen_t len = 0; struct sockaddr_un sock; int cl_fd = -1; int res = -1; len = sizeof(sock); while ((cl_fd = accept(sockfd, (struct sockaddr *) &sock, &len)) < 0) { int xerrno = errno; if (xerrno == EINTR) { pr_signals_handle(); continue; } pr_trace_msg(trace_channel, 3, "error: unable to accept on local socket: %s", strerror(xerrno)); errno = xerrno; return -1; } /* NULL terminate the name */ sock.sun_path[sizeof(sock.sun_path)-1] = '\0'; #if defined(SO_PEERCRED) pr_trace_msg(trace_channel, 5, "checking client credentials using SO_PEERCRED"); res = ctrls_get_creds_peercred(cl_fd, uid, gid, pid); #elif !defined(SO_PEERCRED) && defined(HAVE_GETPEEREID) pr_trace_msg(trace_channel, 5, "checking client credentials using getpeereid(2)"); res = ctrls_get_creds_peereid(cl_fd, uid, gid); #elif !defined(SO_PEERCRED) && !defined(HAVE_GETPEEREID) && \ defined(HAVE_GETPEERUCRED) pr_trace_msg(trace_channel, 5, "checking client credentials using getpeerucred(3)"); res = ctrls_get_creds_peerucred(cl_fd, uid, gid); #elif !defined(SO_PEERCRED) && !defined(HAVE_GETPEEREID) && \ !defined(HAVE_GETPEERUCRED) && defined(LOCAL_CREDS) pr_trace_msg(trace_channel, 5, "checking client credentials using SCM_CREDS"); res = ctrls_get_creds_local(cl_fd, uid, gid, pid); #endif /* Fallback to the Stevens method of determining connection credentials, * if the kernel-enforced methods did not pan out. */ if (res < 0) { pr_trace_msg(trace_channel, 5, "checking client credentials using Stevens' method"); res = ctrls_get_creds_basic(&sock, cl_fd, max_age, uid, gid, pid); if (res < 0) return res; } /* Done with the path now */ PRIVS_ROOT unlink(sock.sun_path); PRIVS_RELINQUISH return cl_fd; } void pr_block_ctrls(void) { ctrls_blocked = TRUE; } void pr_unblock_ctrls(void) { ctrls_blocked = FALSE; } int pr_check_actions(void) { ctrls_action_t *act = NULL; for (act = ctrls_action_list; act; act = act->next) { if (act->flags & PR_CTRLS_ACT_SOLITARY) { /* This is a territorial action -- only one instance allowed */ if (ctrls_lookup_action(NULL, act->action, FALSE)) { pr_log_pri(PR_LOG_NOTICE, "duplicate controls for '%s' action not allowed", act->action); return -1; } } } return 0; } int pr_run_ctrls(module *mod, const char *action) { pr_ctrls_t *ctrl = NULL; /* Are ctrls blocked? */ if (ctrls_blocked) { errno = EPERM; return -1; } for (ctrl = ctrls_active_list; ctrl; ctrl = ctrl->ctrls_next) { /* Be watchful of the various client-side flags. Note: if * ctrl->ctrls_cl is ever NULL, it means there's a bug in the code. */ if (ctrl->ctrls_cl->cl_flags != PR_CTRLS_CL_HAVEREQ) continue; /* Has this control been disabled? */ if (ctrl->ctrls_flags & PR_CTRLS_ACT_DISABLED) continue; /* Is it time to trigger this ctrl? */ if (!(ctrl->ctrls_flags & PR_CTRLS_REQUESTED)) continue; if (ctrl->ctrls_when > time(NULL)) { ctrl->ctrls_flags |= PR_CTRLS_PENDING; pr_ctrls_add_response(ctrl, "request pending"); continue; } if (action && strcmp(ctrl->ctrls_action, action) == 0) { pr_trace_msg(trace_channel, 7, "calling '%s' control handler", ctrl->ctrls_action); /* Invoke the callback, if the ctrl's action matches. Unblock * ctrls before invoking the callback, then re-block them after the * callback returns. This will allow the action handlers to use some * of the Controls API functions correctly. */ pr_unblock_ctrls(); ctrl->ctrls_cb_retval = ctrl->ctrls_cb(ctrl, (ctrl->ctrls_cb_args ? ctrl->ctrls_cb_args->nelts : 0), (ctrl->ctrls_cb_args ? (char **) ctrl->ctrls_cb_args->elts : NULL)); pr_block_ctrls(); if (ctrl->ctrls_cb_retval < 1) { ctrl->ctrls_flags &= ~PR_CTRLS_REQUESTED; ctrl->ctrls_flags &= ~PR_CTRLS_PENDING; ctrl->ctrls_flags |= PR_CTRLS_HANDLED; } } else if (!action) { pr_trace_msg(trace_channel, 7, "calling '%s' control handler", ctrl->ctrls_action); /* If no action was given, invoke every callback */ pr_unblock_ctrls(); ctrl->ctrls_cb_retval = ctrl->ctrls_cb(ctrl, (ctrl->ctrls_cb_args ? ctrl->ctrls_cb_args->nelts : 0), (ctrl->ctrls_cb_args ? (char **) ctrl->ctrls_cb_args->elts : NULL)); pr_block_ctrls(); if (ctrl->ctrls_cb_retval < 1) { ctrl->ctrls_flags &= ~PR_CTRLS_REQUESTED; ctrl->ctrls_flags &= ~PR_CTRLS_PENDING; ctrl->ctrls_flags |= PR_CTRLS_HANDLED; } } } return 0; } int pr_reset_ctrls(void) { pr_ctrls_t *ctrl = NULL; /* NOTE: need a clean_ctrls() or somesuch that will, after sending any * responses, iterate through the list and "free" any ctrls whose * ctrls_cb_retval is zero. This feature is used to handle things like * shutdown requests in the future -- the request is only considered * "processed" when the callback returns zero. Any non-zero requests are * not cleared, and are considered "pending". However, this brings up the * complication of an additional request for that action being issued by the * client before the request is processed. Simplest solution: remove the * old request args, and replace them with the new ones. * * This requires that the return value of the ctrl callback be explicitly * documented. * * How about: ctrls_cb_retval = 1 pending * 0 processed, OK (reset) * -1 processed, error (reset) */ for (ctrl = ctrls_active_list; ctrl; ctrl = ctrl->ctrls_next) { if (ctrl->ctrls_cb_retval < 1) ctrls_free(ctrl); } return 0; } /* From include/mod_ctrls.h */ /* Returns TRUE if the given cl_gid is allowed by the group ACL, FALSE * otherwise. Note that the default is to deny everyone, unless an ACL has * been configured. */ unsigned char pr_ctrls_check_group_acl(gid_t cl_gid, const ctrls_grp_acl_t *grp_acl) { register int i = 0; unsigned char res = FALSE; /* Note: the special condition of ngids of 1 and gids of NULL signals * that all groups are to be treated according to the allow member. */ if (grp_acl->gids) { for (i = 0; i < grp_acl->ngids; i++) { if ((grp_acl->gids)[i] == cl_gid) { res = TRUE; } } } else if (grp_acl->ngids == 1) res = TRUE; if (!grp_acl->allow) res = !res; return res; } /* Returns TRUE if the given cl_uid is allowed by the user ACL, FALSE * otherwise. Note that the default is to deny everyone, unless an ACL has * been configured. */ unsigned char pr_ctrls_check_user_acl(uid_t cl_uid, const ctrls_usr_acl_t *usr_acl) { register int i = 0; unsigned char res = FALSE; /* Note: the special condition of nuids of 1 and uids of NULL signals * that all users are to be treated according to the allow member. */ if (usr_acl->uids) { for (i = 0; i < usr_acl->nuids; i++) { if ((usr_acl->uids)[i] == cl_uid) { res = TRUE; } } } else if (usr_acl->nuids == 1) res = TRUE; if (!usr_acl->allow) res = !res; return res; } /* Returns TRUE for allowed, FALSE for denied. */ unsigned char pr_ctrls_check_acl(const pr_ctrls_t *ctrl, const ctrls_acttab_t *acttab, const char *action) { register unsigned int i = 0; for (i = 0; acttab[i].act_action; i++) { if (strcmp(acttab[i].act_action, action) == 0) { if (!pr_ctrls_check_user_acl(ctrl->ctrls_cl->cl_uid, &(acttab[i].act_acl->acl_usrs)) && !pr_ctrls_check_group_acl(ctrl->ctrls_cl->cl_gid, &(acttab[i].act_acl->acl_grps))) { /* Access denied */ return FALSE; } } } return TRUE; } void pr_ctrls_init_acl(ctrls_acl_t *acl) { /* Sanity check */ if (!acl) return; memset(acl, 0, sizeof(ctrls_acl_t)); acl->acl_usrs.allow = acl->acl_grps.allow = TRUE; } static char *ctrls_argsep(char **arg) { char *ret = NULL, *dst = NULL; char quote_mode = 0; if (!arg || !*arg || !**arg) return NULL; while (**arg && PR_ISSPACE(**arg)) (*arg)++; if (!**arg) return NULL; ret = dst = *arg; if (**arg == '\"') { quote_mode++; (*arg)++; } while (**arg && **arg != ',' && (quote_mode ? (**arg != '\"') : (!PR_ISSPACE(**arg)))) { if (**arg == '\\' && quote_mode) { /* escaped char */ if (*((*arg) + 1)) *dst = *(++(*arg)); } *dst++ = **arg; ++(*arg); } if (**arg) (*arg)++; *dst = '\0'; return ret; } char **pr_ctrls_parse_acl(pool *acl_pool, char *acl_str) { char *name = NULL, *acl_str_dup = NULL, **acl_list = NULL; array_header *acl_arr = NULL; pool *tmp_pool = NULL; /* Sanity checks */ if (!acl_pool || !acl_str) return NULL; tmp_pool = make_sub_pool(acl_pool); acl_str_dup = pstrdup(tmp_pool, acl_str); /* Allocate an array */ acl_arr = make_array(acl_pool, 0, sizeof(char **)); /* Add each name to the array */ while ((name = ctrls_argsep(&acl_str_dup)) != NULL) { char *tmp = pstrdup(acl_pool, name); /* Push the name into the ACL array */ *((char **) push_array(acl_arr)) = tmp; } /* Terminate the temp array with a NULL, as is proper. */ *((char **) push_array(acl_arr)) = NULL; acl_list = (char **) acl_arr->elts; destroy_pool(tmp_pool); /* return the array of names */ return acl_list; } void pr_ctrls_set_group_acl(pool *grp_acl_pool, ctrls_grp_acl_t *grp_acl, const char *allow, char *grouplist) { char *group = NULL, **groups = NULL; array_header *gid_list = NULL; gid_t gid = 0; pool *tmp_pool = NULL; if (grp_acl_pool == NULL || grp_acl == NULL || allow == NULL || grouplist == NULL) { return; } tmp_pool = make_sub_pool(grp_acl_pool); if (strncmp(allow, "allow", 6) == 0) { grp_acl->allow = TRUE; } else { grp_acl->allow = FALSE; } /* Parse the given expression into an array, then retrieve the GID * for each given name. */ groups = pr_ctrls_parse_acl(grp_acl_pool, grouplist); /* Allocate an array of gid_t's */ gid_list = make_array(grp_acl_pool, 0, sizeof(gid_t)); for (group = *groups; group != NULL; group = *++groups) { /* Handle a group name of "*" differently. */ if (strncmp(group, "*", 2) == 0) { grp_acl->ngids = 1; grp_acl->gids = NULL; destroy_pool(tmp_pool); return; } else { gid = pr_auth_name2gid(tmp_pool, group); if (gid == (gid_t) -1) continue; } *((gid_t *) push_array(gid_list)) = gid; } grp_acl->ngids = gid_list->nelts; grp_acl->gids = (gid_t *) gid_list->elts; destroy_pool(tmp_pool); } void pr_ctrls_set_user_acl(pool *usr_acl_pool, ctrls_usr_acl_t *usr_acl, const char *allow, char *userlist) { char *user = NULL, **users = NULL; array_header *uid_list = NULL; uid_t uid = 0; pool *tmp_pool = NULL; /* Sanity checks */ if (usr_acl_pool == NULL || usr_acl == NULL || allow == NULL || userlist == NULL) { return; } tmp_pool = make_sub_pool(usr_acl_pool); if (strncmp(allow, "allow", 6) == 0) { usr_acl->allow = TRUE; } else { usr_acl->allow = FALSE; } /* Parse the given expression into an array, then retrieve the UID * for each given name. */ users = pr_ctrls_parse_acl(usr_acl_pool, userlist); /* Allocate an array of uid_t's */ uid_list = make_array(usr_acl_pool, 0, sizeof(uid_t)); for (user = *users; user != NULL; user = *++users) { /* Handle a user name of "*" differently. */ if (strncmp(user, "*", 2) == 0) { usr_acl->nuids = 1; usr_acl->uids = NULL; destroy_pool(tmp_pool); return; } else { uid = pr_auth_name2uid(tmp_pool, user); if (uid == (uid_t) -1) continue; } *((uid_t *) push_array(uid_list)) = uid; } usr_acl->nuids = uid_list->nelts; usr_acl->uids = (uid_t *) uid_list->elts; destroy_pool(tmp_pool); } char *pr_ctrls_set_module_acls(ctrls_acttab_t *acttab, pool *acl_pool, char **actions, const char *allow, const char *type, char *list) { register unsigned int i = 0; unsigned char all_actions = FALSE; /* First, sanity check the given list of actions against the actions * in the given table. */ for (i = 0; actions[i]; i++) { register unsigned int j = 0; unsigned char valid_action = FALSE; if (strncmp(actions[i], "all", 4) == 0) continue; for (j = 0; acttab[j].act_action; j++) { if (strcmp(actions[i], acttab[j].act_action) == 0) { valid_action = TRUE; break; } } if (!valid_action) return actions[i]; } for (i = 0; actions[i]; i++) { register unsigned int j = 0; if (!all_actions && strncmp(actions[i], "all", 4) == 0) all_actions = TRUE; for (j = 0; acttab[j].act_action; j++) { if (all_actions || strcmp(actions[i], acttab[j].act_action) == 0) { /* Use the type parameter to determine whether the list is of users or * of groups. */ if (strncmp(type, "user", 5) == 0) { pr_ctrls_set_user_acl(acl_pool, &(acttab[j].act_acl->acl_usrs), allow, list); } else if (strncmp(type, "group", 6) == 0) { pr_ctrls_set_group_acl(acl_pool, &(acttab[j].act_acl->acl_grps), allow, list); } } } } return NULL; } char *pr_ctrls_unregister_module_actions(ctrls_acttab_t *acttab, char **actions, module *mod) { register unsigned int i = 0; /* First, sanity check the given actions against the actions supported by * this module. */ for (i = 0; actions[i]; i++) { register unsigned int j = 0; unsigned char valid_action = FALSE; for (j = 0; acttab[j].act_action; j++) { if (strcmp(actions[i], acttab[j].act_action) == 0) { valid_action = TRUE; break; } } if (!valid_action) return actions[i]; } /* Next, iterate through both lists again, looking for actions of the * module _not_ in the given list. */ for (i = 0; acttab[i].act_action; i++) { register unsigned int j = 0; unsigned char have_action = FALSE; for (j = 0; actions[j]; j++) { if (strcmp(acttab[i].act_action, actions[j]) == 0) { have_action = TRUE; break; } } if (have_action) { pr_trace_msg(trace_channel, 4, "mod_%s.c: removing '%s' control", mod->name, acttab[i].act_action); pr_ctrls_unregister(mod, acttab[i].act_action); destroy_pool(acttab[i].act_acl->acl_pool); } } return NULL; } int pr_ctrls_set_logfd(int fd) { /* Close any existing log fd. */ if (ctrls_logfd >= 0) { (void) close(ctrls_logfd); } ctrls_logfd = fd; return 0; } int pr_ctrls_log(const char *module_version, const char *fmt, ...) { va_list msg; int res; /* sanity check */ if (ctrls_logfd < 0) return 0; va_start(msg, fmt); res = pr_log_vwritefile(ctrls_logfd, module_version, fmt, msg); va_end(msg); return res; } /* Initialize the Controls API. */ void init_ctrls(void) { struct stat st; int sockfd; struct sockaddr_un sockun; size_t socklen; char *sockpath = PR_RUN_DIR "/test.sock"; if (ctrls_pool) { destroy_pool(ctrls_pool); } ctrls_pool = make_sub_pool(permanent_pool); pr_pool_tag(ctrls_pool, "Controls Pool"); /* Make sure all of the lists are zero'd out. */ ctrls_action_list = NULL; ctrls_active_list = NULL; ctrls_free_list = NULL; /* And that the lookup indices are (re)set as well... */ action_lookup_next = NULL; action_lookup_action = NULL; action_lookup_module = NULL; /* Run-time check to find out whether this platform identifies a * Unix domain socket file descriptor via the S_ISFIFO macro, or * the S_ISSOCK macro. */ sockfd = socket(AF_UNIX, SOCK_STREAM, 0); if (sockfd < 0) { pr_log_debug(DEBUG10, "unable to create Unix domain socket: %s", strerror(errno)); return; } memset(&sockun, 0, sizeof(sockun)); sockun.sun_family = AF_UNIX; sstrncpy(sockun.sun_path, sockpath, sizeof(sockun.sun_path)); socklen = sizeof(struct sockaddr_un); if (bind(sockfd, (struct sockaddr *) &sockun, socklen) < 0) { pr_log_debug(DEBUG10, "unable to bind to Unix domain socket at '%s': %s", sockpath, strerror(errno)); (void) close(sockfd); (void) unlink(sockpath); return; } if (fstat(sockfd, &st) < 0) { pr_log_debug(DEBUG10, "unable to stat Unix domain socket at '%s': %s", sockpath, strerror(errno)); (void) close(sockfd); (void) unlink(sockpath); return; } #ifdef S_ISFIFO pr_log_debug(DEBUG10, "testing Unix domain socket using S_ISFIFO"); if (S_ISFIFO(st.st_mode)) { ctrls_use_isfifo = TRUE; } #else pr_log_debug(DEBUG10, "cannot test Unix domain socket using S_ISFIFO: " "macro undefined"); #endif #ifdef S_ISSOCK pr_log_debug(DEBUG10, "testing Unix domain socket using S_ISSOCK"); if (S_ISSOCK(st.st_mode)) { ctrls_use_isfifo = FALSE; } #else pr_log_debug(DEBUG10, "cannot test Unix domain socket using S_ISSOCK: " "macro undefined"); #endif pr_log_debug(DEBUG10, "using %s macro for Unix domain socket detection", ctrls_use_isfifo ? "S_ISFIFO" : "S_ISSOCK"); (void) close(sockfd); (void) unlink(sockpath); return; } #endif /* PR_USE_CTRLS */ proftpd-dfsg-1.3.5~rc3/src/cmd.c0000644000175000017500000002154312067354624016261 0ustar frankiefrankie/* * ProFTPD - FTP server daemon * Copyright (c) 2009-2012 The ProFTPD Project team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * As a special exemption, The ProFTPD Project team and other respective * copyright holders give permission to link this program with OpenSSL, and * distribute the resulting executable, without including the source code for * OpenSSL in the source distribution. * * $Id: cmd.c,v 1.12 2012/12/28 17:40:36 castaglia Exp $ */ #include "conf.h" /* This struct and the list of such structs are used to try to reduce * the use of the following idiom to identify which command a given * cmd_rec is: * * if (strcmp(cmd->argv[0], C_USER) == 0) * * Rather than using strcmp(3) so freely, try to reduce the command to * a fixed ID (an index into the struct list); this ID can then be compared * rather than using strcmp(3). For commands not in the list, strcmp(3) * can always be used as a fallback. * * A future improvement would be to sort the entries in the table so that * the most common commands appear earlier in the table, and make the * linear scan even shorter. But I'd need to collect better metrics in * order to do that. */ struct cmd_entry { const char *cmd_name; size_t cmd_namelen; }; static struct cmd_entry cmd_ids[] = { { " ", 1 }, /* Index 0 is intentionally filled with a sentinel */ { C_USER, 4 }, /* PR_CMD_USER_ID (1) */ { C_PASS, 4 }, /* PR_CMD_PASS_ID (2) */ { C_ACCT, 4 }, /* PR_CMD_ACCT_ID (3) */ { C_CWD, 3 }, /* PR_CMD_CWD_ID (4) */ { C_XCWD, 4 }, /* PR_CMD_XCWD_ID (5) */ { C_CDUP, 4 }, /* PR_CMD_CDUP_ID (6) */ { C_XCUP, 4 }, /* PR_CMD_XCUP_ID (7) */ { C_SMNT, 4 }, /* PR_CMD_SMNT_ID (8) */ { C_REIN, 4 }, /* PR_CMD_REIN_ID (9) */ { C_QUIT, 4 }, /* PR_CMD_QUIT_ID (10) */ { C_PORT, 4 }, /* PR_CMD_PORT_ID (11) */ { C_EPRT, 4 }, /* PR_CMD_EPRT_ID (12) */ { C_PASV, 4 }, /* PR_CMD_PASV_ID (13) */ { C_EPSV, 4 }, /* PR_CMD_EPSV_ID (14) */ { C_TYPE, 4 }, /* PR_CMD_TYPE_ID (15) */ { C_STRU, 4 }, /* PR_CMD_STRU_ID (16) */ { C_MODE, 4 }, /* PR_CMD_MODE_ID (17) */ { C_RETR, 4 }, /* PR_CMD_RETR_ID (18) */ { C_STOR, 4 }, /* PR_CMD_STOR_ID (19) */ { C_STOU, 4 }, /* PR_CMD_STOU_ID (20) */ { C_APPE, 4 }, /* PR_CMD_APPE_ID (21) */ { C_ALLO, 4 }, /* PR_CMD_ALLO_ID (22) */ { C_REST, 4 }, /* PR_CMD_REST_ID (23) */ { C_RNFR, 4 }, /* PR_CMD_RNFR_ID (24) */ { C_RNTO, 4 }, /* PR_CMD_RNTO_ID (25) */ { C_ABOR, 4 }, /* PR_CMD_ABOR_ID (26) */ { C_DELE, 4 }, /* PR_CMD_DELE_ID (27) */ { C_MDTM, 4 }, /* PR_CMD_MDTM_ID (28) */ { C_RMD, 3 }, /* PR_CMD_RMD_ID (29) */ { C_XRMD, 4 }, /* PR_CMD_XRMD_ID (30) */ { C_MKD, 3 }, /* PR_CMD_MKD_ID (31) */ { C_MLSD, 4 }, /* PR_CMD_MLSD_ID (32) */ { C_MLST, 4 }, /* PR_CMD_MLST_ID (33) */ { C_XMKD, 4 }, /* PR_CMD_XMKD_ID (34) */ { C_PWD, 3 }, /* PR_CMD_PWD_ID (35) */ { C_XPWD, 4 }, /* PR_CMD_XPWD_ID (36) */ { C_SIZE, 4 }, /* PR_CMD_SIZE_ID (37) */ { C_LIST, 4 }, /* PR_CMD_LIST_ID (38) */ { C_NLST, 4 }, /* PR_CMD_NLST_ID (39) */ { C_SITE, 4 }, /* PR_CMD_SITE_ID (40) */ { C_SYST, 4 }, /* PR_CMD_SYST_ID (41) */ { C_STAT, 4 }, /* PR_CMD_STAT_ID (42) */ { C_HELP, 4 }, /* PR_CMD_HELP_ID (43) */ { C_NOOP, 4 }, /* PR_CMD_NOOP_ID (44) */ { C_FEAT, 4 }, /* PR_CMD_FEAT_ID (45) */ { C_OPTS, 4 }, /* PR_CMD_OPTS_ID (46) */ { C_LANG, 4 }, /* PR_CMD_LANG_ID (47) */ { C_ADAT, 4 }, /* PR_CMD_ADAT_ID (48) */ { C_AUTH, 4 }, /* PR_CMD_AUTH_ID (49) */ { C_CCC, 3 }, /* PR_CMD_CCC_ID (50) */ { C_CONF, 4 }, /* PR_CMD_CONF_ID (51) */ { C_ENC, 3 }, /* PR_CMD_ENC_ID (52) */ { C_MIC, 3 }, /* PR_CMD_MIC_ID (53) */ { C_PBSZ, 4 }, /* PR_CMD_PBSZ_ID (54) */ { C_PROT, 4 }, /* PR_CMD_PROT_ID (55) */ { C_MFF, 3 }, /* PR_CMD_MFF_ID (56) */ { C_MFMT, 4 }, /* PR_CMD_MFMT_ID (57) */ { C_HOST, 4 }, /* PR_CMD_HOST_ID (58) */ { NULL, 0 } }; cmd_rec *pr_cmd_alloc(pool *p, int argc, ...) { pool *newpool = NULL; cmd_rec *cmd = NULL; va_list args; if (p == NULL) { errno = EINVAL; return NULL; } newpool = make_sub_pool(p); pr_pool_tag(newpool, "cmd_rec pool"); cmd = pcalloc(newpool, sizeof(cmd_rec)); cmd->argc = argc; cmd->stash_index = -1; cmd->pool = newpool; cmd->tmp_pool = make_sub_pool(cmd->pool); pr_pool_tag(cmd->tmp_pool, "cmd_rec tmp pool"); if (argc) { register unsigned int i = 0; cmd->argv = pcalloc(newpool, sizeof(void *) * (argc + 1)); va_start(args, argc); for (i = 0; i < argc; i++) cmd->argv[i] = (void *) va_arg(args, char *); va_end(args); cmd->argv[argc] = NULL; } /* This table will not contain that many entries, so a low number * of chains should suffice. */ cmd->notes = pr_table_nalloc(cmd->pool, 0, 8); return cmd; } int pr_cmd_clear_cache(cmd_rec *cmd) { if (cmd == NULL) { errno = EINVAL; return -1; } /* Clear the strings that have been cached for this command in the * notes table. */ (void) pr_table_remove(cmd->notes, "displayable-str", NULL); return 0; } int pr_cmd_cmp(cmd_rec *cmd, int cmd_id) { if (cmd == NULL || cmd_id <= 0) { errno = EINVAL; return -1; } if (cmd->argc == 0 || cmd->argv == NULL) { return 1; } /* The cmd ID is unknown; look it up. */ if (cmd->cmd_id == 0) { cmd->cmd_id = pr_cmd_get_id(cmd->argv[0]); } /* The cmd ID is known to be unknown. */ if (cmd->cmd_id < 0) { return 1; } if (cmd->cmd_id == cmd_id) { return 0; } return cmd->cmd_id < cmd_id ? -1 : 1; } int pr_cmd_set_name(cmd_rec *cmd, const char *cmd_name) { if (cmd == NULL || cmd_name == NULL) { errno = EINVAL; return -1; } cmd->argv[0] = (char *) cmd_name; cmd->cmd_id = pr_cmd_get_id(cmd->argv[0]); return 0; } int pr_cmd_strcmp(cmd_rec *cmd, const char *cmd_name) { int cmd_id, res; size_t cmd_namelen; if (cmd == NULL || cmd_name == NULL) { errno = EINVAL; return -1; } if (cmd->argc == 0 || cmd->argv == NULL) { return 1; } /* The cmd ID is unknown; look it up. */ if (cmd->cmd_id == 0) { cmd->cmd_id = pr_cmd_get_id(cmd->argv[0]); } if (cmd->cmd_id > 0) { cmd_id = pr_cmd_get_id(cmd_name); res = pr_cmd_cmp(cmd, cmd_id); if (res == 0) { return 0; } return strncmp(cmd_name, cmd->argv[0], cmd_ids[cmd->cmd_id].cmd_namelen + 1); } cmd_namelen = strlen(cmd_name); return strncmp(cmd->argv[0], cmd_name, cmd_namelen + 1); } char *pr_cmd_get_displayable_str(cmd_rec *cmd, size_t *str_len) { char *res; int argc; char **argv; pool *p; if (cmd == NULL) { errno = EINVAL; return NULL; } res = pr_table_get(cmd->notes, "displayable-str", NULL); if (res) { if (str_len != NULL) { *str_len = strlen(res); } return res; } argc = cmd->argc; argv = cmd->argv; p = cmd->pool; res = ""; /* Check for "sensitive" commands. */ if (pr_cmd_cmp(cmd, PR_CMD_PASS_ID) == 0 || pr_cmd_cmp(cmd, PR_CMD_ADAT_ID) == 0) { argc = 2; argv[1] = "(hidden)"; } if (argc > 0) { register unsigned int i; res = pstrcat(p, res, pr_fs_decode_path(p, argv[0]), NULL); for (i = 1; i < argc; i++) { res = pstrcat(p, res, " ", pr_fs_decode_path(p, argv[i]), NULL); } } /* XXX Check for errors here */ pr_table_add(cmd->notes, pstrdup(cmd->pool, "displayable-str"), pstrdup(cmd->pool, res), 0); if (str_len != NULL) { *str_len = strlen(res); } return res; } int pr_cmd_get_id(const char *cmd_name) { register unsigned int i; size_t cmd_namelen; if (cmd_name == NULL) { errno = EINVAL; return -1; } cmd_namelen = strlen(cmd_name); /* Take advantage of the fact that we know, a priori, that the shortest * command name in the list is 3 characters, and that the longest is 4 * characters. No need to scan the list if we know that the given name * is not within that length range. */ if (cmd_namelen < PR_CMD_MIN_NAMELEN || cmd_namelen > PR_CMD_MAX_NAMELEN) { errno = ENOENT; return -1; } for (i = 1; cmd_ids[i].cmd_name != NULL; i++) { if (cmd_ids[i].cmd_namelen != cmd_namelen) { continue; } if (cmd_ids[i].cmd_name[0] != cmd_name[0]) { continue; } if (strcmp(cmd_ids[i].cmd_name, cmd_name) == 0) { return i; } } errno = ENOENT; return -1; } proftpd-dfsg-1.3.5~rc3/src/env.c0000644000175000017500000000616311566550020016276 0ustar frankiefrankie/* * ProFTPD - FTP server daemon * Copyright (c) 2007-2010 The ProFTPD Project team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * As a special exemption, The ProFTPD Project team and other respective * copyright holders give permission to link this program with OpenSSL, and * distribute the resulting executable, without including the source code for * OpenSSL in the source distribution. */ /* Environment management * $Id: env.c,v 1.7 2011/05/23 21:22:24 castaglia Exp $ */ #include "conf.h" char *pr_env_get(pool *p, const char *key) { if (!p || !key) { errno = EINVAL; return NULL; } #if defined(HAVE_GETENV) return getenv(key); #else errno = ENOSYS; return NULL; #endif /* !HAVE_GETENV */ } int pr_env_set(pool *p, const char *key, const char *value) { size_t valuelen; #if defined(HAVE_SETENV) const char *k, *v; #elif defined(HAVE_PUTENV) const char *str; #endif /* !HAVE_SETENV and !HAVE_PUTENV */ if (!p || !key || !value) { errno = EINVAL; return -1; } valuelen = strlen(value); if (valuelen > PR_TUNABLE_ENV_MAX) { errno = EPERM; return -1; } /* In the PR_USE_DEVEL cases below, we use strdup(2) rather than ProFTPD's * pstrdup() in order to soothe memory trackers (e.g. Valgrind) who may * complain. */ #if defined(HAVE_SETENV) # ifdef PR_USE_DEVEL k = strdup(key); if (!k) { pr_log_pri(PR_LOG_ERR, "fatal: Memory exhausted"); exit(1); } v = strdup(value); if (!v) { pr_log_pri(PR_LOG_ERR, "fatal: Memory exhausted"); exit(1); } # else k = key; v = value; # endif /* PR_USE_DEVEL */ return setenv(k, v, 1); #elif defined(HAVE_PUTENV) str = pstrcat(p, key, "=", value, NULL); # ifdef PR_USE_DEVEL str = strdup(str); if (!str) { pr_log_pri(PR_LOG_ERR, "fatal: Memory exhausted"); exit(1); } # endif /* PR_USE_DEVEL */ return putenv((char *) str); #else errno = ENOSYS; return -1; #endif /* !HAVE_SETENV and !HAVE_PUTENV */ } int pr_env_unset(pool *p, const char *key) { #if defined(HAVE_UNSETENV) char *res; #endif /* !HAVE_UNSETENV */ if (!p || !key) { errno = EINVAL; return -1; } #if defined(HAVE_UNSETENV) /* The same key may appear multiple times in the environ, so make certain * that all such occurrences are removed. */ res = pr_env_get(p, key); while (res) { pr_signals_handle(); unsetenv(key); res = pr_env_get(p, key); } return 0; #else errno = ENOSYS; return -1; #endif /* !HAVE_UNSETENV */ } proftpd-dfsg-1.3.5~rc3/src/log.c0000644000175000017500000005054512112744461016274 0ustar frankiefrankie/* * ProFTPD - FTP server daemon * Copyright (c) 1997, 1998 Public Flood Software * Copyright (c) 1999, 2000 MacGyver aka Habeeb J. Dihu * Copyright (c) 2001-2013 The ProFTPD Project team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * As a special exemption, Public Flood Software/MacGyver aka Habeeb J. Dihu * and other respective copyright holders give permission to link this program * with OpenSSL, and distribute the resulting executable, without including * the source code for OpenSSL in the source distribution. */ /* ProFTPD logging support. * $Id: log.c,v 1.116 2013/02/25 20:27:29 castaglia Exp $ */ #include "conf.h" /* Max path length plus 64 bytes for additional info. */ #define LOGBUFFER_SIZE (PR_TUNABLE_PATH_MAX + 64) static int syslog_open = FALSE; static int syslog_discard = FALSE; static int logstderr = TRUE; static int debug_level = DEBUG0; /* Default is no debug logging */ static int facility = LOG_DAEMON; static int set_facility = -1; static char systemlog_fn[PR_TUNABLE_PATH_MAX] = {'\0'}; static char systemlog_host[256] = {'\0'}; static int systemlog_fd = -1; int syslog_sockfd = -1; #ifdef PR_USE_NONBLOCKING_LOG_OPEN static int fd_set_block(int fd) { int flags, res; flags = fcntl(fd, F_GETFL); res = fcntl(fd, F_SETFL, flags & (U32BITS ^ O_NONBLOCK)); return res; } #endif /* PR_USE_NONBLOCKING_LOG_OPEN */ int pr_log_openfile(const char *log_file, int *log_fd, mode_t log_mode) { int res; pool *tmp_pool = NULL; char *tmp = NULL, *lf; unsigned char have_stat = FALSE, *allow_log_symlinks = NULL; struct stat st; /* Sanity check */ if (!log_file || !log_fd) { errno = EINVAL; return -1; } /* Make a temporary copy of log_file in case it's a constant */ tmp_pool = make_sub_pool(permanent_pool); pr_pool_tag(tmp_pool, "log_openfile() tmp pool"); lf = pstrdup(tmp_pool, log_file); tmp = strrchr(lf, '/'); if (tmp == NULL) { pr_log_debug(DEBUG0, "inappropriate log file: %s", lf); destroy_pool(tmp_pool); errno = EINVAL; return -1; } /* Set the path separator to zero, in order to obtain the directory * name, so that checks of the directory may be made. */ *tmp = '\0'; if (stat(lf, &st) < 0) { int xerrno = errno; pr_log_debug(DEBUG0, "error: unable to stat() %s: %s", lf, strerror(errno)); destroy_pool(tmp_pool); errno = xerrno; return -1; } /* The path must be in a valid directory */ if (!S_ISDIR(st.st_mode)) { pr_log_debug(DEBUG0, "error: %s is not a directory", lf); destroy_pool(tmp_pool); errno = ENOTDIR; return -1; } /* Do not log to world-writeable directories */ if (st.st_mode & S_IWOTH) { pr_log_pri(PR_LOG_NOTICE, "error: %s is a world writeable directory", lf); destroy_pool(tmp_pool); return PR_LOG_WRITABLE_DIR; } /* Restore the path separator so that checks on the file itself may be * done. */ *tmp = '/'; allow_log_symlinks = get_param_ptr(main_server->conf, "AllowLogSymlinks", FALSE); if (allow_log_symlinks == NULL || *allow_log_symlinks == FALSE) { int flags = O_APPEND|O_CREAT|O_WRONLY; #ifdef PR_USE_NONBLOCKING_LOG_OPEN /* Use the O_NONBLOCK flag when opening log files, as they might be * FIFOs whose other end is not currently running; we do not want to * block indefinitely in such cases. */ flags |= O_NONBLOCK; #endif /* PR_USE_NONBLOCKING_LOG_OPEN */ #ifdef O_NOFOLLOW /* On systems that support the O_NOFOLLOW flag (e.g. Linux and FreeBSD), * use it so that the path being opened, if it is a symlink, is not * followed. */ flags |= O_NOFOLLOW; #elif defined(SOLARIS2) /* Solaris doesn't support the O_NOFOLLOW flag. Instead, in their * wisdom (hah!), Solaris decided that if the given path is a symlink * and the flags O_CREAT and O_EXCL are set, the link is not followed. * Right. The problem here is the case where the path is not a symlink; * using O_CREAT|O_EXCL will then cause the open() to fail if the * file already exists. */ flags |= O_EXCL; #endif /* O_NOFOLLOW or SOLARIS2 */ *log_fd = open(lf, flags, log_mode); if (*log_fd < 0) { if (errno != EEXIST) { destroy_pool(tmp_pool); /* More portability fun: Linux likes to report ELOOP if O_NOFOLLOW * is used to open a symlink file; FreeBSD likes to return EMLINK. * Both would lead to rather misleading error messages being * logged. Catch these errnos, and return the value that properly * informs the caller that the given path was an illegal symlink. */ switch (errno) { #ifdef ELOOP case ELOOP: return PR_LOG_SYMLINK; #endif /* ELOOP */ #ifdef EMLINK case EMLINK: return PR_LOG_SYMLINK; #endif /* EMLINK */ } return -1; } else { #if defined(SOLARIS2) /* On Solaris, because of the stupid multiplexing of O_CREAT and * O_EXCL to get open() not to follow a symlink, it's possible that * the path already exists. Now, we'll try to open() without * O_EXCL, then lstat() the path to see if this pre-existing file is * a symlink or a regular file. * * Note that because this check cannot be done atomically on Solaris, * the possibility of a race condition/symlink attack still exists. * Solaris doesn't provide a good way around this situation. */ flags &= ~O_EXCL; *log_fd = open(lf, flags, log_mode); if (*log_fd < 0) { destroy_pool(tmp_pool); return -1; } /* The race condition on Solaris is here, between the open() call * above and the lstat() call below... */ if (lstat(lf, &st) != -1) have_stat = TRUE; #else destroy_pool(tmp_pool); return -1; #endif /* SOLARIS2 */ } } /* Stat the file using the descriptor, not the path */ if (!have_stat && fstat(*log_fd, &st) != -1) have_stat = TRUE; if (!have_stat || S_ISLNK(st.st_mode)) { pr_log_debug(DEBUG0, !have_stat ? "error: unable to stat %s" : "error: %s is a symbolic link", lf); close(*log_fd); *log_fd = -1; destroy_pool(tmp_pool); return PR_LOG_SYMLINK; } } else { int flags = O_CREAT|O_APPEND|O_WRONLY; #ifdef PR_USE_NONBLOCKING_LOG_OPEN /* Use the O_NONBLOCK flag when opening log files, as they might be * FIFOs whose other end is not currently running; we do not want to * block indefinitely in such cases. */ flags |= O_NONBLOCK; #endif /* PR_USE_NONBLOCKING_LOG_OPEN */ *log_fd = open(lf, flags, log_mode); if (*log_fd < 0) { destroy_pool(tmp_pool); return -1; } } /* Find a usable fd for the just-opened log fd. */ if (*log_fd <= STDERR_FILENO) { res = pr_fs_get_usable_fd(*log_fd); if (res < 0) { pr_log_debug(DEBUG0, "warning: unable to find good fd for logfd %d: %s", *log_fd, strerror(errno)); } else { close(*log_fd); *log_fd = res; } } if (fcntl(*log_fd, F_SETFD, FD_CLOEXEC) < 0) { pr_log_pri(PR_LOG_WARNING, "unable to set CLO_EXEC on log fd %d: %s", *log_fd, strerror(errno)); } #ifdef PR_USE_NONBLOCKING_LOG_OPEN /* Return the fd to blocking mode. */ fd_set_block(*log_fd); #endif /* PR_USE_NONBLOCKING_LOG_OPEN */ destroy_pool(tmp_pool); return 0; } int pr_log_vwritefile(int logfd, const char *ident, const char *fmt, va_list msg) { char buf[PR_TUNABLE_BUFFER_SIZE] = {'\0'}; struct timeval now; struct tm *tm = NULL; size_t buflen, len; unsigned long millis; if (logfd < 0) { errno = EINVAL; return -1; } gettimeofday(&now, NULL); tm = pr_localtime(NULL, (const time_t *) &(now.tv_sec)); if (tm == NULL) { return -1; } /* Prepend the timestamp */ len = strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm); buflen = len; buf[sizeof(buf)-1] = '\0'; /* Convert microsecs to millisecs. */ millis = now.tv_usec / 1000; len = snprintf(buf + buflen, sizeof(buf) - len, ",%03lu ", millis); buflen += len; /* Prepend a small header */ len = snprintf(buf + buflen, sizeof(buf) - buflen, "%s[%u]: ", ident, (unsigned int) (session.pid ? session.pid : getpid())); buflen += len; buf[sizeof(buf)-1] = '\0'; /* Affix the message */ len = vsnprintf(buf + buflen, sizeof(buf) - buflen - 1, fmt, msg); buflen += len; buf[sizeof(buf)-1] = '\0'; if (buflen < (sizeof(buf) - 1)) { buf[buflen++] = '\n'; } else { buf[sizeof(buf)-2] = '\n'; buflen++; } pr_log_event_generate(PR_LOG_TYPE_UNSPEC, logfd, -1, buf, buflen); while (write(logfd, buf, buflen) < 0) { if (errno == EINTR) { pr_signals_handle(); continue; } return -1; } return 0; } int pr_log_writefile(int logfd, const char *ident, const char *fmt, ...) { va_list msg; int res; if (logfd < 0) { errno = EINVAL; return -1; } va_start(msg, fmt); res = pr_log_vwritefile(logfd, ident, fmt, msg); va_end(msg); return res; } int log_opensyslog(const char *fn) { int res = 0; if (set_facility != -1) facility = set_facility; if (fn) { memset(systemlog_fn, '\0', sizeof(systemlog_fn)); sstrncpy(systemlog_fn, fn, sizeof(systemlog_fn)); } if (!*systemlog_fn) { /* The child may have inherited a valid socket from the parent. */ pr_closelog(syslog_sockfd); syslog_sockfd = pr_openlog("proftpd", LOG_NDELAY|LOG_PID, facility); if (syslog_sockfd < 0) return -1; /* Find a usable fd for the just-opened socket fd. */ if (syslog_sockfd <= STDERR_FILENO) { res = pr_fs_get_usable_fd(syslog_sockfd); if (res > 0) { (void) close(syslog_sockfd); syslog_sockfd = res; } } fcntl(syslog_sockfd, F_SETFD, FD_CLOEXEC); systemlog_fd = -1; } else if ((res = pr_log_openfile(systemlog_fn, &systemlog_fd, PR_LOG_SYSTEM_MODE)) < 0) { memset(systemlog_fn, '\0', sizeof(systemlog_fn)); return res; } syslog_open = TRUE; return 0; } void log_closesyslog(void) { (void) close(systemlog_fd); systemlog_fd = -1; (void) pr_closelog(syslog_sockfd); syslog_sockfd = -1; syslog_open = FALSE; } int log_getfacility(void) { return set_facility; } void log_setfacility(int f) { set_facility = f; } void log_discard(void) { syslog_discard = TRUE; } static void log_write(int priority, int f, char *s, int discard) { unsigned int *max_priority = NULL; char serverinfo[PR_TUNABLE_BUFFER_SIZE] = {'\0'}; memset(serverinfo, '\0', sizeof(serverinfo)); if (main_server && main_server->ServerFQDN) { pr_netaddr_t *remote_addr = pr_netaddr_get_sess_remote_addr(); const char *remote_name = pr_netaddr_get_sess_remote_name(); snprintf(serverinfo, sizeof(serverinfo)-1, "%s", main_server->ServerFQDN); serverinfo[sizeof(serverinfo)-1] = '\0'; if (remote_addr && remote_name) { size_t serverinfo_len; serverinfo_len = strlen(serverinfo); snprintf(serverinfo + serverinfo_len, sizeof(serverinfo) - serverinfo_len, " (%s[%s])", remote_name, pr_netaddr_get_ipstr(remote_addr)); serverinfo[sizeof(serverinfo)-1] = '\0'; } } if (!discard && (logstderr || !main_server)) { char buf[LOGBUFFER_SIZE] = {'\0'}; size_t buflen, len; struct timeval now; struct tm *tm = NULL; unsigned long millis; gettimeofday(&now, NULL); tm = pr_localtime(NULL, (const time_t *) &(now.tv_sec)); if (tm == NULL) { return; } len = strftime(buf, sizeof(buf)-1, "%Y-%m-%d %H:%M:%S", tm); buflen = len; buf[sizeof(buf)-1] = '\0'; /* Convert microsecs to millisecs. */ millis = now.tv_usec / 1000; len = snprintf(buf + buflen, sizeof(buf) - len, ",%03lu ", millis); buflen += len; buf[sizeof(buf)-1] = '\0'; if (*serverinfo) { len = snprintf(buf + buflen, sizeof(buf) - buflen, "%s proftpd[%u] %s: %s\n", systemlog_host, (unsigned int) (session.pid ? session.pid : getpid()), serverinfo, s); } else { len = snprintf(buf + buflen, sizeof(buf) - buflen, "%s proftpd[%u]: %s\n", systemlog_host, (unsigned int) (session.pid ? session.pid : getpid()), s); } buflen += len; buf[sizeof(buf)-1] = '\0'; pr_log_event_generate(PR_LOG_TYPE_SYSTEMLOG, STDERR_FILENO, priority, buf, buflen); fprintf(stderr, "%s", buf); return; } if (syslog_discard) { /* Only return now if we don't have any log listeners. */ if (pr_log_event_listening(PR_LOG_TYPE_SYSLOG) <= 0 && pr_log_event_listening(PR_LOG_TYPE_SYSTEMLOG) <= 0) { return; } } max_priority = get_param_ptr(main_server->conf, "SyslogLevel", FALSE); if (max_priority != NULL && priority > *max_priority) { /* Only return now if we don't have any log listeners. */ if (pr_log_event_listening(PR_LOG_TYPE_SYSLOG) <= 0 && pr_log_event_listening(PR_LOG_TYPE_SYSTEMLOG) <= 0) { return; } } if (systemlog_fd != -1) { char buf[LOGBUFFER_SIZE] = {'\0'}; size_t buflen, len; struct timeval now; struct tm *tm; unsigned long millis; gettimeofday(&now, NULL); tm = pr_localtime(NULL, (const time_t *) &(now.tv_sec)); if (tm == NULL) { return; } len = strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm); buflen = len; buf[sizeof(buf) - 1] = '\0'; /* Convert microsecs to millisecs. */ millis = now.tv_usec / 1000; len = snprintf(buf + buflen, sizeof(buf) - len, ",%03lu ", millis); buflen += len; buf[sizeof(buf) - 1] = '\0'; if (*serverinfo) { len = snprintf(buf + buflen, sizeof(buf) - buflen, "%s proftpd[%u] %s: %s\n", systemlog_host, (unsigned int) (session.pid ? session.pid : getpid()), serverinfo, s); } else { len = snprintf(buf + buflen, sizeof(buf) - buflen, "%s proftpd[%u]: %s\n", systemlog_host, (unsigned int) (session.pid ? session.pid : getpid()), s); } buflen += len; buf[sizeof(buf)-1] = '\0'; pr_log_event_generate(PR_LOG_TYPE_SYSTEMLOG, systemlog_fd, priority, buf, buflen); /* Now we need to enforce the discard, syslog_discard and SyslogLevel * filtering. */ if (discard) { return; } if (syslog_discard) { return; } if (max_priority != NULL && priority > *max_priority) { return; } while (write(systemlog_fd, buf, buflen) < 0) { if (errno == EINTR) { pr_signals_handle(); continue; } return; } return; } pr_log_event_generate(PR_LOG_TYPE_SYSLOG, syslog_sockfd, priority, s, strlen(s)); if (set_facility != -1) f = set_facility; if (!syslog_open) { syslog_sockfd = pr_openlog("proftpd", LOG_NDELAY|LOG_PID, f); syslog_open = TRUE; } else if (f != facility) { /* If this message is to be sent to a different log facility than a * default one (or the facility configured via SyslogFacility), then * OR in the facility with the priority value, as per the syslog(3) * docs. */ priority |= f; } if (*serverinfo) { pr_syslog(syslog_sockfd, priority, "%s - %s\n", serverinfo, s); } else { pr_syslog(syslog_sockfd, priority, "%s\n", s); } } void pr_log_pri(int priority, const char *fmt, ...) { char buf[LOGBUFFER_SIZE] = {'\0'}; va_list msg; va_start(msg, fmt); vsnprintf(buf, sizeof(buf), fmt, msg); va_end(msg); /* Always make sure the buffer is NUL-terminated. */ buf[sizeof(buf) - 1] = '\0'; log_write(priority, facility, buf, FALSE); } /* Like pr_log_pri(), but sends the log entry in the LOG_AUTHPRIV * facility (presumably it doesn't need to be seen by everyone). */ void pr_log_auth(int priority, const char *fmt, ...) { char buf[LOGBUFFER_SIZE] = {'\0'}; va_list msg; va_start(msg, fmt); vsnprintf(buf, sizeof(buf), fmt, msg); va_end(msg); /* Always make sure the buffer is NUL-terminated. */ buf[sizeof(buf) - 1] = '\0'; log_write(priority, LOG_AUTHPRIV, buf, FALSE); } /* Disable logging to stderr, should be done right before forking * or disassociation from controlling tty. After disabling stderr * logging, all messages go to syslog. */ void log_stderr(int bool) { logstderr = bool; } /* Set the debug logging level, see log.h for constants. Higher * numbers mean print more, DEBUG0 (0) == print no debugging log * (default) */ int pr_log_setdebuglevel(int level) { int old_level = debug_level; debug_level = level; return old_level; } /* Convert a string into the matching syslog level value. Return -1 * if no matching level is found. */ int pr_log_str2sysloglevel(const char *name) { if (strncasecmp(name, "emerg", 6) == 0) { return PR_LOG_EMERG; } else if (strncasecmp(name, "alert", 6) == 0) { return PR_LOG_ALERT; } else if (strncasecmp(name, "crit", 5) == 0) { return PR_LOG_CRIT; } else if (strncasecmp(name, "error", 6) == 0) { return PR_LOG_ERR; } else if (strncasecmp(name, "warn", 5) == 0) { return PR_LOG_WARNING; } else if (strncasecmp(name, "notice", 7) == 0) { return PR_LOG_NOTICE; } else if (strncasecmp(name, "info", 5) == 0) { return PR_LOG_INFO; } else if (strncasecmp(name, "debug", 6) == 0) { return PR_LOG_DEBUG; } errno = ENOENT; return -1; } void pr_log_debug(int level, const char *fmt, ...) { char buf[LOGBUFFER_SIZE] = {'\0'}; va_list msg; int discard = FALSE; if (debug_level < level) { discard = TRUE; if (pr_log_event_listening(PR_LOG_TYPE_SYSLOG) <= 0 && pr_log_event_listening(PR_LOG_TYPE_SYSTEMLOG) <= 0) { return; } } if (fmt == NULL) return; memset(buf, '\0', sizeof(buf)); va_start(msg, fmt); vsnprintf(buf, sizeof(buf), fmt, msg); va_end(msg); /* Always make sure the buffer is NUL-terminated. */ buf[sizeof(buf) - 1] = '\0'; log_write(PR_LOG_DEBUG, facility, buf, discard); } static const char *get_log_event_name(unsigned int log_type) { const char *event_name = NULL; switch (log_type) { case PR_LOG_TYPE_UNSPEC: event_name = PR_LOG_NAME_UNSPEC; break; case PR_LOG_TYPE_XFERLOG: event_name = PR_LOG_NAME_XFERLOG; break; case PR_LOG_TYPE_SYSLOG: event_name = PR_LOG_NAME_SYSLOG; break; case PR_LOG_TYPE_SYSTEMLOG: event_name = PR_LOG_NAME_SYSTEMLOG; break; case PR_LOG_TYPE_EXTLOG: event_name = PR_LOG_NAME_EXTLOG; break; case PR_LOG_TYPE_TRACELOG: event_name = PR_LOG_NAME_TRACELOG; break; default: errno = EINVAL; return NULL; } return event_name; } int pr_log_event_generate(unsigned int log_type, int log_fd, int log_level, const char *log_msg, size_t log_msglen) { const char *event_name; pr_log_event_t le; if (log_msg == NULL || log_msglen == 0) { errno = EINVAL; return -1; } if (pr_log_event_listening(log_type) <= 0) { errno = ENOENT; return -1; } event_name = get_log_event_name(log_type); memset(&le, 0, sizeof(le)); le.log_type = log_type; le.log_fd = log_fd; le.log_level = log_level; le.log_msg = log_msg; le.log_msglen = log_msglen; pr_event_generate(event_name, &le); return 0; } int pr_log_event_listening(unsigned int log_type) { const char *event_name; int res; event_name = get_log_event_name(log_type); if (event_name == NULL) { return FALSE; } res = pr_event_listening(event_name); if (res <= 0) { return FALSE; } return TRUE; } void init_log(void) { char buf[256]; memset(buf, '\0', sizeof(buf)); if (gethostname(buf, sizeof(buf)) == -1) sstrncpy(buf, "localhost", sizeof(buf)); sstrncpy(systemlog_host, (char *) pr_netaddr_validate_dns_str(buf), sizeof(systemlog_host)); memset(systemlog_fn, '\0', sizeof(systemlog_fn)); log_closesyslog(); } proftpd-dfsg-1.3.5~rc3/src/str.c0000644000175000017500000003135312107534404016315 0ustar frankiefrankie/* * ProFTPD - FTP server daemon * Copyright (c) 2008-2013 The ProFTPD Project team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * As a special exemption, Public Flood Software/MacGyver aka Habeeb J. Dihu * and other respective copyright holders give permission to link this program * with OpenSSL, and distribute the resulting executable, without including * the source code for OpenSSL in the source distribution. */ /* String manipulation functions * $Id: str.c,v 1.16 2013/02/15 22:39:00 castaglia Exp $ */ #include "conf.h" /* Maximum number of matches that we will do in a given string. */ #define PR_STR_MAX_MATCHES 128 static char *str_vreplace(pool *p, unsigned int max_replaces, char *s, va_list args) { char *m, *r, *src, *cp; char *matches[PR_STR_MAX_MATCHES+1], *replaces[PR_STR_MAX_MATCHES+1]; char buf[PR_TUNABLE_PATH_MAX] = {'\0'}, *pbuf = NULL; size_t nmatches = 0, rlen = 0; int blen = 0; src = s; cp = buf; *cp = '\0'; memset(matches, 0, sizeof(matches)); memset(replaces, 0, sizeof(replaces)); blen = strlen(src) + 1; while ((m = va_arg(args, char *)) != NULL && nmatches < PR_STR_MAX_MATCHES) { char *tmp = NULL; int count = 0; r = va_arg(args, char *); if (r == NULL) { break; } /* Increase the length of the needed buffer by the difference between * the given match and replacement strings, multiplied by the number * of times the match string occurs in the source string. */ tmp = strstr(s, m); while (tmp) { pr_signals_handle(); count++; if (count > max_replaces) { errno = E2BIG; return NULL; } /* Be sure to increment the pointer returned by strstr(3), to * advance past the beginning of the substring for which we are * looking. Otherwise, we just loop endlessly, seeing the same * value for tmp over and over. */ tmp += strlen(m); tmp = strstr(tmp, m); } /* We are only concerned about match/replacement strings that actually * occur in the given string. */ if (count) { blen += count * (strlen(r) - strlen(m)); if (blen < 0) { /* Integer overflow. In order to overflow this, somebody must be * doing something very strange. The possibility still exists that * we might not catch this overflow in extreme corner cases, but * massive amounts of data (gigabytes) would need to be in s to * trigger this, easily larger than any buffer we might use. */ return s; } matches[nmatches] = m; replaces[nmatches++] = r; } } /* If there are no matches, then there is nothing to replace. */ if (nmatches == 0) { return s; } /* Try to handle large buffer situations (i.e. escaping of PR_TUNABLE_PATH_MAX * (>2048) correctly, but do not allow very big buffer sizes, that may * be dangerous (BUFSIZ may be defined in stdio.h) in some library * functions. */ #ifndef BUFSIZ # define BUFSIZ 8192 #endif if (blen >= BUFSIZ) { errno = ENOSPC; return NULL; } cp = pbuf = (char *) pcalloc(p, ++blen); while (*src) { char **mptr, **rptr; for (mptr = matches, rptr = replaces; *mptr; mptr++, rptr++) { size_t mlen; mlen = strlen(*mptr); rlen = strlen(*rptr); if (strncmp(src, *mptr, mlen) == 0) { sstrncpy(cp, *rptr, blen - strlen(pbuf)); if (((cp + rlen) - pbuf + 1) > blen) { pr_log_pri(PR_LOG_ERR, "WARNING: attempt to overflow internal ProFTPD buffers"); cp = pbuf; cp += (blen - 1); goto done; } else { cp += rlen; } src += mlen; break; } } if (!*mptr) { if ((cp - pbuf + 1) >= blen) { pr_log_pri(PR_LOG_ERR, "WARNING: attempt to overflow internal ProFTPD buffers"); cp = pbuf; cp += (blen - 1); goto done; } *cp++ = *src++; } } done: *cp = '\0'; return pbuf; } char *pr_str_replace(pool *p, unsigned int max_replaces, char *s, ...) { va_list args; char *res = NULL; if (p == NULL || s == NULL || max_replaces == 0) { errno = EINVAL; return NULL; } va_start(args, s); res = str_vreplace(p, max_replaces, s, args); va_end(args); return res; } char *sreplace(pool *p, char *s, ...) { va_list args; char *res = NULL; if (p == NULL || s == NULL) { errno = EINVAL; return NULL; } va_start(args, s); res = str_vreplace(p, PR_STR_MAX_REPLACEMENTS, s, args); va_end(args); if (res == NULL && errno == E2BIG) { /* For backward compatible behavior. */ return s; } return res; } /* "safe" strcat, saves room for NUL at end of dst, and refuses to copy more * than "n" bytes. */ char *sstrcat(char *dst, const char *src, size_t n) { register char *d = dst; if (dst == NULL || src == NULL || n == 0) { errno = EINVAL; return NULL; } /* Edge case short ciruit; strlcat(3) doesn't do what I think it should * do for this particular case. */ if (n > 1) { #ifdef HAVE_STRLCAT strlcat(dst, src, n); #else for (; *d && n > 1; d++, n--) ; while (n-- > 1 && *src) { *d++ = *src++; } *d = '\0'; #endif /* HAVE_STRLCAT */ } else { *d = '\0'; } return dst; } char *pstrdup(pool *p, const char *str) { char *res; size_t len; if (!p || !str) { errno = EINVAL; return NULL; } len = strlen(str) + 1; res = palloc(p, len); sstrncpy(res, str, len); return res; } char *pstrndup(pool *p, const char *str, size_t n) { char *res; if (!p || !str) { errno = EINVAL; return NULL; } res = palloc(p, n + 1); sstrncpy(res, str, n + 1); return res; } char *pdircat(pool *p, ...) { char *argp, *res; char last; int count = 0; size_t len = 0; va_list ap; if (p == NULL) { errno = EINVAL; return NULL; } va_start(ap, p); last = 0; while ((res = va_arg(ap, char *)) != NULL) { /* If the first argument is "", we have to account for a leading / * which must be added. */ if (!count++ && !*res) len++; else if (last && last != '/' && *res != '/') len++; else if (last && last == '/' && *res == '/') len--; len += strlen(res); last = (*res ? res[strlen(res) - 1] : 0); } va_end(ap); res = (char *) pcalloc(p, len + 1); va_start(ap, p); last = 0; while ((argp = va_arg(ap, char *)) != NULL) { if (last && last == '/' && *argp == '/') argp++; else if (last && last != '/' && *argp != '/') sstrcat(res, "/", len + 1); sstrcat(res, argp, len + 1); last = (*res ? res[strlen(res) - 1] : 0); } va_end(ap); return res; } char *pstrcat(pool *p, ...) { char *argp, *res; size_t len = 0; va_list ap; if (p == NULL) { errno = EINVAL; return NULL; } va_start(ap, p); while ((res = va_arg(ap, char *)) != NULL) len += strlen(res); va_end(ap); res = pcalloc(p, len + 1); va_start(ap, p); while ((argp = va_arg(ap, char *)) != NULL) sstrcat(res, argp, len + 1); va_end(ap); return res; } char *pr_str_strip(pool *p, char *str) { char c, *dupstr, *start, *finish; if (!p || !str) { errno = EINVAL; return NULL; } /* First, find the non-whitespace start of the given string */ for (start = str; PR_ISSPACE(*start); start++); /* Now, find the non-whitespace end of the given string */ for (finish = &str[strlen(str)-1]; PR_ISSPACE(*finish); finish--); /* finish is now pointing to a non-whitespace character. So advance one * character forward, and set that to NUL. */ c = *++finish; *finish = '\0'; /* The space-stripped string is, then, everything from start to finish. */ dupstr = pstrdup(p, start); /* Restore the given string buffer contents. */ *finish = c; return dupstr; } char *pr_str_strip_end(char *s, char *ch) { size_t len; if (s == NULL || ch == NULL) { errno = EINVAL; return NULL; } len = strlen(s); while (len && strchr(ch, *(s+len - 1))) { pr_signals_handle(); *(s+len - 1) = '\0'; len--; } return s; } int pr_str_get_nbytes(const char *str, const char *units, off_t *nbytes) { off_t sz; char *ptr = NULL; float factor = 0.0; if (str == NULL) { errno = EINVAL; return -1; } /* No negative numbers. */ if (*str == '-') { errno = EINVAL; return -1; } if (units == NULL || *units == '\0') { factor = 1.0; } else if (strncasecmp(units, "KB", 3) == 0) { factor = 1024.0; } else if (strncasecmp(units, "MB", 3) == 0) { factor = 1024.0 * 1024.0; } else if (strncasecmp(units, "GB", 3) == 0) { factor = 1024.0 * 1024.0 * 1024.0; } else if (strncasecmp(units, "TB", 3) == 0) { factor = 1024.0 * 1024.0 * 1024.0 * 1024.0; } else if (strncasecmp(units, "B", 2) == 0) { factor = 1.0; } else { errno = EINVAL; return -1; } errno = 0; #ifdef HAVE_STRTOULL sz = strtoull(str, &ptr, 10); #else sz = strtoul(str, &ptr, 10); #endif /* !HAVE_STRTOULL */ if (errno == ERANGE) { return -1; } if (ptr != NULL && *ptr) { /* Error parsing the given string */ errno = EINVAL; return -1; } /* Don't bother applying the factor if the result will overflow the result. */ #ifdef ULLONG_MAX if (sz > (ULLONG_MAX / factor)) { #else if (sz > (ULONG_MAX / factor)) { #endif /* !ULLONG_MAX */ errno = ERANGE; return -1; } if (nbytes != NULL) { *nbytes = (off_t) (sz * factor); } return 0; } char *pr_str_get_word(char **cp, int flags) { char *res, *dst; char quote_mode = 0; if (cp == NULL || !*cp || !**cp) { errno = EINVAL; return NULL; } if (!(flags & PR_STR_FL_PRESERVE_WHITESPACE)) { while (**cp && PR_ISSPACE(**cp)) { (*cp)++; } } if (!**cp) return NULL; res = dst = *cp; if (!(flags & PR_STR_FL_PRESERVE_COMMENTS)) { /* Stop processing at start of an inline comment. */ if (**cp == '#') return NULL; } if (**cp == '\"') { quote_mode++; (*cp)++; } while (**cp && (quote_mode ? (**cp != '\"') : !PR_ISSPACE(**cp))) { if (**cp == '\\' && quote_mode) { /* Escaped char */ if (*((*cp)+1)) *dst = *(++(*cp)); } *dst++ = **cp; ++(*cp); } if (**cp) (*cp)++; *dst = '\0'; return res; } /* get_token tokenizes a string, increments the src pointer to the next * non-separator in the string. If the src string is empty or NULL, the next * token returned is NULL. */ char *pr_str_get_token(char **s, char *sep) { char *res; if (s == NULL || *s == NULL || **s == '\0' || sep == NULL) { errno = EINVAL; return NULL; } res = *s; while (**s && !strchr(sep, **s)) { (*s)++; } if (**s) *(*s)++ = '\0'; return res; } int pr_str_is_boolean(const char *str) { if (str == NULL) { errno = EINVAL; return -1; } if (strncasecmp(str, "on", 3) == 0) { return TRUE; } if (strncasecmp(str, "off", 4) == 0) { return FALSE; } if (strncasecmp(str, "yes", 4) == 0) { return TRUE; } if (strncasecmp(str, "no", 3) == 0) { return FALSE; } if (strncasecmp(str, "true", 5) == 0) { return TRUE; } if (strncasecmp(str, "false", 6) == 0) { return FALSE; } if (strncasecmp(str, "1", 2) == 0) { return TRUE; } if (strncasecmp(str, "0", 2) == 0) { return FALSE; } errno = EINVAL; return -1; } /* Return true if str contains any of the glob(7) characters. */ int pr_str_is_fnmatch(const char *str) { int have_bracket = 0; while (*str) { switch (*str) { case '?': case '*': return TRUE; case '\\': /* If the next character is NUL, we've reached the end of the string. */ if (*(str+1) == '\0') return FALSE; /* Skip past the escaped character, i.e. the next character. */ str++; break; case '[': have_bracket++; break; case ']': if (have_bracket) return TRUE; break; default: break; } str++; } return FALSE; } proftpd-dfsg-1.3.5~rc3/src/proftpd.conf.50000644000175000017500000000243712156653650020043 0ustar frankiefrankie.TH proftpd.conf 5 .SH NAME proftpd.conf \- ProFTPD server configuration file .SH DESCRIPTION .PP The .B proftpd(8) daemon reads its configuration file, typically stored in one of the following locations: .LP .I /etc/proftpd.conf .br .I /etc/proftpd/proftpd.conf .br .I /usr/local/etc/proftpd.conf .TP or passed to proftpd with the -c command-line option. .PP The .B proftpd.conf configuration file contains .I directives , one per line. Lines starting with # and empty lines are comments and are ignored. Directives are case-insensitive, whereas values are case-sensitive. Values may be enclosed in double-quotes (") if they contain spaces. .PP The possible directives and their descriptions are described online at .BR http://www.proftpd.org/docs/directives/linked/by-name.html .RE .SH FILES .PD 0 .B /usr/local/sbin/proftpd .br .B /usr/local/etc/proftpd.conf .PP .PD .SH AUTHORS .PP ProFTPD is written and maintained by a number of people, full credits can be found on .BR http://www.proftpd.org/credits.html .PD .SH "SEE ALSO" .BR proftpd(8) .PP Full documentation on ProFTPD, including configuration and FAQs, is available at .BR http://www.proftpd.org/ .PP For help/support, try the ProFTPD mailing lists, detailed on .BR http://www.proftpd.org/lists.html .PP Report bugs at .BR http://bugs.proftpd.org/ proftpd-dfsg-1.3.5~rc3/src/var.c0000644000175000017500000001301212135523310016260 0ustar frankiefrankie/* * ProFTPD - FTP server daemon * Copyright (c) 2004-2013 The ProFTPD Project team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * As a special exemption, The ProFTPD Project team and other respective * copyright holders give permission to link this program with OpenSSL, and * distribute the resulting executable, without including the source code for * OpenSSL in the source distribution. */ /* Variables API implementation * $Id: var.c,v 1.7 2013/04/23 15:20:40 castaglia Exp $ */ #include "conf.h" struct var { int v_type; const char *v_desc; void *v_val; void *v_data; size_t v_datasz; }; static pool *var_pool = NULL; static pr_table_t *var_tab = NULL; typedef const char *(*var_vstr_cb)(void *, size_t); /* Public API */ int pr_var_delete(const char *name) { if (!var_tab) { errno = EPERM; return -1; } if (!name) { errno = EINVAL; return -1; } return pr_table_remove(var_tab, name, NULL) ? 0 : -1; } int pr_var_exists(const char *name) { if (!var_tab) { errno = EPERM; return -1; } if (!name) { errno = EINVAL; return -1; } return pr_table_exists(var_tab, name) > 0 ? TRUE : FALSE; } const char *pr_var_get(const char *name) { struct var *v; if (!var_tab) { errno = EPERM; return NULL; } if (!name) { errno = EINVAL; return NULL; } v = pr_table_get(var_tab, name, NULL); if (!v) return NULL; switch (v->v_type) { case PR_VAR_TYPE_STR: return (const char *) v->v_val; break; case PR_VAR_TYPE_FUNC: return ((var_vstr_cb) v->v_val)(v->v_data, v->v_datasz); break; default: /* Pass through to the error case. */ ; } errno = EINVAL; return NULL; } const char *pr_var_next(const char **desc) { const char *name; struct var *v; if (!var_tab) { errno = EPERM; return NULL; } name = pr_table_next(var_tab); if (!name) return NULL; v = pr_table_get(var_tab, name, NULL); if (v && desc) *desc = v->v_desc; return name; } void pr_var_rewind(void) { if (var_tab) pr_table_rewind(var_tab); } int pr_var_set(pool *p, const char *name, const char *desc, int type, void *val, void *data, size_t datasz) { struct var *v; if (var_tab == NULL) { errno = EPERM; return -1; } if (p == NULL || name == NULL || val == NULL) { errno = EINVAL; return -1; } /* The length of the key must be greater than 3 characters (for "%{}"). */ if (strlen(name) < 4) { errno = EINVAL; return -1; } /* Specifying data, but no length for that data, is an error. */ if (data != NULL && datasz == 0) { errno = EINVAL; return -1; } /* Specifying no data, but providing a non-zero length for that data, is an * error. */ if (data == NULL && datasz > 0) { errno = EINVAL; return -1; } /* Variable names MUST start with '%{', and end in '}'. */ if (strncmp(name, "%{", 2) != 0 || name[strlen(name)-1] != '}') { errno = EINVAL; return -1; } /* Remove any previously registered value for this name. For names whose * values change rapidly (e.g. session.xfer.total_bytes), a callback * function should be used, rather than always setting the same name as an * update; using a callback avoids the memory consumption that setting does * (set always allocates a new struct var *). */ (void) pr_var_delete(name); /* Note: if var_pool was used for allocating the struct var *, rather * than the given pool, then deleting an entry would not necessarily * lead to such memory consumption (assuming it would even be a problem). * However, if this was the case, then a churn counter would be needed, * and var_pool would need to be churned occasionally to limit memory * growth. */ switch (type) { case PR_VAR_TYPE_STR: v = pcalloc(p, sizeof(struct var)); if (desc) v->v_desc = (const char *) pstrdup(p, desc); v->v_type = PR_VAR_TYPE_STR; v->v_val = pstrdup(p, (char *) val); v->v_datasz = strlen((char *) val); break; case PR_VAR_TYPE_FUNC: v = pcalloc(p, sizeof(struct var)); if (desc) v->v_desc = (const char *) pstrdup(p, desc); v->v_type = PR_VAR_TYPE_FUNC; v->v_val = val; if (data) { v->v_data = data; v->v_datasz = datasz; } break; default: errno = EINVAL; return -1; } return pr_table_add(var_tab, name, v, sizeof(struct var)); } int var_init(void) { if (!var_pool) { var_pool = make_sub_pool(permanent_pool); pr_pool_tag(var_pool, "Variables Pool"); } if (!var_tab) var_tab = pr_table_alloc(var_pool, 0); return 0; } int var_free(void) { if (var_pool) { if (var_tab) { pr_table_empty(var_tab); pr_table_free(var_tab); } destroy_pool(var_pool); var_pool = NULL; var_tab = NULL; } return 0; } proftpd-dfsg-1.3.5~rc3/src/response.c0000644000175000017500000002356711621547526017364 0ustar frankiefrankie/* * ProFTPD - FTP server daemon * Copyright (c) 2001-2011 The ProFTPD Project team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * As a special exemption, Public Flood Software/MacGyver aka Habeeb J. Dihu * and other respective copyright holders give permission to link this program * with OpenSSL, and distribute the resulting executable, without including * the source code for OpenSSL in the source distribution. */ /* Command response routines * $Id: response.c,v 1.22 2011/08/13 19:24:06 castaglia Exp $ */ #include "conf.h" pr_response_t *resp_list = NULL, *resp_err_list = NULL; static int resp_blocked = FALSE; static pool *resp_pool = NULL; static char resp_buf[PR_RESPONSE_BUFFER_SIZE] = {'\0'}; static char *resp_last_response_code = NULL; static char *resp_last_response_msg = NULL; static char *(*resp_handler_cb)(pool *, const char *, ...) = NULL; static const char *trace_channel = "response"; #define RESPONSE_WRITE_NUM_STR(strm, fmt, numeric, msg) \ pr_trace_msg(trace_channel, 1, (fmt), (numeric), (msg)); \ if (resp_handler_cb) \ pr_netio_printf((strm), "%s", resp_handler_cb(resp_pool, (fmt), (numeric), \ (msg))); \ else \ pr_netio_printf((strm), (fmt), (numeric), (msg)); #define RESPONSE_WRITE_STR(strm, fmt, msg) \ pr_trace_msg(trace_channel, 1, (fmt), (msg)); \ if (resp_handler_cb) \ pr_netio_printf((strm), "%s", resp_handler_cb(resp_pool, (fmt), (msg))); \ else \ pr_netio_printf((strm), (fmt), (msg)); #define RESPONSE_WRITE_STR_ASYNC(strm, fmt, msg) \ pr_trace_msg(trace_channel, 1, pstrcat(session.pool, "async: ", (fmt), NULL), \ (msg)); \ if (resp_handler_cb) \ pr_netio_printf_async((strm), "%s", resp_handler_cb(resp_pool, (fmt), \ (msg))); \ else \ pr_netio_printf_async((strm), (fmt), (msg)); pool *pr_response_get_pool(void) { return resp_pool; } static void reset_last_response(void) { resp_last_response_code = NULL; resp_last_response_msg = NULL; } void pr_response_set_pool(pool *p) { resp_pool = p; /* Copy any old "last" values out of the new pool. */ if (resp_last_response_code != NULL) { char *tmp; tmp = resp_last_response_code; resp_last_response_code = pstrdup(p, tmp); } if (resp_last_response_msg != NULL) { char *tmp; tmp = resp_last_response_msg; resp_last_response_msg = pstrdup(p, tmp); } } int pr_response_get_last(pool *p, char **response_code, char **response_msg) { if (p == NULL) { errno = EINVAL; return -1; } if (response_code == NULL && response_msg == NULL) { errno = EINVAL; return -1; } if (response_code != NULL) { *response_code = pstrdup(p, resp_last_response_code); } if (response_msg != NULL) { *response_msg = pstrdup(p, resp_last_response_msg); } return 0; } void pr_response_register_handler(char *(*handler_cb)(pool *, const char *, ...)) { resp_handler_cb = handler_cb; } int pr_response_block(int bool) { if (bool == TRUE || bool == FALSE) { resp_blocked = bool; return 0; } errno = EINVAL; return -1; } void pr_response_clear(pr_response_t **head) { reset_last_response(); *head = NULL; } void pr_response_flush(pr_response_t **head) { unsigned char ml = FALSE; char *last_numeric = NULL; pr_response_t *resp = NULL; if (resp_blocked) { return; } if (session.c == NULL) { /* Not sure what happened to the control connection, but since it's gone, * there's no need to flush any messages. */ return; } for (resp = *head; resp; resp = resp->next) { if (ml) { /* Look for end of multiline */ if (resp->next == NULL || (resp->num != NULL && strcmp(resp->num, last_numeric) != 0)) { RESPONSE_WRITE_NUM_STR(session.c->outstrm, "%s %s\r\n", last_numeric, resp->msg) ml = FALSE; } else { /* RFC2228's multiline responses are required for protected sessions. */ if (session.multiline_rfc2228 || session.sp_flags) { RESPONSE_WRITE_NUM_STR(session.c->outstrm, "%s-%s\r\n", last_numeric, resp->msg) } else { RESPONSE_WRITE_STR(session.c->outstrm, " %s\r\n" , resp->msg) } } } else { /* Look for start of multiline */ if (resp->next && (resp->next->num == NULL || strcmp(resp->num, resp->next->num) == 0)) { RESPONSE_WRITE_NUM_STR(session.c->outstrm, "%s-%s\r\n", resp->num, resp->msg) ml = TRUE; last_numeric = resp->num; } else { RESPONSE_WRITE_NUM_STR(session.c->outstrm, "%s %s\r\n", resp->num, resp->msg) } } } pr_response_clear(head); } void pr_response_add_err(const char *numeric, const char *fmt, ...) { pr_response_t *resp = NULL, **head = NULL; va_list msg; va_start(msg, fmt); vsnprintf(resp_buf, sizeof(resp_buf), fmt, msg); va_end(msg); resp_buf[sizeof(resp_buf) - 1] = '\0'; resp = (pr_response_t *) pcalloc(resp_pool, sizeof(pr_response_t)); resp->num = (numeric ? pstrdup(resp_pool, numeric) : NULL); resp->msg = pstrdup(resp_pool, resp_buf); resp_last_response_code = pstrdup(resp_pool, resp->num); resp_last_response_msg = pstrdup(resp_pool, resp->msg); pr_trace_msg(trace_channel, 7, "error response added to pending list: %s %s", resp->num ? resp->num : "(null)", resp->msg); if (numeric != NULL) { pr_response_t *iter; /* Handle the case where the first messages in the list may have R_DUP * for the numeric response code (i.e. NULL). To do this, we scan the * list for the first non-null response code, and use that for any R_DUP * messages. */ for (iter = resp_err_list; iter; iter = iter->next) { if (iter->num == NULL) { iter->num = resp->num; } } } for (head = &resp_err_list; *head && (!numeric || !(*head)->num || strcmp((*head)->num, numeric) <= 0) && !(numeric && !(*head)->num && head == &resp_err_list); head = &(*head)->next); resp->next = *head; *head = resp; } void pr_response_add(const char *numeric, const char *fmt, ...) { pr_response_t *resp = NULL, **head = NULL; va_list msg; va_start(msg, fmt); vsnprintf(resp_buf, sizeof(resp_buf), fmt, msg); va_end(msg); resp_buf[sizeof(resp_buf) - 1] = '\0'; resp = (pr_response_t *) pcalloc(resp_pool, sizeof(pr_response_t)); resp->num = (numeric ? pstrdup(resp_pool, numeric) : NULL); resp->msg = pstrdup(resp_pool, resp_buf); resp_last_response_code = pstrdup(resp_pool, resp->num); resp_last_response_msg = pstrdup(resp_pool, resp->msg); pr_trace_msg(trace_channel, 7, "response added to pending list: %s %s", resp->num ? resp->num : "(null)", resp->msg); if (numeric != NULL) { pr_response_t *iter; /* Handle the case where the first messages in the list may have R_DUP * for the numeric response code (i.e. NULL). To do this, we scan the * list for the first non-null response code, and use that for any R_DUP * messages. */ for (iter = resp_list; iter; iter = iter->next) { if (iter->num == NULL) { iter->num = resp->num; } } } for (head = &resp_list; *head && (!numeric || !(*head)->num || strcmp((*head)->num, numeric) <= 0) && !(numeric && !(*head)->num && head == &resp_list); head = &(*head)->next); resp->next = *head; *head = resp; } void pr_response_send_async(const char *resp_numeric, const char *fmt, ...) { char buf[PR_TUNABLE_BUFFER_SIZE] = {'\0'}; va_list msg; int maxlen; if (resp_blocked) { return; } if (session.c == NULL) { /* Not sure what happened to the control connection, but since it's gone, * there's no need to flush any messages. */ return; } sstrncpy(buf, resp_numeric, sizeof(buf)); sstrcat(buf, " ", sizeof(buf)); maxlen = sizeof(buf) - strlen(buf) - 1; va_start(msg, fmt); vsnprintf(buf + strlen(buf), maxlen, fmt, msg); va_end(msg); buf[sizeof(buf) - 1] = '\0'; resp_last_response_code = pstrdup(resp_pool, resp_numeric); resp_last_response_msg = pstrdup(resp_pool, buf + strlen(resp_numeric) + 1); sstrcat(buf, "\r\n", sizeof(buf)); RESPONSE_WRITE_STR_ASYNC(session.c->outstrm, "%s", buf) } void pr_response_send(const char *resp_numeric, const char *fmt, ...) { va_list msg; if (resp_blocked) { return; } if (session.c == NULL) { /* Not sure what happened to the control connection, but since it's gone, * there's no need to flush any messages. */ return; } va_start(msg, fmt); vsnprintf(resp_buf, sizeof(resp_buf), fmt, msg); va_end(msg); resp_buf[sizeof(resp_buf) - 1] = '\0'; resp_last_response_code = pstrdup(resp_pool, resp_numeric); resp_last_response_msg = pstrdup(resp_pool, resp_buf); RESPONSE_WRITE_NUM_STR(session.c->outstrm, "%s %s\r\n", resp_numeric, resp_buf) } void pr_response_send_raw(const char *fmt, ...) { va_list msg; if (resp_blocked) { return; } if (session.c == NULL) { /* Not sure what happened to the control connection, but since it's gone, * there's no need to flush any messages. */ return; } va_start(msg, fmt); vsnprintf(resp_buf, sizeof(resp_buf), fmt, msg); va_end(msg); resp_buf[sizeof(resp_buf) - 1] = '\0'; RESPONSE_WRITE_STR(session.c->outstrm, "%s\r\n", resp_buf) } proftpd-dfsg-1.3.5~rc3/src/proftpd.8.in0000644000175000017500000001031612135612670017514 0ustar frankiefrankie.TH proftpd 8 "July 2000" .\" Process with .\" groff -man -Tascii proftpd.1 .\" .SH NAME proftpd \- Professional configurable, secure file transfer protocol server .SH SYNOPSIS .B proftpd [ .B \-hlntv ] [ .BI \-c " config\-file" ] [ .BI \-d " debuglevel" ] [ .BI \-p " 0|1" ] .SH DESCRIPTION .B proftpd is the Professional File Transfer Protocol (FTP) server daemon. The server may be invoked by the Internet "super-server" inetd(8) each time a connection to the FTP service is made, or alternatively it can be run as a standalone daemon. .PP .br Each successful and failed ftp(1) session is logged using syslog with a facility of LOG_FTP. Note: LOG_FTP messages are not displayed by syslogd(8) by default, and may have to be enabled in syslogd(8)'s configuration file. .PP When .B proftpd is run in standalone mode and it receives a SIGHUP then it will reread its configuration file. When run in standalone mode without the .B \-n option, the main .B proftpd daemon writes its process ID to .B @LOCALSTATEDIR@/proftpd.pid to make it easy to know which process to SIGHUP. .SH OPTIONS .TP 12 .B \-h,\--help Display a short usage description, including all available options. .TP .B \-n,\--nodaemon Runs the proftpd process in standalone mode (must be configured as such in the configuration file), but does not background the process or disassociate it from the controlling tty. Additionally, all output (log or debug messages) are sent to stderr, rather than the syslog mechanism. Most often used with the \fB-d option\fP for debugging. .TP .B \-q,\--quiet Quiet mode; don't send logging information to standard error when running with the \fB-n option\fP. .TP .B \-v,\--version Displays the version number of ProFTPD to stdout. .TP .BI \-D,\--define " parameter" Sets a configuration \fIparameter\fP which can be used ... sections in the configuration files to conditionally skip or process commands. .TP .BI \-d,\--debug " debuglevel" Sets proftpd's internal debug level (normally 0). The \fIdebuglevel\fP should be an integer value from 0 to 10, with higher numbers producing more debug output. Normally, debug messages are sent to \fBsyslog\fP using the \fBDEBUG\fP facility, however if the \fB-n option\fP is used, all such output is sent to stderr. .TP .BI \-c,\--config " config\-file" Specifies an alternate \fIconfig\-file\fP to be parsed at startup, rather than the default configuration file. The default configuration file is .B @SYSCONFDIR@/proftpd.conf .br .TP .BI \-N,\--nocollision Disables address/port collision checking. .TP .BI \-V,\--settings Displays various compile-time settings and exits. .TP .BI \-S,\--serveraddr Specifies an IP address for the host machine, avoiding an DNS lookup of the hostname .TP .BI \-t,\--configtest Read the configuration file, report any syntax errors, and exit. .TP .BI \-p,\--persistent " 0|1" Disables (0) or enables (1) the default persistent password support, which is determined at configure time for each platform. This option \fBonly\fP affects the default support, it can still be overridden at run-time with the \fBPersistentPasswd\fP directive. .TP .BI \-l,\--list Lists all modules compiled into proftpd. .TP .BI \-4,\--ipv4 Support IPv4 functionality \fBonly\fP, regardless of whether the \fB--enable-ipv6\fP configure option was used. .TP .BI \-6,\--ipv6 Support IPv6 connections and lookup of IPv6 addresses for server DNS names. This is enabled by default, if the \fB--enable-ipv6\fP configure option is used. .SH FILES .PD 0 .B @SBINDIR@/proftpd .br .B @SYSCONFDIR@/proftpd.conf .br .B @BINDIR@/ftpwho .br .B @BINDIR@/ftpcount .br .B @BINDIR@/ftptop .br .B @SBINDIR@/ftpshut .br .B /etc/ftpusers .br .B /var/log/xferlog .br .B @LOCALSTATEDIR@/proftpd.pid .br .B @LOCALSTATEDIR@/proftpd.scoreboard .PD .SH AUTHORS .PP ProFTPD is written and maintained by a number of people, full credits can be found on .BR http://www.proftpd.org/credits.html .PD .SH SEE ALSO .BR proftpd.conf(5), inetd(8), ftp(1), ftpwho(1), ftpcount(1), ftpshut(8) .PP Full documentation on ProFTPD, including configuration and FAQs, is available at .BR http://www.proftpd.org/ .PP For help/support, try the ProFTPD mailing lists, detailed on .BR http://www.proftpd.org/lists.html .PP Report bugs at .BR http://bugs.proftpd.org/ proftpd-dfsg-1.3.5~rc3/src/ftpdctl.80000644000175000017500000000321212156653650017074 0ustar frankiefrankie.TH ftpdctl 8 "November 2003" .\" Process with .\" groff -man -Tascii ftpdctl.8 .\" .SH NAME ftpdctl \- ProFTPD control program .SH SYNOPSIS .B ftpdctl [ .B \-hv ] [ .BI \-s " Unix domain socket" ] .BI action " action-parameters" .SH DESCRIPTION .B ftpdctl is the control program for the Professional File Transfer Protocol (FTP) server daemon. The control program is used to control the daemon while it is running, supporting actions like restarting or shutting down the daemon, disabling or enabling specific virtual servers, kicking FTP users, etc. .PP The specific \fBactions\fP available via .B ftpdctl depend on the modules compiled into .B proftpd. Check the modules documentation for more information on the specific \fBactions\fP supported by the modules. .PD .SH OPTIONS .TP 12 .B \-h,\--help Display a short usage description, including all available options. .TP .B \-s,\--socket Specifies an alternate \fBpath\fP to be used for communicating with .B proftpd rather than the default Unix domain socket. The default controls socket is .B /var/run/proftpd/proftpd.sock .TP .B \-v,\--verbose Display informational messages while communicating with the .B proftpd daemon. .TP .PD .SH AUTHORS .PP ProFTPD is written and maintained by a number of people, full credits can be found on .BR http://www.proftpd.org/credits.html .PD .SH SEE ALSO .BR proftpd(8), ftp(1), ftpwho(1), ftpcount(1), ftpshut(8) .PP Full documentation on ProFTPD, including configuration and FAQs, is available at .BR http://www.proftpd.org/ .PP For help/support, try the ProFTPD mailing lists, detailed on .BR http://www.proftpd.org/lists.html .PP Report bugs at .BR http://bugs.proftpd.org/ proftpd-dfsg-1.3.5~rc3/src/ftpdctl.c0000644000175000017500000001615711566550020017152 0ustar frankiefrankie/* * ProFTPD - FTP server daemon * Copyright (c) 2001-2011 The ProFTPD Project team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * As a special exemption, Public Flood Software/MacGyver aka Habeeb J. Dihu * and other respective copyright holders give permission to link this program * with OpenSSL, and distribute the resulting executable, without including * the source code for OpenSSL in the source distribution. */ /* ProFTPD Controls command-line client * $Id: ftpdctl.c,v 1.18 2011/05/23 21:22:24 castaglia Exp $ */ #include "conf.h" #include "privs.h" #ifdef HAVE_GETOPT_H # include #endif static const char *program = "ftpdctl"; /* NOTE: these empty stubs are needed for proper linking. What a mess. */ session_t session; server_rec *main_server = NULL; void *get_param_ptr(xaset_t *set, const char *name, int recurse) { return NULL; } void pr_alarms_block(void) { } void pr_alarms_unblock(void) { } gid_t pr_auth_name2gid(pool *p, const char *name) { return (gid_t) -1; } uid_t pr_auth_name2uid(pool *p, const char *name) { return (uid_t) -1; } void pr_event_generate(const char *event, const void *event_data) { (void) event; (void) event_data; } int pr_event_listening(const char *event) { return -1; } int pr_fs_get_usable_fd(int fd) { return -1; } int pr_privs_root(const char *file, int lineno) { return 0; } int pr_privs_relinquish(const char *file, int lineno) { return 0; } void pr_signals_block(void) { } void pr_signals_unblock(void) { } void pr_signals_handle(void) { } pr_table_t *pr_table_alloc(pool *p, int flags) { errno = EPERM; return NULL; } int pr_table_add(pr_table_t *tab, const char *k, void *v, size_t sz) { errno = EPERM; return -1; } int pr_table_count(pr_table_t *tab) { errno = EPERM; return -1; } int pr_table_empty(pr_table_t *tab) { errno = EPERM; return -1; } int pr_table_exists(pr_table_t *tab, const char *k) { errno = EPERM; return -1; } int pr_table_free(pr_table_t *tab) { errno = EPERM; return -1; } void *pr_table_get(pr_table_t *tab, const char *k, size_t *sz) { errno = EPERM; return NULL; } int pr_table_set(pr_table_t *tab, const char *k, void *v, size_t sz) { errno = EPERM; return -1; } struct tm *pr_localtime(pool *p, const time_t *t) { return localtime(t); } int pr_trace_msg(const char *channel, int level, const char *fmt, ...) { errno = ENOSYS; return -1; } char *sstrncpy(char *dest, const char *src, size_t n) { register char *d = dest; if (!dest) return NULL; if (n == 0) return NULL; if (src && *src) { for (; *src && n > 1; n--) *d++ = *src++; } *d = '\0'; return dest; } #ifdef PR_USE_CTRLS /* need a SIGPIPE handler */ static RETSIGTYPE sig_pipe(int sig) { signal(SIGPIPE, sig_pipe); } static void usage(void) { fprintf(stdout, "usage: %s [options]\n", program); fprintf(stdout, " -h\tdisplays this message\n"); fprintf(stdout, " -s\tspecify an alternate local socket\n"); fprintf(stdout, " -v\tdisplays more verbose information\n"); fprintf(stdout, "\n"); return; } int main(int argc, char *argv[]) { unsigned char verbose = FALSE; char **respargv = NULL; const char *cmdopts = "hs:v"; register int i = 0; char *socket_file = PR_RUN_DIR "/proftpd.sock"; int sockfd = -1, optc = 0, status = 0, respargc = 0; unsigned int reqargc = 0; pool *ctl_pool = NULL; array_header *reqargv = NULL; /* Make sure we were called with at least one argument. */ if (argc-1 < 1) { fprintf(stdout, "%s: missing required arguments\n", program); exit(1); } /* Set the POSIXLY_CORRECT environment variable, so that control handlers * can themselves have optional flags. */ if (putenv("POSIXLY_CORRECT=1") < 0) { fprintf(stderr, "%s: unable to set POSIXLY_CORRECT: %s\n", program, strerror(errno)); exit(1); } opterr = 0; while ((optc = getopt(argc, argv, cmdopts)) != -1) { switch (optc) { case 'h': usage(); return 0; case 's': if (*optarg != '/') { fprintf(stderr, "%s: alternate socket path must be an absolute " "path\n", program); return 1; } socket_file = optarg; break; case 'v': verbose = TRUE; break; case '?': fprintf(stdout, "%s: unknown option: %c\n", program, (char) optopt); break; } } signal(SIGPIPE, sig_pipe); /* Allocate some memory for proftpd objects. */ ctl_pool = make_sub_pool(NULL); reqargv = make_array(ctl_pool, 0, sizeof(char *)); /* Process the command-line args into an array_header. */ for (i = optind; i < argc; i++) { if (verbose) fprintf(stdout, "%s: adding \"%s\" to reqargv\n", program, argv[i]); *((char **) push_array(reqargv)) = pstrdup(ctl_pool, argv[i]); reqargc++; } /* Don't forget to NULL-terminate the array. */ *((char **) push_array(reqargv)) = NULL; /* Open a connection to the socket maintained by mod_ctrls. */ if (verbose) fprintf(stdout, "%s: contacting server using '%s'\n", program, socket_file); sockfd = pr_ctrls_connect(socket_file); if (sockfd < 0) { fprintf(stderr, "%s: error contacting server using '%s': %s\n", program, socket_file, strerror(errno)); exit(1); } if (verbose) fprintf(stdout, "%s: sending control request\n", program); if (pr_ctrls_send_msg(sockfd, 0, reqargc, (char **) reqargv->elts) < 0) { fprintf(stderr, "%s: error sending request: %s\n", program, strerror(errno)); exit(1); } /* Read and display the responses. */ if (verbose) fprintf(stdout, "%s: receiving control response\n", program); /* Manually set errno to this value, so that if an error (like a segfault) * occurs, the error string displayed to the user is more indicative of * the cause of the lack of responses. */ errno = EPERM; if ((respargc = pr_ctrls_recv_response(ctl_pool, sockfd, &status, &respargv)) < 0) { fprintf(stdout, "%s: error receiving response: %s\n", program, strerror(errno)); exit(1); } if (respargv != NULL) { for (i = 0; i < respargc; i++) fprintf(stdout, "%s: %s\n", program, respargv[i]); } else fprintf(stdout, "%s: no response from server\n", program); destroy_pool(ctl_pool); ctl_pool = NULL; return 0; } #else int main(int argc, char *argv[]) { printf("%s:\n", program); printf(" Controls support disabled.\n"); printf(" Please recompile proftpd using --enable-ctrls\n"); return 1; } #endif /* PR_USE_CTRLS */ proftpd-dfsg-1.3.5~rc3/src/netaddr.c0000644000175000017500000015773512133326600017137 0ustar frankiefrankie/* * ProFTPD - FTP server daemon * Copyright (c) 2003-2013 The ProFTPD Project team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * As a special exemption, The ProFTPD Project team and other respective * copyright holders give permission to link this program with OpenSSL, and * distribute the resulting executable, without including the source code for * OpenSSL in the source distribution. */ /* Network address routines * $Id: netaddr.c,v 1.92 2013/04/16 19:58:56 castaglia Exp $ */ #include "conf.h" #if HAVE_NET_IF_H # include #endif #if HAVE_IFADDRS_H # include #endif /* Define an IPv4 equivalent of the IN6_IS_ADDR_LOOPBACK macro. */ #undef IN_IS_ADDR_LOOPBACK #define IN_IS_ADDR_LOOPBACK(a) \ ((((unsigned long int) ntohl((a)->s_addr)) & 0xff000000) == 0x7f000000) static pr_netaddr_t sess_local_addr; static int have_sess_local_addr = FALSE; static pr_netaddr_t sess_remote_addr; static char sess_remote_name[PR_TUNABLE_BUFFER_SIZE]; static int have_sess_remote_addr = FALSE; /* Do reverse DNS lookups? */ static int reverse_dns = 1; /* Use IPv6? */ #ifdef PR_USE_IPV6 static int use_ipv6 = TRUE; #else static int use_ipv6 = FALSE; #endif /* PR_USE_IPV6 */ static char localaddr_str[PR_TUNABLE_BUFFER_SIZE]; static int have_localaddr_str = FALSE; static pool *netaddr_pool = NULL; static pr_table_t *netaddr_iptab = NULL; static pr_table_t *netaddr_dnstab = NULL; static const char *trace_channel = "dns"; /* Netaddr cache management */ static array_header *netaddr_dnscache_get(pool *p, const char *ip_str) { array_header *res = NULL; if (netaddr_dnstab) { void *v = pr_table_get(netaddr_dnstab, ip_str, NULL); if (v) { res = v; pr_trace_msg(trace_channel, 4, "using %d DNS %s from netaddr DNS cache for IP address '%s'", res->nelts, res->nelts != 1 ? "names" : "name", ip_str); if (p) { /* If the caller provided a pool, return a copy of the array. */ return copy_array_str(p, res); } return res; } } pr_trace_msg(trace_channel, 12, "no DNS names found in netaddr DNS cache for IP address '%s'", ip_str); errno = ENOENT; return NULL; } static void netaddr_dnscache_set(const char *ip_str, const char *dns_name) { if (netaddr_dnstab) { void *v = NULL; array_header *res = NULL; int add_list = FALSE; res = netaddr_dnscache_get(NULL, ip_str); if (res == NULL) { /* No existing entries for this IP address yet. */ res = make_array(netaddr_pool, 1, sizeof(char *)); add_list = TRUE; } else { register unsigned int i; char **names; /* Check for duplicates. */ names = res->elts; for (i = 0; i < res->nelts; i++) { if (names[i] != NULL) { if (strcmp(names[i], dns_name) == 0) { pr_trace_msg(trace_channel, 5, "DNS name '%s' for IP address '%s' already stashed in the " "netaddr DNS cache", dns_name, ip_str); return; } } } } *((char **) push_array(res)) = pstrdup(netaddr_pool, dns_name); v = res; if (add_list) { if (pr_table_add(netaddr_dnstab, pstrdup(netaddr_pool, ip_str), v, sizeof(array_header *)) < 0) { pr_trace_msg(trace_channel, 3, "error adding DNS name '%s' for IP address '%s' to the netaddr " "DNS cache: %s", dns_name, ip_str, strerror(errno)); } else { pr_trace_msg(trace_channel, 5, "stashed DNS name '%s' for IP address '%s' in the netaddr DNS cache", dns_name, ip_str); } } else { pr_trace_msg(trace_channel, 5, "stashed DNS name '%s' for IP address '%s' in the netaddr DNS cache", dns_name, ip_str); } } return; } static pr_netaddr_t *netaddr_ipcache_get(pool *p, const char *name) { pr_netaddr_t *res = NULL; if (netaddr_iptab) { void *v = pr_table_get(netaddr_iptab, name, NULL); if (v) { res = v; pr_trace_msg(trace_channel, 4, "using IP address '%s' from netaddr IP cache for name '%s'", pr_netaddr_get_ipstr(res), name); /* We return a copy of the cache's netaddr_t, if the caller provided * a pool for duplication. */ if (p) { return pr_netaddr_dup(p, res); } return res; } } pr_trace_msg(trace_channel, 2, "no IP address found in netaddr IP cache for name '%s'", name); errno = ENOENT; return NULL; } static void netaddr_ipcache_set(const char *name, pr_netaddr_t *na) { if (netaddr_iptab) { int count = 0; void *v = NULL; /* We store an internal copy of the netaddr_t in the cache. */ v = pr_netaddr_dup(netaddr_pool, na); count = pr_table_exists(netaddr_iptab, name); if (count <= 0) { if (pr_table_add(netaddr_iptab, pstrdup(netaddr_pool, name), v, sizeof(pr_netaddr_t *)) < 0) { pr_trace_msg(trace_channel, 3, "error adding IP address '%s' for name '%s' to the netaddr " "IP cache: %s", pr_netaddr_get_ipstr(na), name, strerror(errno)); } else { pr_trace_msg(trace_channel, 5, "stashed IP address '%s' for name '%s' in the netaddr IP cache", pr_netaddr_get_ipstr(v), name); } } else { if (pr_table_set(netaddr_iptab, pstrdup(netaddr_pool, name), v, sizeof(pr_netaddr_t *)) < 0) { pr_trace_msg(trace_channel, 3, "error setting IP address '%s' for name '%s' in the netaddr " "IP cache: %s", pr_netaddr_get_ipstr(na), name, strerror(errno)); } } } return; } /* Provide replacements for needed functions. */ #if !defined(HAVE_GETNAMEINFO) || defined(PR_USE_GETNAMEINFO) int pr_getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags) { struct sockaddr_in *sai = (struct sockaddr_in *) sa; if (!sai || sai->sin_family != AF_INET) return EAI_FAMILY; if (serv != NULL && servlen > (size_t) 1) snprintf(serv, servlen, "%lu", (unsigned long) ntohs(sai->sin_port)); if (host != NULL && hostlen > (size_t) 1) { struct hostent *he = NULL; if ((flags & NI_NUMERICHOST) == 0 && (he = gethostbyaddr((const char *) &(sai->sin_addr), sizeof(sai->sin_addr), AF_INET)) != NULL && he->h_name != NULL && *he->h_name != 0) { if (strlen(he->h_name) >= hostlen) goto handle_numeric_ip; sstrncpy(host, he->h_name, hostlen); } else { char *ipstr = NULL; handle_numeric_ip: ipstr = inet_ntoa(sai->sin_addr); if (ipstr == NULL) return EAI_SYSTEM; if (strlen(ipstr) >= hostlen) return EAI_FAIL; sstrncpy(host, ipstr, hostlen); } } return 0; } #endif /* HAVE_GETNAMEINFO or PR_USE_GETNAMEINFO */ #if !defined(HAVE_GETADDRINFO) || defined(PR_USE_GETADDRINFO) int pr_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) { struct addrinfo *ans = NULL; struct sockaddr_in *saddr = NULL; const char *proto_name = "tcp"; int socktype = SOCK_STREAM; unsigned short port = 0; if (!res) return EAI_FAIL; *res = NULL; ans = malloc(sizeof(struct addrinfo)); if (ans == NULL) return EAI_MEMORY; saddr = malloc(sizeof(struct sockaddr_in)); if (saddr == NULL) { free(ans); return EAI_MEMORY; } ans->ai_family = AF_INET; ans->ai_addrlen = sizeof *saddr; ans->ai_addr = (struct sockaddr *) saddr; ans->ai_next = NULL; memset(saddr, 0, sizeof(*saddr)); saddr->sin_family = AF_INET; if (hints != NULL) { struct protoent *pe = NULL; if ((pe = getprotobynumber(hints->ai_protocol)) != NULL && pe->p_name != NULL && *pe->p_name != 0) proto_name = pe->p_name; if (hints->ai_socktype != 0) { socktype = hints->ai_socktype; } else if (strncasecmp(proto_name, "udp", 4) == 0) { socktype = SOCK_DGRAM; } } if (service != NULL) { struct servent *se = NULL; if ((se = getservbyname(service, proto_name)) != NULL && se->s_port > 0) port = se->s_port; else if ((port = (unsigned short) strtoul(service, NULL, 0)) <= 0 || port > 65535) port = 0; } if (hints != NULL && (hints->ai_flags & AI_PASSIVE) != 0) saddr->sin_addr.s_addr = htonl(INADDR_ANY); if (node != NULL) { struct hostent *he = NULL; if ((he = gethostbyname(node)) != NULL && he->h_addr_list != NULL && he->h_addr_list[0] != NULL && he->h_length > 0 && he->h_length <= (int) sizeof(saddr->sin_addr)) memcpy(&saddr->sin_addr, he->h_addr_list[0], he->h_length); } ans->ai_socktype = socktype; saddr->sin_port = htons(port); *res = ans; return 0; } void pr_freeaddrinfo(struct addrinfo *ai) { if (!ai) return; if (ai->ai_addr != NULL) { free(ai->ai_addr); ai->ai_addr = NULL; } free(ai); } #endif /* HAVE_GETADDRINFO or PR_USE_GETADDRINFO */ #if !defined(HAVE_INET_NTOP) const char *pr_inet_ntop(int af, const void *src, char *dst, size_t len) { char *res; if (af != AF_INET) { errno = EAFNOSUPPORT; return NULL; } res = inet_ntoa(*((struct in_addr *) src)); if (res == NULL) return NULL; memcpy(dst, res, len); return dst; } #endif /* !HAVE_INET_NTOP */ #if !defined(HAVE_INET_PTON) int pr_inet_pton(int af, const char *src, void *dst) { unsigned long res; if (af != AF_INET) { errno = EAFNOSUPPORT; return -1; } /* inet_aton(3) would be better. However, it is not ubiquitous. */ res = inet_addr(src); if (res == INADDR_NONE || res == 0) return 0; memcpy(dst, &res, sizeof(res)); return 1; } #endif /* !HAVE_INET_PTON */ static void *get_v4inaddr(const pr_netaddr_t *na) { /* This function is specifically for IPv4 clients (when gethostbyname2(2) is * present) that have an IPv4-mapped IPv6 address, when performing reverse * DNS checks. This function is called iff the given netaddr object is * indeed an IPv4-mapped IPv6 address. IPv6 address have 128 bits in their * sin6_addr field. For IPv4-mapped IPv6 addresses, the relevant 32 bits * are the last of those 128 bits (or, alternatively, the last 4 bytes of * those 16 bytes); hence the read of 12 bytes after the start of the * sin6_addr pointer. */ return (((char *) pr_netaddr_get_inaddr(na)) + 12); } /* Validate anything returned from the 'outside', since it's untrusted * information. */ char *pr_netaddr_validate_dns_str(char *buf) { char *p; if (buf == NULL) { errno = EINVAL; return NULL; } /* Validate anything returned from a DNS. */ for (p = buf; p && *p; p++) { /* Per RFC requirements, these are all that are valid from a DNS. */ if (!PR_ISALNUM(*p) && *p != '.' && *p != '-' #ifdef PR_USE_IPV6 && *p != ':' #endif /* PR_USE_IPV6 */ ) { /* We set it to _ because we know that's an invalid, yet safe, option * for a DNS entry. */ *p = '_'; } } return buf; } int pr_netaddr_set_reverse_dns(int enable) { int old_enable = reverse_dns; reverse_dns = enable; return old_enable; } pr_netaddr_t *pr_netaddr_alloc(pool *p) { if (!p) { errno = EINVAL; return NULL; } return pcalloc(p, sizeof(pr_netaddr_t)); } void pr_netaddr_clear(pr_netaddr_t *na) { if (!na) return; memset(na, 0, sizeof(pr_netaddr_t)); } pr_netaddr_t *pr_netaddr_dup(pool *p, pr_netaddr_t *na) { pr_netaddr_t *dup_na; if (!p || !na) { errno = EINVAL; return NULL; } dup_na = pr_netaddr_alloc(p); pr_netaddr_set_family(dup_na, pr_netaddr_get_family(na)); pr_netaddr_set_sockaddr(dup_na, pr_netaddr_get_sockaddr(na)); if (na->na_have_ipstr) { sstrncpy(dup_na->na_ipstr, na->na_ipstr, sizeof(dup_na->na_ipstr)); dup_na->na_have_ipstr = 1; } if (na->na_have_dnsstr) { sstrncpy(dup_na->na_dnsstr, na->na_dnsstr, sizeof(dup_na->na_dnsstr)); dup_na->na_have_dnsstr = 1; } return dup_na; } static pr_netaddr_t *get_addr_by_ip(pool *p, const char *name, array_header **addrs) { struct sockaddr_in v4; pr_netaddr_t *na = NULL; int res; #ifdef PR_USE_IPV6 if (use_ipv6) { struct sockaddr_in6 v6; memset(&v6, 0, sizeof(v6)); v6.sin6_family = AF_INET6; # ifdef SIN6_LEN v6.sin6_len = sizeof(struct sockaddr_in6); # endif /* SIN6_LEN */ res = pr_inet_pton(AF_INET6, name, &v6.sin6_addr); if (res > 0) { na = (pr_netaddr_t *) pcalloc(p, sizeof(pr_netaddr_t)); pr_netaddr_set_family(na, AF_INET6); pr_netaddr_set_sockaddr(na, (struct sockaddr *) &v6); if (addrs) { *addrs = NULL; } pr_trace_msg(trace_channel, 7, "'%s' resolved to IPv6 address %s", name, pr_netaddr_get_ipstr(na)); netaddr_ipcache_set(name, na); netaddr_ipcache_set(pr_netaddr_get_ipstr(na), na); return na; } } #endif /* PR_USE_IPV6 */ memset(&v4, 0, sizeof(v4)); v4.sin_family = AF_INET; # ifdef SIN_LEN v4.sin_len = sizeof(struct sockaddr_in); # endif /* SIN_LEN */ res = pr_inet_pton(AF_INET, name, &v4.sin_addr); if (res > 0) { na = (pr_netaddr_t *) pcalloc(p, sizeof(pr_netaddr_t)); pr_netaddr_set_family(na, AF_INET); pr_netaddr_set_sockaddr(na, (struct sockaddr *) &v4); if (addrs) { *addrs = NULL; } pr_trace_msg(trace_channel, 7, "'%s' resolved to IPv4 address %s", name, pr_netaddr_get_ipstr(na)); netaddr_ipcache_set(name, na); netaddr_ipcache_set(pr_netaddr_get_ipstr(na), na); return na; } return NULL; } static pr_netaddr_t *get_addr_by_name(pool *p, const char *name, array_header **addrs) { pr_netaddr_t *na = NULL; int res; struct addrinfo hints, *info = NULL; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; pr_trace_msg(trace_channel, 7, "attempting to resolve '%s' to IPv4 address via DNS", name); res = pr_getaddrinfo(name, NULL, &hints, &info); if (res != 0) { int xerrno = errno; if (res != EAI_SYSTEM) { #ifdef PR_USE_IPV6 if (use_ipv6) { pr_trace_msg(trace_channel, 7, "unable to resolve '%s' to an IPv4 address: %s", name, pr_gai_strerror(res)); info = NULL; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET6; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; pr_trace_msg(trace_channel, 7, "attempting to resolve '%s' to IPv6 address via DNS", name); res = pr_getaddrinfo(name, NULL, &hints, &info); if (res != 0) { xerrno = errno; if (res != EAI_SYSTEM) { pr_trace_msg(trace_channel, 5, "unable to resolve '%s' to an IPv6 address: %s", name, pr_gai_strerror(res)); } else { pr_trace_msg(trace_channel, 1, "IPv6 getaddrinfo '%s' system error: [%d] %s", name, xerrno, strerror(xerrno)); } } } else { pr_trace_msg(trace_channel, 1, "IPv4 getaddrinfo '%s' error: %s", name, pr_gai_strerror(res)); } #else pr_trace_msg(trace_channel, 1, "IPv4 getaddrinfo '%s' error: %s", name, pr_gai_strerror(res)); #endif /* PR_USE_IPV6 */ } else { pr_trace_msg(trace_channel, 1, "IPv4 getaddrinfo '%s' system error: [%d] %s", name, xerrno, strerror(xerrno)); } if (res != 0) { errno = xerrno; return NULL; } } if (info) { na = (pr_netaddr_t *) pcalloc(p, sizeof(pr_netaddr_t)); /* Copy the first returned addr into na, as the return value. */ pr_netaddr_set_family(na, info->ai_family); pr_netaddr_set_sockaddr(na, info->ai_addr); pr_trace_msg(trace_channel, 7, "resolved '%s' to %s address %s", name, info->ai_family == AF_INET ? "IPv4" : "IPv6", pr_netaddr_get_ipstr(na)); netaddr_ipcache_set(name, na); netaddr_ipcache_set(pr_netaddr_get_ipstr(na), na); pr_freeaddrinfo(info); } #ifdef PR_USE_IPV6 if (use_ipv6 && addrs) { /* Do the call again, this time for IPv6 addresses. * * We make two separate getaddrinfo(3) calls, rather than one * with a hint of AF_UNSPEC, because of certain bugs where the use * of AF_UNSPEC does not function as advertised. (I suspect this * bug was caused by proftpd's calling pattern, but as I could * not track it down, and as there are reports of AF_UNSPEC not * being as fast as AF_INET/AF_INET6, it just seemed easier to * do it this way.) */ memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET6; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; pr_trace_msg(trace_channel, 7, "attempting to resolve '%s' to IPv6 address via DNS", name); res = pr_getaddrinfo(name, NULL, &hints, &info); if (res != 0) { int xerrno = errno; if (res != EAI_SYSTEM) { pr_trace_msg(trace_channel, 1, "IPv6 getaddrinfo '%s' error: %s", name, pr_gai_strerror(res)); } else { pr_trace_msg(trace_channel, 1, "IPv6 getaddrinfo '%s' system error: [%d] %s", name, xerrno, strerror(xerrno)); } } else { /* We may have already looked up an IPv6 address as the first * address; we don't want to have duplicate addresses in the * returned list of additional addresses. */ if (info && info->ai_family != pr_netaddr_get_family(na)) { pr_netaddr_t **elt; *addrs = make_array(p, 0, sizeof(pr_netaddr_t *)); elt = push_array(*addrs); *elt = pcalloc(p, sizeof(pr_netaddr_t)); pr_netaddr_set_family(*elt, info->ai_family); pr_netaddr_set_sockaddr(*elt, info->ai_addr); pr_trace_msg(trace_channel, 7, "resolved '%s' to %s address %s", name, info->ai_family == AF_INET ? "IPv4" : "IPv6", pr_netaddr_get_ipstr(*elt)); pr_freeaddrinfo(info); } } } #endif /* PR_USE_IPV6 */ return na; } static pr_netaddr_t *get_addr_by_device(pool *p, const char *name, array_header **addrs) { #ifdef HAVE_GETIFADDRS struct ifaddrs *ifaddr; pr_netaddr_t *na = NULL; int res, xerrno; /* Try to use the given name as a device/interface name, and see if we * can suss out the IP address(es) to use based on that. */ res = getifaddrs(&ifaddr); if (res < 0) { xerrno = errno; pr_trace_msg(trace_channel, 1, "error retrieving interfaces via getifaddrs(3): %s", strerror(xerrno)); } else { struct ifaddrs *ifa; int found_device = FALSE; for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { /* We're only looking for addresses, not stats. */ if (ifa->ifa_addr->sa_family != AF_INET #ifdef PR_USE_IPV6 && ifa->ifa_addr->sa_family != AF_INET6 #endif /* PR_USE_IPV6 */ ) { continue; } if (strcmp(ifa->ifa_name, name) == 0) { if (found_device == FALSE) { na = (pr_netaddr_t *) pcalloc(p, sizeof(pr_netaddr_t)); pr_netaddr_set_family(na, ifa->ifa_addr->sa_family); pr_netaddr_set_sockaddr(na, ifa->ifa_addr); pr_trace_msg(trace_channel, 7, "resolved '%s' to interface with %s address %s", name, ifa->ifa_addr->sa_family == AF_INET ? "IPv4" : "IPv6", pr_netaddr_get_ipstr(na)); found_device = TRUE; /* If the caller did not request additional addresses, then * return now. Otherwise, we keep looking for the other * addresses bound to this interface. */ if (addrs == NULL) { break; } } else { pr_netaddr_t **elt; /* We've already found the first match; this block happens * if the caller wants all of the addresses for this interface. */ *addrs = make_array(p, 0, sizeof(pr_netaddr_t *)); elt = push_array(*addrs); *elt = pcalloc(p, sizeof(pr_netaddr_t)); pr_netaddr_set_family(*elt, ifa->ifa_addr->sa_family); pr_netaddr_set_sockaddr(*elt, ifa->ifa_addr); pr_trace_msg(trace_channel, 7, "resolved '%s' to interface with %s address %s", name, ifa->ifa_addr->sa_family == AF_INET ? "IPv4" : "IPv6", pr_netaddr_get_ipstr(*elt)); } } } if (found_device) { return na; } } errno = ENOENT; #else errno = ENOSYS; #endif /* HAVE_GETIFADDRS */ return NULL; } pr_netaddr_t *pr_netaddr_get_addr2(pool *p, const char *name, array_header **addrs, unsigned int flags) { pr_netaddr_t *na = NULL; if (p == NULL || name == NULL) { errno = EINVAL; return NULL; } pr_trace_msg(trace_channel, 10, "resolving name '%s' to IP address", name); /* First, check our cache to see if this name has already been * resolved. We only want to use the cache, though, if the caller did not * provide the `addrs' pointer, indicating that the caller wants to know * about any additional addresses for the given name. The netaddr cache * is a simple cache, hidden from callers, and thus is unable to populate * that `addrs' pointer if the name is in the cache. */ if (addrs == NULL) { na = netaddr_ipcache_get(p, name); if (na) { return na; } } /* Attempt to translate the given name into a pr_netaddr_t using * pr_inet_pton() first. * * First, if IPv6 support is enabled, we try to translate the name using * pr_inet_pton(AF_INET6) on the hopes that the given string is a valid * representation of an IPv6 address. If that fails, or if IPv6 support * is not enabled, we try with pr_inet_pton(AF_INET). If that fails, we * assume that the given name is a DNS name, and we call pr_getaddrinfo(). */ na = get_addr_by_ip(p, name, addrs); if (na != NULL) { return na; } /* If get_addr_by_ip() returns NULL, it means that name does not represent a * valid network address in the specified address family. Usually, * this means that name is actually a DNS name, not an IP address * string. So we treat it as a DNS name, and use getaddrinfo(3) to * resolve that name to its IP address(es). */ na = get_addr_by_name(p, name, addrs); if (na != NULL) { return na; } if (flags & PR_NETADDR_GET_ADDR_FL_INCL_DEVICE) { na = get_addr_by_device(p, name, addrs); if (na != NULL) { return na; } } pr_trace_msg(trace_channel, 8, "failed to resolve '%s' to an IP address", name); errno = ENOENT; return NULL; } pr_netaddr_t *pr_netaddr_get_addr(pool *p, const char *name, array_header **addrs) { return pr_netaddr_get_addr2(p, name, addrs, 0); } int pr_netaddr_get_family(const pr_netaddr_t *na) { if (!na) { errno = EINVAL; return -1; } return na->na_family; } int pr_netaddr_set_family(pr_netaddr_t *na, int family) { if (!na) { errno = EINVAL; return -1; } /* Set the family member of the appropriate sockaddr struct. */ switch (family) { case AF_INET: na->na_addr.v4.sin_family = AF_INET; break; #ifdef PR_USE_IPV6 case AF_INET6: if (use_ipv6) { na->na_addr.v6.sin6_family = AF_INET6; break; } #endif /* PR_USE_IPV6 */ default: #ifdef EAFNOSUPPORT errno = EAFNOSUPPORT; #else errno = EINVAL; #endif return -1; } na->na_family = family; return 0; } size_t pr_netaddr_get_sockaddr_len(const pr_netaddr_t *na) { if (!na) { errno = EINVAL; return -1; } switch (pr_netaddr_get_family(na)) { case AF_INET: return sizeof(struct sockaddr_in); #ifdef PR_USE_IPV6 case AF_INET6: if (use_ipv6) return sizeof(struct sockaddr_in6); #endif /* PR_USE_IPV6 */ } errno = EPERM; return -1; } size_t pr_netaddr_get_inaddr_len(const pr_netaddr_t *na) { if (!na) { errno = EINVAL; return -1; } switch (pr_netaddr_get_family(na)) { case AF_INET: return sizeof(struct in_addr); #ifdef PR_USE_IPV6 case AF_INET6: if (use_ipv6) return sizeof(struct in6_addr); #endif /* PR_USE_IPV6 */ } errno = EPERM; return -1; } struct sockaddr *pr_netaddr_get_sockaddr(const pr_netaddr_t *na) { if (!na) { errno = EINVAL; return NULL; } switch (pr_netaddr_get_family(na)) { case AF_INET: return (struct sockaddr *) &na->na_addr.v4; #ifdef PR_USE_IPV6 case AF_INET6: if (use_ipv6) return (struct sockaddr *) &na->na_addr.v6; #endif /* PR_USE_IPV6 */ } errno = EPERM; return NULL; } int pr_netaddr_set_sockaddr(pr_netaddr_t *na, struct sockaddr *addr) { if (!na || !addr) { errno = EINVAL; return -1; } memset(&na->na_addr, 0, sizeof(na->na_addr)); switch (na->na_family) { case AF_INET: memcpy(&(na->na_addr.v4), addr, sizeof(struct sockaddr_in)); return 0; #ifdef PR_USE_IPV6 case AF_INET6: if (use_ipv6) { memcpy(&(na->na_addr.v6), addr, sizeof(struct sockaddr_in6)); return 0; } #endif /* PR_USE_IPV6 */ } errno = EPERM; return -1; } int pr_netaddr_set_sockaddr_any(pr_netaddr_t *na) { if (!na) { errno = EINVAL; return -1; } switch (pr_netaddr_get_family(na)) { case AF_INET: { struct in_addr in4addr_any; in4addr_any.s_addr = htonl(INADDR_ANY); na->na_addr.v4.sin_family = AF_INET; #ifdef SIN_LEN na->na_addr.v4.sin_len = sizeof(struct sockaddr_in); #endif /* SIN_LEN */ memcpy(&na->na_addr.v4.sin_addr, &in4addr_any, sizeof(struct in_addr)); return 0; } #ifdef PR_USE_IPV6 case AF_INET6: if (use_ipv6) { na->na_addr.v6.sin6_family = AF_INET6; #ifdef SIN6_LEN na->na_addr.v6.sin6_len = sizeof(struct sockaddr_in6); #endif /* SIN6_LEN */ memcpy(&na->na_addr.v6.sin6_addr, &in6addr_any, sizeof(struct in6_addr)); return 0; } #endif /* PR_USE_IPV6 */ } errno = EPERM; return -1; } void *pr_netaddr_get_inaddr(const pr_netaddr_t *na) { if (!na) { errno = EINVAL; return NULL; } switch (pr_netaddr_get_family(na)) { case AF_INET: return (void *) &na->na_addr.v4.sin_addr; #ifdef PR_USE_IPV6 case AF_INET6: if (use_ipv6) return (void *) &na->na_addr.v6.sin6_addr; #endif /* PR_USE_IPV6 */ } errno = EPERM; return NULL; } unsigned int pr_netaddr_get_port(const pr_netaddr_t *na) { if (!na) { errno = EINVAL; return 0; } switch (pr_netaddr_get_family(na)) { case AF_INET: return na->na_addr.v4.sin_port; #ifdef PR_USE_IPV6 case AF_INET6: if (use_ipv6) return na->na_addr.v6.sin6_port; #endif /* PR_USE_IPV6 */ } errno = EPERM; return 0; } int pr_netaddr_set_port(pr_netaddr_t *na, unsigned int port) { if (!na) { errno = EINVAL; return -1; } switch (pr_netaddr_get_family(na)) { case AF_INET: na->na_addr.v4.sin_port = port; return 0; #ifdef PR_USE_IPV6 case AF_INET6: if (use_ipv6) { na->na_addr.v6.sin6_port = port; return 0; } #endif /* PR_USE_IPV6 */ } errno = EPERM; return -1; } int pr_netaddr_set_port2(pr_netaddr_t *na, unsigned int port) { return pr_netaddr_set_port(na, htons(port)); } int pr_netaddr_cmp(const pr_netaddr_t *na1, const pr_netaddr_t *na2) { pool *tmp_pool = NULL; pr_netaddr_t *a, *b; int res; if (na1 && !na2) return 1; if (!na1 && na2) return -1; if (!na1 && !na2) return 0; if (pr_netaddr_get_family(na1) != pr_netaddr_get_family(na2)) { /* Cannot compare addresses from different families, unless one * of the netaddrs has an AF_INET family, and the other has an * AF_INET6 family AND is an IPv4-mapped IPv6 address. */ if (pr_netaddr_is_v4mappedv6(na1) != TRUE && pr_netaddr_is_v4mappedv6(na2) != TRUE) { errno = EINVAL; return -1; } if (pr_netaddr_is_v4mappedv6(na1) == TRUE) { tmp_pool = make_sub_pool(permanent_pool); pr_trace_msg(trace_channel, 5, "addr '%s' is an IPv4-mapped IPv6 address", pr_netaddr_get_ipstr((pr_netaddr_t *) na1)); /* This case means that na1 is an IPv4-mapped IPv6 address, and * na2 is an IPv4 address. */ a = pr_netaddr_v6tov4(tmp_pool, na1); b = (pr_netaddr_t *) na2; pr_trace_msg(trace_channel, 6, "comparing IPv4 address '%s' against " "IPv4-mapped IPv6 address '%s'", pr_netaddr_get_ipstr(b), pr_netaddr_get_ipstr(a)); } else if (pr_netaddr_is_v4mappedv6(na2) == TRUE) { tmp_pool = make_sub_pool(permanent_pool); pr_trace_msg(trace_channel, 5, "addr '%s' is an IPv4-mapped IPv6 address", pr_netaddr_get_ipstr((pr_netaddr_t *) na2)); /* This case means that na is an IPv4 address, and na2 is an * IPv4-mapped IPv6 address. */ a = (pr_netaddr_t *) na1; b = pr_netaddr_v6tov4(tmp_pool, na2); pr_trace_msg(trace_channel, 6, "comparing IPv4 address '%s' against " "IPv4-mapped IPv6 address '%s'", pr_netaddr_get_ipstr(a), pr_netaddr_get_ipstr(b)); } else { a = (pr_netaddr_t *) na1; b = (pr_netaddr_t *) na2; } } else { a = (pr_netaddr_t *) na1; b = (pr_netaddr_t *) na2; } switch (pr_netaddr_get_family(a)) { case AF_INET: res = memcmp(&a->na_addr.v4.sin_addr, &b->na_addr.v4.sin_addr, sizeof(struct in_addr)); if (res != 0) { pr_trace_msg(trace_channel, 4, "addr %s does not match addr %s", pr_netaddr_get_ipstr(a), pr_netaddr_get_ipstr(b)); } if (tmp_pool) { destroy_pool(tmp_pool); tmp_pool = NULL; } return res; #ifdef PR_USE_IPV6 case AF_INET6: if (use_ipv6) { res = memcmp(&a->na_addr.v6.sin6_addr, &b->na_addr.v6.sin6_addr, sizeof(struct in6_addr)); if (res != 0) { pr_trace_msg(trace_channel, 4, "addr %s does not match addr %s", pr_netaddr_get_ipstr(a), pr_netaddr_get_ipstr(b)); } if (tmp_pool) { destroy_pool(tmp_pool); tmp_pool = NULL; } return res; } #endif /* PR_USE_IPV6 */ } if (tmp_pool) destroy_pool(tmp_pool); errno = EPERM; return -1; } static int addr_ncmp(const unsigned char *aptr, const unsigned char *bptr, unsigned int masklen) { unsigned char nbits, nbytes; int res; nbytes = masklen / 8; nbits = masklen % 8; res = memcmp(aptr, bptr, nbytes); if (res != 0) { return -1; } if (nbits > 0) { unsigned char abyte, bbyte, mask; abyte = aptr[nbytes]; bbyte = bptr[nbytes]; mask = (0xff << (8 - nbits)) & 0xff; if ((abyte & mask) > (bbyte & mask)) { return 1; } if ((abyte & mask) < (bbyte & mask)) { return -1; } } return 0; } int pr_netaddr_ncmp(const pr_netaddr_t *na1, const pr_netaddr_t *na2, unsigned int bitlen) { pool *tmp_pool = NULL; pr_netaddr_t *a, *b; const unsigned char *in1, *in2; int res; if (na1 && !na2) { return 1; } if (!na1 && na2) { return -1; } if (!na1 && !na2) { return 0; } if (pr_netaddr_get_family(na1) != pr_netaddr_get_family(na2)) { /* Cannot compare addresses from different families, unless one * of the netaddrs has an AF_INET family, and the other has an * AF_INET6 family AND is an IPv4-mapped IPv6 address. */ if (pr_netaddr_is_v4mappedv6(na1) != TRUE && pr_netaddr_is_v4mappedv6(na2) != TRUE) { errno = EINVAL; return -1; } if (pr_netaddr_is_v4mappedv6(na1) == TRUE) { tmp_pool = make_sub_pool(permanent_pool); /* This case means that na1 is an IPv4-mapped IPv6 address, and * na2 is an IPv4 address. */ a = pr_netaddr_v6tov4(tmp_pool, na1); b = (pr_netaddr_t *) na2; pr_trace_msg(trace_channel, 6, "comparing IPv4 address '%s' against " "IPv4-mapped IPv6 address '%s'", pr_netaddr_get_ipstr(b), pr_netaddr_get_ipstr(a)); } else if (pr_netaddr_is_v4mappedv6(na2) == TRUE) { tmp_pool = make_sub_pool(permanent_pool); /* This case means that na is an IPv4 address, and na2 is an * IPv4-mapped IPv6 address. */ a = (pr_netaddr_t *) na1; b = pr_netaddr_v6tov4(tmp_pool, na2); pr_trace_msg(trace_channel, 6, "comparing IPv4 address '%s' against " "IPv4-mapped IPv6 address '%s'", pr_netaddr_get_ipstr(a), pr_netaddr_get_ipstr(b)); } else { a = (pr_netaddr_t *) na1; b = (pr_netaddr_t *) na2; } } else { a = (pr_netaddr_t *) na1; b = (pr_netaddr_t *) na2; } switch (pr_netaddr_get_family(a)) { case AF_INET: { /* Make sure that the given number of bits is not more than supported * for IPv4 addresses (32). */ if (bitlen > 32) { errno = EINVAL; return -1; } break; } #ifdef PR_USE_IPV6 case AF_INET6: { if (use_ipv6) { /* Make sure that the given number of bits is not more than supported * for IPv6 addresses (128). */ if (bitlen > 128) { errno = EINVAL; return -1; } break; } } #endif /* PR_USE_IPV6 */ default: errno = EPERM; return -1; } /* Retrieve pointers to the contained in_addrs. */ in1 = (const unsigned char *) pr_netaddr_get_inaddr(a); in2 = (const unsigned char *) pr_netaddr_get_inaddr(b); res = addr_ncmp(in1, in2, bitlen); if (tmp_pool) { destroy_pool(tmp_pool); } return res; } int pr_netaddr_fnmatch(pr_netaddr_t *na, const char *pattern, int flags) { /* Note: I'm still not sure why proftpd bundles an fnmatch(3) * implementation rather than using the system library's implementation. * Needs looking into. * * The FNM_CASEFOLD flag is a GNU extension; perhaps the bundled * implementation was added to make that flag available on other platforms. */ int match_flags = PR_FNM_NOESCAPE|PR_FNM_CASEFOLD; if (!na || !pattern) { errno = EINVAL; return -1; } if (flags & PR_NETADDR_MATCH_DNS) { const char *dnsstr = pr_netaddr_get_dnsstr(na); if (pr_fnmatch(pattern, dnsstr, match_flags) == 0) { pr_trace_msg(trace_channel, 6, "DNS name '%s' matches pattern '%s'", dnsstr, pattern); return TRUE; } } if (flags & PR_NETADDR_MATCH_IP) { const char *ipstr = pr_netaddr_get_ipstr(na); if (pr_fnmatch(pattern, ipstr, match_flags) == 0) { pr_trace_msg(trace_channel, 6, "IP address '%s' matches pattern '%s'", ipstr, pattern); return TRUE; } /* If the address is an IPv4-mapped IPv6 address, get the IPv4 address * and try to match that against the configured glob pattern. */ if (pr_netaddr_is_v4mappedv6(na) == TRUE) { pool *tmp_pool; pr_netaddr_t *a; pr_trace_msg(trace_channel, 5, "addr '%s' is an IPv4-mapped IPv6 address", ipstr); tmp_pool = make_sub_pool(permanent_pool); a = pr_netaddr_v6tov4(tmp_pool, na); ipstr = pr_netaddr_get_ipstr(a); if (pr_fnmatch(pattern, ipstr, match_flags) == 0) { pr_trace_msg(trace_channel, 6, "IP address '%s' matches pattern '%s'", ipstr, pattern); destroy_pool(tmp_pool); return TRUE; } destroy_pool(tmp_pool); } } pr_trace_msg(trace_channel, 4, "addr %s does not match pattern '%s'", pr_netaddr_get_ipstr(na), pattern); return FALSE; } const char *pr_netaddr_get_ipstr(pr_netaddr_t *na) { #ifdef PR_USE_IPV6 char buf[INET6_ADDRSTRLEN]; #else char buf[INET_ADDRSTRLEN]; #endif /* PR_USE_IPV6 */ int res = 0, xerrno; if (!na) { errno = EINVAL; return NULL; } /* If this pr_netaddr_t has already been resolved to an IP string, return the * cached string. */ if (na->na_have_ipstr) return na->na_ipstr; memset(buf, '\0', sizeof(buf)); res = pr_getnameinfo(pr_netaddr_get_sockaddr(na), pr_netaddr_get_sockaddr_len(na), buf, sizeof(buf), NULL, 0, NI_NUMERICHOST); xerrno = errno; if (res != 0) { if (res != EAI_SYSTEM) { pr_log_pri(PR_LOG_WARNING, "getnameinfo error: %s", pr_gai_strerror(res)); errno = EIO; } else { pr_log_pri(PR_LOG_WARNING, "getnameinfo system error: [%d] %s", xerrno, strerror(xerrno)); errno = xerrno; } return NULL; } #ifdef PR_USE_IPV6 if (use_ipv6 && pr_netaddr_get_family(na) == AF_INET6) { /* The getnameinfo(3) implementation might append the zone ID to an IPv6 * name; we need to trim it off. */ char *ptr; ptr = strrchr(buf, '%'); if (ptr != NULL) { *ptr = '\0'; } } #endif /* PR_USE_IPV6 */ /* Copy the string into the pr_netaddr_t cache as well, so we only * have to do this once for this pr_netaddr_t. */ memset(na->na_ipstr, '\0', sizeof(na->na_ipstr)); sstrncpy(na->na_ipstr, buf, sizeof(na->na_ipstr)); na->na_have_ipstr = TRUE; return na->na_ipstr; } #if defined(HAVE_GETADDRINFO) && !defined(HAVE_GETHOSTBYNAME2) static int netaddr_get_dnsstr_getaddrinfo(pr_netaddr_t *na, const char *name) { struct addrinfo hints, *info = NULL; int family, flags = 0, res = 0, ok = FALSE; void *inaddr = pr_netaddr_get_inaddr(na); family = pr_netaddr_get_family(na); if (pr_netaddr_is_v4mappedv6(na) == TRUE) { family = AF_INET; inaddr = get_v4inaddr(na); } #ifdef AI_CANONNAME flags |= AI_CANONNAME; #endif #ifdef AI_ALL flags |= AI_ALL; #endif #ifdef AI_V4MAPPED flags |= AI_V4MAPPED; #endif memset(&hints, 0, sizeof(hints)); hints.ai_family = family; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = flags; res = pr_getaddrinfo(name, NULL, &hints, &info); if (res != 0) { int xerrno = errno; if (res != EAI_SYSTEM) { pr_trace_msg(trace_channel, 1, "%s getaddrinfo '%s' error: %s", hints.ai_family == AF_INET ? "IPv4" : "IPv6", name, pr_gai_strerror(res)); } else { pr_trace_msg(trace_channel, 1, "%s getaddrinfo '%s' system error: [%d] %s", hints.ai_family == AF_INET ? "IPv4" : "IPv6", name, xerrno, strerror(xerrno)); } errno = xerrno; return -1; } if (info != NULL) { #ifdef PR_USE_IPV6 char buf[INET6_ADDRSTRLEN]; #else char buf[INET_ADDRSTRLEN]; #endif /* PR_USE_IPV6 */ struct addrinfo *ai; int xerrno; memset(buf, '\0', sizeof(buf)); res = pr_getnameinfo(info->ai_addr, info->ai_addrlen, buf, sizeof(buf), NULL, 0, NI_NAMEREQD); xerrno = errno; if (res != 0) { if (res != EAI_SYSTEM) { pr_trace_msg(trace_channel, 1, "%s getnameinfo error: %s", hints.ai_family == AF_INET ? "IPv4" : "IPv6", pr_gai_strerror(res)); } else { pr_trace_msg(trace_channel, 1, "%s getnameinfo system error: [%d] %s", hints.ai_family == AF_INET ? "IPv4" : "IPv6", xerrno, strerror(xerrno)); } errno = xerrno; return -1; } netaddr_dnscache_set(pr_netaddr_get_ipstr(na), buf); ok = TRUE; pr_trace_msg(trace_channel, 10, "checking addresses associated with host '%s'", buf); for (ai = info->ai_next; ai; ai = ai->ai_next) { #ifdef PR_USE_IPV6 char alias[INET6_ADDRSTRLEN]; #else char alias[INET_ADDRSTRLEN]; #endif /* PR_USE_IPV6 */ switch (ai->ai_family) { case AF_INET: if (family == AF_INET) { if (memcmp(ai->ai_addr, inaddr, ai->ai_addrlen) == 0) { memset(alias, '\0', sizeof(alias)); res = pr_getnameinfo(ai->ai_addr, ai->ai_addrlen, alias, sizeof(alias), NULL, 0, NI_NAMEREQD); if (res == 0) { pr_trace_msg(trace_channel, 10, "host '%s' has alias '%s'", buf, alias); netaddr_ipcache_set(alias, na); netaddr_dnscache_set(pr_netaddr_get_ipstr(na), alias); } } } break; #ifdef PR_USE_IPV6 case AF_INET6: if (use_ipv6 && family == AF_INET6) { if (memcmp(ai->ai_addr, inaddr, ai->ai_addrlen) == 0) { memset(alias, '\0', sizeof(alias)); res = pr_getnameinfo(ai->ai_addr, ai->ai_addrlen, alias, sizeof(alias), NULL, 0, NI_NAMEREQD); if (res == 0) { pr_trace_msg(trace_channel, 10, "host '%s' has alias '%s'", buf, alias); netaddr_ipcache_set(alias, na); netaddr_dnscache_set(pr_netaddr_get_ipstr(na), alias); } } } break; #endif /* PR_USE_IPV6 */ } } pr_freeaddrinfo(info); } return (ok ? 0 : -1); } #endif /* HAVE_GETADDRINFO and not HAVE_GETHOSTBYNAME2 */ static int netaddr_get_dnsstr_gethostbyname(pr_netaddr_t *na, const char *name) { char **checkaddr; struct hostent *hent = NULL; int ok = FALSE; int family = pr_netaddr_get_family(na); void *inaddr = pr_netaddr_get_inaddr(na); #ifdef HAVE_GETHOSTBYNAME2 if (pr_netaddr_is_v4mappedv6(na) == TRUE) { family = AF_INET; inaddr = get_v4inaddr(na); } hent = gethostbyname2(name, family); #else hent = gethostbyname(name); #endif /* HAVE_GETHOSTBYNAME2 */ if (hent != NULL) { if (hent->h_name != NULL) { netaddr_dnscache_set(pr_netaddr_get_ipstr(na), hent->h_name); } pr_trace_msg(trace_channel, 10, "checking addresses associated with host '%s'", hent->h_name ? hent->h_name : "(null)"); switch (hent->h_addrtype) { case AF_INET: if (family == AF_INET) { for (checkaddr = hent->h_addr_list; *checkaddr; ++checkaddr) { if (memcmp(*checkaddr, inaddr, hent->h_length) == 0) { char **alias; for (alias = hent->h_aliases; *alias; ++alias) { if (hent->h_name) { pr_trace_msg(trace_channel, 10, "host '%s' has alias '%s'", hent->h_name, *alias); netaddr_ipcache_set(*alias, na); netaddr_dnscache_set(pr_netaddr_get_ipstr(na), *alias); } } ok = TRUE; break; } } } break; #ifdef PR_USE_IPV6 case AF_INET6: if (use_ipv6 && family == AF_INET6) { for (checkaddr = hent->h_addr_list; *checkaddr; ++checkaddr) { if (memcmp(*checkaddr, inaddr, hent->h_length) == 0) { char **alias; for (alias = hent->h_aliases; *alias; ++alias) { if (hent->h_name) { pr_trace_msg(trace_channel, 10, "host '%s' has alias '%s'", hent->h_name, *alias); netaddr_ipcache_set(*alias, na); netaddr_dnscache_set(pr_netaddr_get_ipstr(na), *alias); } } ok = TRUE; break; } } } break; #endif /* PR_USE_IPV6 */ } } else { pr_log_debug(DEBUG1, "notice: unable to resolve '%s': %s", name, hstrerror(h_errno)); } return (ok ? 0 : -1); } /* This differs from pr_netaddr_get_ipstr() in that pr_netaddr_get_ipstr() * returns a string of the numeric form of the given network address, whereas * this function returns a string of the DNS name (if present). */ const char *pr_netaddr_get_dnsstr(pr_netaddr_t *na) { char *name = NULL; pr_netaddr_t *cache = NULL; if (na == NULL) { errno = EINVAL; return NULL; } cache = netaddr_ipcache_get(NULL, pr_netaddr_get_ipstr(na)); if (cache && cache->na_have_dnsstr) { memset(na->na_dnsstr, '\0', sizeof(na->na_dnsstr)); sstrncpy(na->na_dnsstr, cache->na_dnsstr, sizeof(na->na_dnsstr)); na->na_have_dnsstr = TRUE; return na->na_dnsstr; } /* If this pr_netaddr_t has already been resolved to an DNS string, return the * cached string. */ if (na->na_have_dnsstr) { return na->na_dnsstr; } if (reverse_dns) { char buf[256]; int res = 0; pr_trace_msg(trace_channel, 3, "verifying DNS name for IP address %s via reverse DNS lookup", pr_netaddr_get_ipstr(na)); memset(buf, '\0', sizeof(buf)); res = pr_getnameinfo(pr_netaddr_get_sockaddr(na), pr_netaddr_get_sockaddr_len(na), buf, sizeof(buf), NULL, 0, NI_NAMEREQD); buf[sizeof(buf)-1] = '\0'; if (res == 0) { /* Some older glibc's getaddrinfo(3) does not appear to handle IPv6 * addresses properly; we thus prefer gethostbyname2(3) on systems * which have it, for such older systems. */ #ifdef HAVE_GETHOSTBYNAME2 res = netaddr_get_dnsstr_gethostbyname(na, buf); #else res = netaddr_get_dnsstr_getaddrinfo(na, buf); #endif /* HAVE_GETHOSTBYNAME2 */ if (res == 0) { name = buf; pr_trace_msg(trace_channel, 8, "using DNS name '%s' for IP address '%s'", name, pr_netaddr_get_ipstr(na)); } else { name = NULL; pr_trace_msg(trace_channel, 8, "unable to verify any DNS names for IP address '%s'", pr_netaddr_get_ipstr(na)); } } } else { pr_log_debug(DEBUG10, "UseReverseDNS off, returning IP address instead of DNS name"); } if (name) { name = pr_netaddr_validate_dns_str(name); } else { name = (char *) pr_netaddr_get_ipstr(na); } /* Copy the string into the pr_netaddr_t cache as well, so we only * have to do this once for this pr_netaddr_t. */ memset(na->na_dnsstr, '\0', sizeof(na->na_dnsstr)); sstrncpy(na->na_dnsstr, name, sizeof(na->na_dnsstr)); na->na_have_dnsstr = TRUE; /* Update the netaddr object in the cache with the resolved DNS names. */ netaddr_ipcache_set(name, na); netaddr_ipcache_set(pr_netaddr_get_ipstr(na), na); return na->na_dnsstr; } array_header *pr_netaddr_get_dnsstr_list(pool *p, pr_netaddr_t *na) { array_header *res; if (p == NULL || na == NULL) { errno = EINVAL; return NULL; } if (!reverse_dns) { /* If UseReverseDNS is off, then we won't have any names that we trust. * So return an empty list. */ return make_array(p, 0, sizeof(char *)); } res = netaddr_dnscache_get(p, pr_netaddr_get_ipstr(na)); if (res == NULL) { res = make_array(p, 0, sizeof(char *)); } return res; } /* Return the hostname (wrapper for gethostname(2), except returns FQDN). */ const char *pr_netaddr_get_localaddr_str(pool *p) { char buf[256]; if (p == NULL) { errno = EINVAL; return NULL; } if (have_localaddr_str) { return pr_netaddr_validate_dns_str(pstrdup(p, localaddr_str)); } memset(buf, '\0', sizeof(buf)); if (gethostname(buf, sizeof(buf)-1) != -1) { struct hostent *host; buf[sizeof(buf)-1] = '\0'; /* Note: this may need to be gethostbyname2() on systems that provide * that function, for it is possible that the configured hostname for * a machine only resolves to an IPv6 address. */ host = gethostbyname(buf); if (host) return pr_netaddr_validate_dns_str(pstrdup(p, host->h_name)); return pr_netaddr_validate_dns_str(pstrdup(p, buf)); } pr_trace_msg(trace_channel, 1, "gethostname(2) error: %s", strerror(errno)); return NULL; } int pr_netaddr_set_localaddr_str(const char *addr_str) { if (addr_str == NULL) { errno = EINVAL; return -1; } memset(localaddr_str, '\0', sizeof(localaddr_str)); sstrncpy(localaddr_str, addr_str, sizeof(localaddr_str)); have_localaddr_str = TRUE; return 0; } int pr_netaddr_is_loopback(const pr_netaddr_t *na) { if (na == NULL) { errno = EINVAL; return -1; } switch (pr_netaddr_get_family(na)) { case AF_INET: return IN_IS_ADDR_LOOPBACK( (struct in_addr *) pr_netaddr_get_inaddr(na)); #ifdef PR_USE_IPV6 case AF_INET6: if (pr_netaddr_is_v4mappedv6(na) == TRUE) { pool *tmp_pool; pr_netaddr_t *v4na; int res; tmp_pool = make_sub_pool(permanent_pool); v4na = pr_netaddr_v6tov4(tmp_pool, na); res = pr_netaddr_is_loopback(v4na); destroy_pool(tmp_pool); return res; } /* XXX *sigh* Different platforms implement the IN6_IS_ADDR macros * differently. For example, on Linux, those macros expect to operate * on s6_addr32, while on Solaris, the macros operate on struct in6_addr. * Certain Drafts define the macros to work on struct in6_addr *, as * Solaris does, so Linux may have it wrong. Tentative research on * Google shows some BSD netinet6/in6.h headers that define these * macros in terms of struct in6_addr *, so I'll go with that for now. * Joy. =P */ # ifndef LINUX return IN6_IS_ADDR_LOOPBACK( (struct in6_addr *) pr_netaddr_get_inaddr(na)); # else return IN6_IS_ADDR_LOOPBACK( ((struct in6_addr *) pr_netaddr_get_inaddr(na))->s6_addr32); # endif #endif /* PR_USE_IPV6 */ } return FALSE; } /* RFC 1918 addresses: * * 10.0.0.0 - 10.255.255.255 (10.0.0.0/8, 24-bit block) * 172.16.0.0 - 172.31.255.255 (172.16.0.0/12, 20-bit block) * 192.168.0.0 - 192.168.255.255 (192.168.0.0/16, 16-bit block) * */ static int is_10_xxx_addr(uint32_t addrno) { uint32_t rfc1918_addrno; rfc1918_addrno = htonl(0x0a000000); return addr_ncmp((const unsigned char *) &addrno, (const unsigned char *) &rfc1918_addrno, 8); } static int is_172_16_xx_addr(uint32_t addrno) { uint32_t rfc1918_addrno; rfc1918_addrno = htonl(0xac100000); return addr_ncmp((const unsigned char *) &addrno, (const unsigned char *) &rfc1918_addrno, 12); } static int is_192_168_xx_addr(uint32_t addrno) { uint32_t rfc1918_addrno; rfc1918_addrno = htonl(0xc0a80000); return addr_ncmp((const unsigned char *) &addrno, (const unsigned char *) &rfc1918_addrno, 16); } int pr_netaddr_is_rfc1918(const pr_netaddr_t *na) { if (na == NULL) { errno = EINVAL; return -1; } switch (pr_netaddr_get_family(na)) { case AF_INET: { uint32_t addrno; addrno = pr_netaddr_get_addrno(na); if (is_192_168_xx_addr(addrno) == 0 || is_172_16_xx_addr(addrno) == 0 || is_10_xxx_addr(addrno) == 0) { return TRUE; } break; } #ifdef PR_USE_IPV6 case AF_INET6: if (pr_netaddr_is_v4mappedv6(na) == TRUE) { pool *tmp_pool; pr_netaddr_t *v4na; int res; tmp_pool = make_sub_pool(permanent_pool); v4na = pr_netaddr_v6tov4(tmp_pool, na); res = pr_netaddr_is_rfc1918(v4na); destroy_pool(tmp_pool); return res; } /* By definition, an IPv6 address is not an RFC1918-defined address. */ return FALSE; #endif /* PR_USE_IPV6 */ } errno = EINVAL; return FALSE; } /* A slightly naughty function that should go away. It relies too much on * knowledge of the internal structures of struct in_addr, struct in6_addr. */ uint32_t pr_netaddr_get_addrno(const pr_netaddr_t *na) { if (na == NULL) { errno = EINVAL; return 0; } switch (pr_netaddr_get_family(na)) { case AF_INET: return (uint32_t) na->na_addr.v4.sin_addr.s_addr; #ifdef PR_USE_IPV6 case AF_INET6: { /* Linux defines s6_addr32 in its netinet/in.h header. * FreeBSD defines s6_addr32 in KAME's netinet6/in6.h header. * Solaris defines s6_addr32 in its netinet/in.h header, but only * for kernel builds. */ #if 0 int *addrs = ((struct sockaddr_in6 *) pr_netaddr_get_inaddr(na))->s6_addr32; return addrs[0]; #else errno = ENOENT; return 0; #endif } #endif /* PR_USE_IPV6 */ } errno = EPERM; return 0; } int pr_netaddr_is_v4(const char *name) { int res; struct sockaddr_in v4; if (name == NULL) { errno = EINVAL; return -1; } memset(&v4, 0, sizeof(v4)); v4.sin_family = AF_INET; # ifdef SIN_LEN v4.sin_len = sizeof(struct sockaddr_in); # endif /* SIN_LEN */ res = pr_inet_pton(AF_INET, name, &v4.sin_addr); if (res > 0) { return TRUE; } return FALSE; } int pr_netaddr_is_v6(const char *name) { if (name == NULL) { errno = EINVAL; return -1; } #ifdef PR_USE_IPV6 if (use_ipv6) { int res; struct sockaddr_in6 v6; memset(&v6, 0, sizeof(v6)); v6.sin6_family = AF_INET6; # ifdef SIN6_LEN v6.sin6_len = sizeof(struct sockaddr_in6); # endif /* SIN6_LEN */ res = pr_inet_pton(AF_INET6, name, &v6.sin6_addr); if (res > 0) { return TRUE; } } return FALSE; #else return FALSE; #endif /* !PR_USE_IPV6 */ } int pr_netaddr_is_v4mappedv6(const pr_netaddr_t *na) { if (!na) { errno = EINVAL; return -1; } switch (pr_netaddr_get_family(na)) { case AF_INET: /* This function tests only IPv6 addresses, not IPv4 addresses. */ errno = EINVAL; return -1; #ifdef PR_USE_IPV6 case AF_INET6: { int res; if (!use_ipv6) { errno = EINVAL; return -1; } # ifndef LINUX res = IN6_IS_ADDR_V4MAPPED( (struct in6_addr *) pr_netaddr_get_inaddr(na)); # else res = IN6_IS_ADDR_V4MAPPED( ((struct in6_addr *) pr_netaddr_get_inaddr(na))->s6_addr32); # endif if (res != TRUE) { errno = EINVAL; } return res; } #endif /* PR_USE_IPV6 */ } errno = EPERM; return -1; } pr_netaddr_t *pr_netaddr_v6tov4(pool *p, const pr_netaddr_t *na) { pr_netaddr_t *res; if (p == NULL || na == NULL) { errno = EINVAL; return NULL; } if (pr_netaddr_is_v4mappedv6(na) != TRUE) { errno = EPERM; return NULL; } res = pr_netaddr_alloc(p); pr_netaddr_set_family(res, AF_INET); pr_netaddr_set_port(res, pr_netaddr_get_port(na)); memcpy(&res->na_addr.v4.sin_addr, get_v4inaddr(na), sizeof(struct in_addr)); return res; } pr_netaddr_t *pr_netaddr_get_sess_local_addr(void) { if (have_sess_local_addr) { return &sess_local_addr; } errno = ENOENT; return NULL; } pr_netaddr_t *pr_netaddr_get_sess_remote_addr(void) { if (have_sess_remote_addr) { return &sess_remote_addr; } errno = ENOENT; return NULL; } const char *pr_netaddr_get_sess_remote_name(void) { if (have_sess_remote_addr) { return sess_remote_name; } errno = ENOENT; return NULL; } void pr_netaddr_set_sess_addrs(void) { pr_netaddr_set_family(&sess_local_addr, pr_netaddr_get_family(session.c->local_addr)); pr_netaddr_set_sockaddr(&sess_local_addr, pr_netaddr_get_sockaddr(session.c->local_addr)); have_sess_local_addr = TRUE; pr_netaddr_set_family(&sess_remote_addr, pr_netaddr_get_family(session.c->remote_addr)); pr_netaddr_set_sockaddr(&sess_remote_addr, pr_netaddr_get_sockaddr(session.c->remote_addr)); memset(sess_remote_name, '\0', sizeof(sess_remote_name)); sstrncpy(sess_remote_name, session.c->remote_name, sizeof(sess_remote_name)); have_sess_remote_addr = TRUE; } unsigned char pr_netaddr_use_ipv6(void) { if (use_ipv6) return TRUE; return FALSE; } void pr_netaddr_disable_ipv6(void) { #ifdef PR_USE_IPV6 use_ipv6 = 0; #endif /* PR_USE_IPV6 */ } void pr_netaddr_enable_ipv6(void) { #ifdef PR_USE_IPV6 use_ipv6 = 1; #endif /* PR_USE_IPV6 */ } void pr_netaddr_clear_cache(void) { if (netaddr_iptab) { pr_trace_msg(trace_channel, 5, "emptying netaddr IP cache"); (void) pr_table_empty(netaddr_iptab); (void) pr_table_free(netaddr_iptab); /* Allocate a fresh table. */ netaddr_iptab = pr_table_alloc(netaddr_pool, 0); } if (netaddr_dnstab) { pr_trace_msg(trace_channel, 5, "emptying netaddr DNS cache"); (void) pr_table_empty(netaddr_dnstab); (void) pr_table_free(netaddr_dnstab); /* Allocate a fresh table. */ netaddr_dnstab = pr_table_alloc(netaddr_pool, 0); } } void init_netaddr(void) { if (netaddr_pool) { pr_netaddr_clear_cache(); destroy_pool(netaddr_pool); netaddr_pool = NULL; } netaddr_pool = make_sub_pool(permanent_pool); pr_pool_tag(netaddr_pool, "Netaddr API"); netaddr_iptab = pr_table_alloc(netaddr_pool, 0); netaddr_dnstab = pr_table_alloc(netaddr_pool, 0); } proftpd-dfsg-1.3.5~rc3/src/table.c0000644000175000017500000006753711721564727016625 0ustar frankiefrankie/* * ProFTPD - FTP server daemon * Copyright (c) 2004-2012 The ProFTPD Project team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * As a special exemption, The ProFTPD Project team and other respective * copyright holders give permission to link this program with OpenSSL, and * distribute the resulting executable, without including the source code for * OpenSSL in the source distribution. */ /* Table API implementation * $Id: table.c,v 1.32 2012/02/24 01:37:27 castaglia Exp $ */ #include "conf.h" #ifdef PR_USE_OPENSSL #include #endif /* PR_USE_OPENSSL */ #define PR_TABLE_DEFAULT_NCHAINS 256 #define PR_TABLE_DEFAULT_MAX_ENTS 8192 #define PR_TABLE_ENT_POOL_SIZE 64 struct table_rec { pool *pool; unsigned long flags; /* These bytes are randomly generated at table creation time, and * are used to seed the hashing function, so as to defend/migitate * against attempts to feed carefully crafted keys which force the * table into its worst-case performance scenario. * * For more information on attacks of this nature, see: * * http://www.cs.rice.edu/~scrosby/hash/CrosbyWallach_UsenixSec2003/ */ unsigned int seed; /* Maximum number of entries that can be stored in this table. The * default maximum (PR_TABLE_DEFAULT_MAX_ENTS) is set fairly high. * This limit is present in order to defend/mitigate against certain abuse * scenarios. * * XXX Note that an additional protective measure can/might be placed on * the maximum length of a given chain, to detect other types of attacks * that force the table into the worse-case performance scenario (i.e. * linear scanning of a long chain). If such is added, then a Table API * function should be added for returning the length of the longest chain * in the table. Such a function could be used by modules to determine * if their tables are being abused (or in need of readjustment). */ unsigned int nmaxents; pr_table_entry_t **chains; unsigned int nchains; unsigned int nents; /* List of free structures. */ pr_table_entry_t *free_ents; pr_table_key_t *free_keys; /* For iterating over all the keys in the entire table. */ pr_table_entry_t *tab_iter_ent; /* For iterating through all of the possible multiple values for a single * key. Only used if the PR_TABLE_FL_MULTI_VALUE flag is set. */ pr_table_entry_t *val_iter_ent; /* Cache of last looked-up entry. Usage of this field can be enabled * by using the PR_TABLE_FL_USE_CACHE flag. */ pr_table_entry_t *cache_ent; /* Table callbacks. */ int (*keycmp)(const void *, size_t, const void *, size_t); unsigned int (*keyhash)(const void *, size_t); void (*entinsert)(pr_table_entry_t **, pr_table_entry_t *); void (*entremove)(pr_table_entry_t **, pr_table_entry_t *); }; static int handling_signal = FALSE; static const char *trace_channel = "table"; /* Default table callbacks */ static int key_cmp(const void *key1, size_t keysz1, const void *key2, size_t keysz2) { const char *k1, *k2; if (keysz1 != keysz2) { return keysz1 < keysz2 ? -1 : 1; } k1 = key1; k2 = key2; if (keysz1 >= 1) { /* Basic check of the first character in each key, trying to reduce * the chances of calling strncmp(3) if not needed. */ if (k1[0] != k2[0]) { return k1[0] < k2[0] ? -1 : 1; } /* Special case (unlikely, but possible). */ if (keysz1 == 1) { return 0; } } return strncmp((const char *) key1, (const char *) key2, keysz1); } /* Use Perl's hashing algorithm by default. * * Here's a good article about this hashing algorithm, and about hashing * functions in general: * * http://www.perl.com/pub/2002/10/01/hashes.html */ static unsigned int key_hash(const void *key, size_t keysz) { unsigned int i = 0; size_t sz = !keysz ? strlen((const char *) key) : keysz; while (sz--) { const char *k = key; unsigned int c; c = k[sz]; if (!handling_signal) { /* Always handle signals in potentially long-running while loops. */ pr_signals_handle(); } i = (i * 33) + c; } return i; } /* Default insertion is simply to add the given entry to the end of the * chain. */ static void entry_insert(pr_table_entry_t **h, pr_table_entry_t *e) { pr_table_entry_t *ei; if (*h == NULL) return; for (ei = *h; ei != NULL && ei->next; ei = ei->next); /* Now, ei points to the last entry in the chain. */ ei->next = e; e->prev = ei; } /* Default removal is simply to remove the entry from the chain. */ static void entry_remove(pr_table_entry_t **h, pr_table_entry_t *e) { if (e->next) { e->next->prev = e->prev; } if (e->prev) { e->prev->next = e->next; } if (e == *h) { if (e->next == NULL) { /* This entry is the head, and is the only entry in this chain. */ *h = NULL; } else { *h = e->next; } } e->prev = e->next = NULL; return; } /* Table key management */ static pr_table_key_t *tab_key_alloc(pr_table_t *tab) { pr_table_key_t *k; /* Try to find a free key on the free list first... */ if (tab->free_keys) { k = tab->free_keys; tab->free_keys = k->next; k->next = NULL; return k; } /* ...otherwise, allocate a new key. */ k = pcalloc(tab->pool, sizeof(pr_table_key_t)); return k; } static void tab_key_free(pr_table_t *tab, pr_table_key_t *k) { /* Clear everything from the given key. */ memset(k, 0, sizeof(pr_table_key_t)); /* Add this key to the table's free list. */ if (tab->free_keys) { pr_table_key_t *i = tab->free_keys; /* Scan to the end of the list. */ while (i->next != NULL) { if (!handling_signal) { pr_signals_handle(); } i = i->next; } i->next = k; } else tab->free_keys = k; } /* Table entry management */ static pr_table_entry_t *tab_entry_alloc(pr_table_t *tab) { pr_table_entry_t *e; /* Try to find a free entry on the free list first... */ if (tab->free_ents) { e = tab->free_ents; tab->free_ents = e->next; e->next = NULL; return e; } /* ...otherwise, allocate a new entry. */ e = pcalloc(tab->pool, sizeof(pr_table_entry_t)); return e; } static void tab_entry_free(pr_table_t *tab, pr_table_entry_t *e) { /* Clear everything from the given entry. */ memset(e, 0, sizeof(pr_table_entry_t)); /* Add this entry to the table's free list. */ if (tab->free_ents) { pr_table_entry_t *i = tab->free_ents; /* Scan to the end of the list. */ while (i->next != NULL) { if (!handling_signal) { pr_signals_handle(); } i = i->next; } i->next = e; } else tab->free_ents = e; } static void tab_entry_insert(pr_table_t *tab, pr_table_entry_t *e) { pr_table_entry_t *h = tab->chains[e->idx]; if (h && h != e) { /* Only insert the entry if the head we found is different from the * the given entry. There is an edge case when the entry being added * is the head of a new chain. */ tab->entinsert(&h, e); tab->chains[e->idx] = h; } e->key->nents++; tab->nents++; } static pr_table_entry_t *tab_entry_next(pr_table_t *tab) { pr_table_entry_t *ent = NULL; if (tab->tab_iter_ent) { ent = tab->tab_iter_ent->next; if (!ent) { register unsigned int i; /* Reset ent to be NULL, so that if we don't find a populated chain, * we properly return NULL to the caller. */ ent = NULL; /* Skip to the next populated chain. */ for (i = tab->tab_iter_ent->idx + 1; i < tab->nchains; i++) { if (tab->chains[i]) { ent = tab->chains[i]; break; } } } } else { register unsigned int i; /* Find the first non-empty chain. */ for (i = 0; i < tab->nchains; i++) { if (tab->chains[i]) { ent = tab->chains[i]; break; } } } tab->tab_iter_ent = ent; return ent; } static void tab_entry_remove(pr_table_t *tab, pr_table_entry_t *e) { pr_table_entry_t *h; h = tab->chains[e->idx]; tab->entremove(&h, e); tab->chains[e->idx] = h; e->key->nents--; if (e->key->nents == 0) { tab_key_free(tab, e->key); e->key = NULL; } tab->nents--; } static unsigned int tab_get_seed(void) { unsigned int seed = 0; #ifndef PR_USE_OPENSSL FILE *fp = NULL; size_t nitems = 0; #endif /* Not PR_USE_OPENSSL */ #ifdef PR_USE_OPENSSL if (RAND_bytes((unsigned char *) &seed, sizeof(seed)) != 1) { RAND_pseudo_bytes((unsigned char *) &seed, sizeof(seed)); } #else /* Try reading from /dev/urandom, if present */ fp = fopen("/dev/urandom", "rb"); if (fp != NULL) { nitems = fread(&seed, sizeof(seed), 1, fp); (void) fclose(fp); } if (nitems == 0) { time_t now = time(NULL); /* No /dev/urandom present (e.g. we might be in a chroot) or not able * to read the needed amount of data, but we still want a seed. Fallback * to using rand(3), PID, and current time. */ seed = (unsigned int) (rand() ^ getpid() ^ now); } #endif /* PR_USE_OPENSSL */ return seed; } /* Public Table API */ int pr_table_kadd(pr_table_t *tab, const void *key_data, size_t key_datasz, void *value_data, size_t value_datasz) { unsigned int h, idx; pr_table_entry_t *e, *n; if (tab == NULL || key_data == NULL || (value_datasz > 0 && value_data == NULL)) { errno = EINVAL; return -1; } if (tab->nents == tab->nmaxents) { /* Table is full. */ errno = ENOSPC; return -1; } /* Don't forget to add in the random seed data. */ h = tab->keyhash(key_data, key_datasz) + tab->seed; /* The index of the chain to use is the hash value modulo the number * of chains. */ idx = h % tab->nchains; /* Allocate a new entry for the given values. */ n = tab_entry_alloc(tab); n->value_data = value_data; n->value_datasz = value_datasz; n->idx = idx; /* Find the current chain entry at this index. */ e = tab->chains[idx]; if (e) { pr_table_entry_t *ei; /* There is a chain at this index. Next step is to see if any entry * on this chain has the exact same key. If so, increase the entry ref * count on that key, otherwise, create a new key. */ for (ei = e; ei; ei = ei->next) { if (ei->key->hash != h) continue; /* Hash collision. Now check if the key data that was hashed * is identical. If so, we have multiple values for the same key. */ if (tab->keycmp(ei->key->key_data, ei->key->key_datasz, key_data, key_datasz) == 0) { /* Check if this table allows multivalues. */ if (!(tab->flags & PR_TABLE_FL_MULTI_VALUE)) { errno = EEXIST; return -1; } else n->key = ei->key; } } } else { /* This new entry becomes the head of this chain. */ tab->chains[idx] = n; } if (!n->key) { pr_table_key_t *k; /* Allocate a new key. */ k = tab_key_alloc(tab); k->key_data = (void *) key_data; k->key_datasz = key_datasz; k->hash = h; k->nents = 0; n->key = k; } tab_entry_insert(tab, n); return 0; } int pr_table_kexists(pr_table_t *tab, const void *key_data, size_t key_datasz) { unsigned int h, idx; pr_table_entry_t *head, *ent; if (!tab || !key_data) { errno = EINVAL; return -1; } if (tab->nents == 0) { errno = ENOENT; return -1; } if (tab->flags & PR_TABLE_FL_USE_CACHE) { /* Has the caller already wanted to lookup this same key previously? * If so, reuse that lookup if we can. In this case, "same key" means * the _exact same pointer_, not identical data. */ if (tab->cache_ent && tab->cache_ent->key->key_data == key_data) return tab->cache_ent->key->nents; } /* Don't forget to add in the random seed data. */ h = tab->keyhash(key_data, key_datasz) + tab->seed; idx = h % tab->nchains; head = tab->chains[idx]; if (!head) { tab->cache_ent = NULL; return 0; } for (ent = head; ent; ent = ent->next) { if (ent->key == NULL || ent->key->hash != h) continue; /* Matching hashes. Now to see if the keys themselves match. */ if (tab->keycmp(ent->key->key_data, ent->key->key_datasz, key_data, key_datasz) == 0) { if (tab->flags & PR_TABLE_FL_USE_CACHE) tab->cache_ent = ent; return ent->key->nents; } } tab->cache_ent = NULL; errno = EINVAL; return 0; } void *pr_table_kget(pr_table_t *tab, const void *key_data, size_t key_datasz, size_t *value_datasz) { unsigned int h; pr_table_entry_t *head, *ent; if (!tab) { errno = EINVAL; return NULL; } /* Use a NULL key as a way of rewinding the per-key lookup. */ if (!key_data) { tab->cache_ent = NULL; tab->val_iter_ent = NULL; errno = ENOENT; return NULL; } if (tab->nents == 0) { tab->cache_ent = NULL; tab->val_iter_ent = NULL; errno = ENOENT; return NULL; } /* Don't forget to add in the random seed data. */ h = tab->keyhash(key_data, key_datasz) + tab->seed; /* Has the caller already looked up this same key previously? * If so, continue the lookup where we left off. In this case, * "same key" means the _exact same pointer_, not identical data. */ if (tab->val_iter_ent && tab->val_iter_ent->key->key_data == key_data) { head = tab->val_iter_ent->next; } else if ((tab->flags & PR_TABLE_FL_USE_CACHE) && tab->cache_ent && tab->cache_ent->key->key_data == key_data) { /* If the cached lookup entry matches, we'll use it. */ head = tab->cache_ent->next; } else { unsigned int idx = h % tab->nchains; head = tab->chains[idx]; } if (!head) { tab->cache_ent = NULL; tab->val_iter_ent = NULL; errno = ENOENT; return NULL; } for (ent = head; ent; ent = ent->next) { if (ent->key == NULL || ent->key->hash != h) continue; /* Matching hashes. Now to see if the keys themselves match. */ if (tab->keycmp(ent->key->key_data, ent->key->key_datasz, key_data, key_datasz) == 0) { if (tab->flags & PR_TABLE_FL_USE_CACHE) tab->cache_ent = ent; if (tab->flags & PR_TABLE_FL_MULTI_VALUE) tab->val_iter_ent = ent; if (value_datasz) *value_datasz = ent->value_datasz; return ent->value_data; } } tab->cache_ent = NULL; tab->val_iter_ent = NULL; errno = ENOENT; return NULL; } void *pr_table_kremove(pr_table_t *tab, const void *key_data, size_t key_datasz, size_t *value_datasz) { unsigned int h, idx; pr_table_entry_t *head, *ent; if (!tab || !key_data) { errno = EINVAL; return NULL; } if (tab->nents == 0) { errno = ENOENT; return NULL; } /* Has the caller already wanted to lookup this same key previously? * If so, reuse that lookup if we can. In this case, "same key" means * the _exact same pointer_, not identical data. */ if ((tab->flags & PR_TABLE_FL_USE_CACHE) && tab->cache_ent && tab->cache_ent->key->key_data == key_data) { void *value_data = tab->cache_ent->value_data; if (value_datasz) *value_datasz = tab->cache_ent->value_datasz; tab_entry_remove(tab, tab->cache_ent); tab_entry_free(tab, tab->cache_ent); tab->cache_ent = NULL; return value_data; } /* Don't forget to add in the random seed data. */ h = tab->keyhash(key_data, key_datasz) + tab->seed; idx = h % tab->nchains; head = tab->chains[idx]; if (!head) { tab->cache_ent = NULL; errno = ENOENT; return NULL; } for (ent = head; ent; ent = ent->next) { if (ent->key == NULL || ent->key->hash != h) continue; /* Matching hashes. Now to see if the keys themselves match. */ if (tab->keycmp(ent->key->key_data, ent->key->key_datasz, key_data, key_datasz) == 0) { void *value_data = ent->value_data; if (value_datasz) *value_datasz = ent->value_datasz; tab_entry_remove(tab, ent); tab_entry_free(tab, ent); tab->cache_ent = NULL; return value_data; } } tab->cache_ent = NULL; errno = EINVAL; return NULL; } int pr_table_kset(pr_table_t *tab, const void *key_data, size_t key_datasz, void *value_data, size_t value_datasz) { unsigned int h; pr_table_entry_t *head, *ent; /* XXX Should callers be allowed to set NULL values for keys? */ if (tab == NULL || key_data == NULL || (value_datasz > 0 && value_data == NULL)) { errno = EINVAL; return -1; } if (tab->nents == 0) { errno = ENOENT; return -1; } /* Don't forget to add in the random seed data. */ h = tab->keyhash(key_data, key_datasz) + tab->seed; /* Has the caller already looked up this same key previously? * If so, continue the lookup where we left off. In this case, * "same key" means the _exact same pointer_, not identical data. */ if (tab->val_iter_ent && tab->val_iter_ent->key->key_data == key_data) { head = tab->val_iter_ent->next; } else if ((tab->flags & PR_TABLE_FL_USE_CACHE) && tab->cache_ent && tab->cache_ent->key->key_data == key_data) { /* If the cached lookup entry matches, we'll use it. */ head = tab->cache_ent->next; } else { unsigned int idx = h % tab->nchains; head = tab->chains[idx]; } if (!head) { tab->cache_ent = NULL; tab->val_iter_ent = NULL; errno = ENOENT; return -1; } for (ent = head; ent; ent = ent->next) { if (ent->key == NULL || ent->key->hash != h) continue; /* Matching hashes. Now to see if the keys themselves match. */ if (tab->keycmp(ent->key->key_data, ent->key->key_datasz, key_data, key_datasz) == 0) { if (ent->value_data == value_data) { errno = EEXIST; return -1; } ent->value_data = value_data; ent->value_datasz = value_datasz; if (tab->flags & PR_TABLE_FL_USE_CACHE) tab->cache_ent = ent; if (tab->flags & PR_TABLE_FL_MULTI_VALUE) tab->val_iter_ent = ent; return 0; } } tab->cache_ent = NULL; tab->val_iter_ent = NULL; errno = EINVAL; return -1; } int pr_table_add(pr_table_t *tab, const char *key_data, void *value_data, size_t value_datasz) { if (tab == NULL || key_data == NULL) { errno = EINVAL; return -1; } if (value_data && value_datasz == 0) value_datasz = strlen((char *) value_data) + 1; return pr_table_kadd(tab, key_data, strlen(key_data) + 1, value_data, value_datasz); } int pr_table_add_dup(pr_table_t *tab, const char *key_data, void *value_data, size_t value_datasz) { void *dup_data; if (!tab || !key_data) { errno = EINVAL; return -1; } if (!value_data && value_datasz != 0) { errno = EINVAL; return -1; } if (value_data && value_datasz == 0) value_datasz = strlen((char *) value_data) + 1; dup_data = pcalloc(tab->pool, value_datasz); memcpy(dup_data, value_data, value_datasz); return pr_table_add(tab, key_data, dup_data, value_datasz); } pr_table_t *pr_table_nalloc(pool *p, int flags, unsigned int nchains) { pr_table_t *tab; pool *tab_pool; if (p == NULL || nchains == 0) { errno = EINVAL; return NULL; } tab_pool = make_sub_pool(p); pr_pool_tag(tab_pool, "table pool"); tab = pcalloc(tab_pool, sizeof(pr_table_t)); tab->pool = tab_pool; tab->flags = flags; tab->nchains = nchains; tab->chains = pcalloc(tab_pool, sizeof(pr_table_entry_t *) * tab->nchains); tab->keycmp = key_cmp; tab->keyhash = key_hash; tab->entinsert = entry_insert; tab->entremove = entry_remove; tab->seed = tab_get_seed(); tab->nmaxents = PR_TABLE_DEFAULT_MAX_ENTS; return tab; } pr_table_t *pr_table_alloc(pool *p, int flags) { return pr_table_nalloc(p, flags, PR_TABLE_DEFAULT_NCHAINS); } int pr_table_count(pr_table_t *tab) { if (!tab) { errno = EINVAL; return -1; } return tab->nents; } int pr_table_do(pr_table_t *tab, int (*cb)(const void *key_data, size_t key_datasz, void *value_data, size_t value_datasz, void *user_data), void *user_data, int flags) { register unsigned int i; if (!tab || !cb) { errno = EINVAL; return -1; } if (tab->nents == 0) return 0; for (i = 0; i < tab->nchains; i++) { pr_table_entry_t *ent = tab->chains[i]; while (ent) { int res; if (!handling_signal) { pr_signals_handle(); } res = cb(ent->key->key_data, ent->key->key_datasz, ent->value_data, ent->value_datasz, user_data); if (res < 0 && !(flags & PR_TABLE_DO_FL_ALL)) { errno = EPERM; return -1; } ent = ent->next; } } return 0; } int pr_table_empty(pr_table_t *tab) { register unsigned int i; if (!tab) { errno = EINVAL; return -1; } if (tab->nents == 0) return 0; for (i = 0; i < tab->nchains; i++) { pr_table_entry_t *e = tab->chains[i]; while (e) { if (!handling_signal) { pr_signals_handle(); } tab_entry_remove(tab, e); tab_entry_free(tab, e); e = tab->chains[i]; } tab->chains[i] = NULL; } return 0; } int pr_table_exists(pr_table_t *tab, const char *key_data) { if (!tab || !key_data) { errno = EINVAL; return -1; } return pr_table_kexists(tab, key_data, strlen(key_data) + 1); } int pr_table_free(pr_table_t *tab) { if (!tab) { errno = EINVAL; return -1; } if (tab->nents != 0) { errno = EPERM; return -1; } destroy_pool(tab->pool); return 0; } void *pr_table_get(pr_table_t *tab, const char *key_data, size_t *value_datasz) { size_t key_datasz = 0; if (!tab) { errno = EINVAL; return NULL; } if (key_data) key_datasz = strlen(key_data) + 1; return pr_table_kget(tab, key_data, key_datasz, value_datasz); } void *pr_table_next(pr_table_t *tab) { pr_table_entry_t *ent, *prev; if (!tab) { errno = EINVAL; return NULL; } prev = tab->tab_iter_ent; ent = tab_entry_next(tab); while (ent) { if (!handling_signal) { pr_signals_handle(); } if (prev && ent->key == prev->key) { ent = tab_entry_next(tab); continue; } break; } if (!ent) { errno = EPERM; return NULL; } return ent->key->key_data; } void *pr_table_remove(pr_table_t *tab, const char *key_data, size_t *value_datasz) { if (!tab || !key_data) { errno = EINVAL; return NULL; } return pr_table_kremove(tab, key_data, strlen(key_data) + 1, value_datasz); } int pr_table_rewind(pr_table_t *tab) { if (!tab) { errno = EINVAL; return -1; } tab->tab_iter_ent = NULL; return 0; } int pr_table_set(pr_table_t *tab, const char *key_data, void *value_data, size_t value_datasz) { if (!tab || !key_data) { errno = EINVAL; return -1; } if (value_data && value_datasz == 0) value_datasz = strlen((char *) value_data) + 1; return pr_table_kset(tab, key_data, strlen(key_data) + 1, value_data, value_datasz); } int pr_table_ctl(pr_table_t *tab, int cmd, void *arg) { if (!tab) { errno = EINVAL; return -1; } /* Set control operations can only be performed on an empty table. */ if (tab->nents != 0) { errno = EPERM; return -1; } switch (cmd) { case PR_TABLE_CTL_SET_KEY_HASH: tab->keyhash = arg ? (unsigned int (*)(const void *, size_t)) arg : (unsigned int (*)(const void *, size_t)) key_hash; return 0; case PR_TABLE_CTL_SET_FLAGS: if (!arg) { errno = EINVAL; return -1; } tab->flags = *((unsigned long *) arg); return 0; case PR_TABLE_CTL_SET_KEY_CMP: tab->keycmp = arg ? (int (*)(const void *, size_t, const void *, size_t)) arg : (int (*)(const void *, size_t, const void *, size_t)) key_cmp; return 0; case PR_TABLE_CTL_SET_ENT_INSERT: tab->entinsert = arg ? (void (*)(pr_table_entry_t **, pr_table_entry_t *)) arg : (void (*)(pr_table_entry_t **, pr_table_entry_t *)) entry_insert; return 0; case PR_TABLE_CTL_SET_ENT_REMOVE: tab->entremove = arg ? (void (*)(pr_table_entry_t **, pr_table_entry_t *)) arg : (void (*)(pr_table_entry_t **, pr_table_entry_t *)) entry_remove; return 0; case PR_TABLE_CTL_SET_NCHAINS: { unsigned int new_nchains; if (arg == NULL) { errno = EINVAL; return -1; } new_nchains = *((unsigned int *) arg); if (new_nchains == 0) { errno = EINVAL; return -1; } tab->nchains = new_nchains; /* Note: by not freeing the memory of the previously allocated * chains, this constitutes a minor leak of the table's memory pool. */ tab->chains = pcalloc(tab->pool, sizeof(pr_table_entry_t *) * tab->nchains); return 0; } case PR_TABLE_CTL_SET_MAX_ENTS: { unsigned int nmaxents; nmaxents = *((unsigned int *) arg); if (nmaxents == 0) { errno = EINVAL; return -1; } /* If the given maximum is less than the number of entries currently * in the table, we have to return an error; we do not want to get * into the business of table truncation just yet. */ if (tab->nents > nmaxents) { errno = EPERM; return -1; } tab->nmaxents = nmaxents; return 0; } default: errno = EINVAL; } return -1; } void *pr_table_pcalloc(pr_table_t *tab, size_t sz) { if (!tab || sz == 0) { errno = EINVAL; return NULL; } return pcalloc(tab->pool, sz); } static void table_printf(const char *fmt, ...) { char buf[PR_TUNABLE_BUFFER_SIZE+1]; va_list msg; memset(buf, '\0', sizeof(buf)); va_start(msg, fmt); vsnprintf(buf, sizeof(buf)-1, fmt, msg); va_end(msg); buf[sizeof(buf)-1] = '\0'; pr_trace_msg(trace_channel, 19, "dump: %s", buf); } float pr_table_load(pr_table_t *tab) { float load_factor; if (tab == NULL) { errno = EINVAL; return -1.0; } load_factor = (tab->nents / tab->nchains); return load_factor; } void pr_table_dump(void (*dumpf)(const char *fmt, ...), pr_table_t *tab) { register unsigned int i; if (tab == NULL) { return; } if (dumpf == NULL) { dumpf = table_printf; } if (tab->flags == 0) { dumpf("%s", "[table flags]: None"); } else { if ((tab->flags & PR_TABLE_FL_MULTI_VALUE) && (tab->flags & PR_TABLE_FL_USE_CACHE)) { dumpf("%s", "[table flags]: MultiValue, UseCache"); } else { if (tab->flags & PR_TABLE_FL_MULTI_VALUE) dumpf("%s", "[table flags]: MultiValue"); if (tab->flags & PR_TABLE_FL_USE_CACHE) dumpf("%s", "[table flags]: UseCache"); } } if (tab->nents == 0) { dumpf("[empty table]"); return; } else dumpf("[table count]: %u", tab->nents); for (i = 0; i < tab->nchains; i++) { register unsigned int j = 0; pr_table_entry_t *ent = tab->chains[i]; while (ent) { if (!handling_signal) { pr_signals_handle(); } dumpf("[hash %u (%u chains) chain %u#%u] '%s' => '%s' (%u)", ent->key->hash, tab->nchains, i, j++, ent->key->key_data, ent->value_data, ent->value_datasz); ent = ent->next; } } return; } int table_handling_signal(int bool) { if (bool == TRUE || bool == FALSE) { handling_signal = bool; return 0; } errno = EINVAL; return -1; } proftpd-dfsg-1.3.5~rc3/src/proctitle.c0000644000175000017500000002022111742606637017516 0ustar frankiefrankie/* * ProFTPD - FTP server daemon * Copyright (c) 2007-2012 The ProFTPD Project team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * As a special exemption, The ProFTPD Project team and other respective * copyright holders give permission to link this program with OpenSSL, and * distribute the resulting executable, without including the source code for * OpenSSL in the source distribution. */ /* Proctitle management * $Id: proctitle.c,v 1.13 2012/04/15 18:04:15 castaglia Exp $ */ #include "conf.h" #if PF_ARGV_TYPE == PF_ARGV_PSTAT # ifdef HAVE_SYS_PSTAT_H # include # else # undef PF_ARGV_TYPE # define PF_ARGV_TYPE PF_ARGV_WRITEABLE # endif /* HAVE_SYS_PSTAT_H */ #endif /* PF_ARGV_PSTAT */ #if PF_ARGV_TYPE == PF_ARGV_PSSTRINGS # ifndef HAVE_SYS_EXEC_H # undef PF_ARGV_TYPE # define PF_ARGV_TYPE PF_ARGV_WRITEABLE # else # include # include # endif /* HAVE_SYS_EXEC_H */ #endif /* PF_ARGV_PSSTRINGS */ #ifdef HAVE___PROGNAME extern char *__progname, *__progname_full; #endif /* HAVE___PROGNAME */ extern char **environ; #ifndef PR_DEVEL_STACK_TRACE static char **prog_argv = NULL; static char *prog_last_argv = NULL; #endif /* PR_DEVEL_STACK_TRACE */ static int prog_argc = -1; static char proc_title_buf[BUFSIZ]; static unsigned int proc_flags = 0; #define PR_PROCTITLE_FL_USE_STATIC 0x001 void pr_proctitle_init(int argc, char *argv[], char *envp[]) { #ifndef PR_DEVEL_STACK_TRACE register int i; register size_t envpsize; char **p; /* Move the environment so setproctitle can use the space. */ for (i = envpsize = 0; envp[i] != NULL; i++) envpsize += strlen(envp[i]) + 1; if ((p = (char **) malloc((i + 1) * sizeof(char *))) != NULL) { environ = p; for (i = 0; envp[i] != NULL; i++) { size_t envp_len = strlen(envp[i]); if (envp_len > PR_TUNABLE_ENV_MAX) { /* Skip any environ variables that are too long. */ continue; } environ[i] = malloc(envp_len + 1); if (environ[i] != NULL) { sstrncpy(environ[i], envp[i], envp_len + 1); } } environ[i] = NULL; } prog_argv = argv; prog_argc = argc; for (i = 0; i < prog_argc; i++) { if (!i || (prog_last_argv + 1 == argv[i])) prog_last_argv = argv[i] + strlen(argv[i]); } for (i = 0; envp[i] != NULL; i++) { if ((prog_last_argv + 1) == envp[i]) prog_last_argv = envp[i] + strlen(envp[i]); } # ifdef HAVE___PROGNAME /* Set the __progname and __progname_full variables so glibc and company * don't go nuts. */ __progname = strdup("proftpd"); __progname_full = strdup(argv[0]); # endif /* HAVE___PROGNAME */ #else /* Silence compiler warning about unused variable when stacktrace * developer mode is configured. */ prog_argc = -1; #endif /* !PR_DEVEL_STACK_TRACE */ memset(proc_title_buf, '\0', sizeof(proc_title_buf)); } void pr_proctitle_free(void) { #ifdef PR_USE_DEVEL # ifndef PR_DEVEL_STACK_TRACE if (environ) { register unsigned int i; for (i = 0; environ[i] != NULL; i++) free(environ[i]); free(environ); environ = NULL; } # ifdef HAVE___PROGNAME free(__progname); __progname = NULL; free(__progname_full); __progname_full = NULL; # endif /* HAVE___PROGNAME */ # endif /* !PR_DEVEL_STACK_TRACE */ #endif /* PR_USE_DEVEL */ } void pr_proctitle_set_str(const char *str) { #ifndef PR_DEVEL_STACK_TRACE # ifndef HAVE_SETPROCTITLE char *p; int i, procbuflen, maxlen = (prog_last_argv - prog_argv[0]) - 2; # if PF_ARGV_TYPE == PF_ARGV_PSTAT union pstun pst; # endif /* PF_ARGV_PSTAT */ if (proc_flags & PR_PROCTITLE_FL_USE_STATIC) { return; } sstrncpy(proc_title_buf, str, sizeof(proc_title_buf)); procbuflen = strlen(proc_title_buf); # if PF_ARGV_TYPE == PF_ARGV_NEW /* We can just replace argv[] arguments. Nice and easy. */ prog_argv[0] = proc_title_buf; for (i = 1; i < prog_argc; i++) { prog_argv[i] = ""; } # endif /* PF_ARGV_NEW */ # if PF_ARGV_TYPE == PF_ARGV_WRITEABLE /* We can overwrite individual argv[] arguments. Semi-nice. */ snprintf(prog_argv[0], maxlen, "%s", proc_title_buf); p = &prog_argv[0][procbuflen]; while (p < prog_last_argv) *p++ = '\0'; for (i = 1; i < prog_argc; i++) { prog_argv[i] = ""; } # endif /* PF_ARGV_WRITEABLE */ # if PF_ARGV_TYPE == PF_ARGV_PSSTRINGS PS_STRINGS->ps_nargvstr = 1; PS_STRINGS->ps_argvstr = proc_title_buf; # endif /* PF_ARGV_PSSTRINGS */ # else if (proc_flags & PR_PROCTITLE_FL_USE_STATIC) { return; } setproctitle("%s", str); # endif /* HAVE_SETPROCTITLE */ #endif /* PR_DEVEL_STACK_TRACE */ } void pr_proctitle_set(const char *fmt, ...) { #ifndef PR_DEVEL_STACK_TRACE va_list msg; # ifndef HAVE_SETPROCTITLE # if PF_ARGV_TYPE == PF_ARGV_PSTAT union pstun pst; # endif /* PF_ARGV_PSTAT */ char *p; int i, procbuflen, maxlen = (prog_last_argv - prog_argv[0]) - 2; # endif /* HAVE_SETPROCTITLE */ if (proc_flags & PR_PROCTITLE_FL_USE_STATIC) { return; } if (!fmt) return; va_start(msg, fmt); memset(proc_title_buf, 0, sizeof(proc_title_buf)); # ifdef HAVE_SETPROCTITLE # if __FreeBSD__ >= 4 && !defined(FREEBSD4_0) && !defined(FREEBSD4_1) /* FreeBSD's setproctitle() automatically prepends the process name. */ vsnprintf(proc_title_buf, sizeof(proc_title_buf), fmt, msg); # else /* FREEBSD4 */ /* Manually append the process name for non-FreeBSD platforms. */ snprintf(proc_title_buf, sizeof(proc_title_buf), "%s", "proftpd: "); vsnprintf(proc_title_buf + strlen(proc_title_buf), sizeof(proc_title_buf) - strlen(proc_title_buf), fmt, msg); # endif /* FREEBSD4 */ setproctitle("%s", proc_title_buf); # else /* HAVE_SETPROCTITLE */ /* Manually append the process name for non-setproctitle() platforms. */ snprintf(proc_title_buf, sizeof(proc_title_buf), "%s", "proftpd: "); vsnprintf(proc_title_buf + strlen(proc_title_buf), sizeof(proc_title_buf) - strlen(proc_title_buf), fmt, msg); # endif /* HAVE_SETPROCTITLE */ va_end(msg); # ifdef HAVE_SETPROCTITLE return; # else procbuflen = strlen(proc_title_buf); # if PF_ARGV_TYPE == PF_ARGV_NEW /* We can just replace argv[] arguments. Nice and easy. */ prog_argv[0] = proc_title_buf; for (i = 1; i < prog_argc; i++) { prog_argv[i] = ""; } # endif /* PF_ARGV_NEW */ # if PF_ARGV_TYPE == PF_ARGV_WRITEABLE /* We can overwrite individual argv[] arguments. Semi-nice. */ snprintf(prog_argv[0], maxlen, "%s", proc_title_buf); p = &prog_argv[0][procbuflen]; while (p < prog_last_argv) *p++ = '\0'; for (i = 1; i < prog_argc; i++) { prog_argv[i] = ""; } # endif /* PF_ARGV_WRITEABLE */ # if PF_ARGV_TYPE == PF_ARGV_PSTAT pst.pst_command = proc_title_buf; pstat(PSTAT_SETCMD, pst, procbuflen, 0, 0); # endif /* PF_ARGV_PSTAT */ # if PF_ARGV_TYPE == PF_ARGV_PSSTRINGS PS_STRINGS->ps_nargvstr = 1; PS_STRINGS->ps_argvstr = proc_title_buf; # endif /* PF_ARGV_PSSTRINGS */ # endif /* HAVE_SETPROCTITLE */ #endif /* !PR_DEVEL_STACK_TRACE */ } void pr_proctitle_set_static_str(const char *buf) { if (buf != NULL) { pr_proctitle_set_str(buf); proc_flags |= PR_PROCTITLE_FL_USE_STATIC; } else { /* Reset. */ proc_flags = 0; } } int pr_proctitle_get(char *buf, size_t bufsz) { if (buf == NULL || bufsz == 0) { /* If the caller didn't provide an input buffer, they are simply * querying for the length of the current process title. Easy enough * to acquiesce to that request. */ return strlen(proc_title_buf); } sstrncpy(buf, proc_title_buf, bufsz); return strlen(buf); } proftpd-dfsg-1.3.5~rc3/src/session.c0000644000175000017500000002743311742606637017210 0ustar frankiefrankie/* * ProFTPD - FTP server daemon * Copyright (c) 2009-2012 The ProFTPD Project team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * As a special exemption, The ProFTPD Project team and other respective * copyright holders give permission to link this program with OpenSSL, and * distribute the resulting executable, without including the source code for * OpenSSL in the source distribution. * * $Id: session.c,v 1.15 2012/04/15 18:04:15 castaglia Exp $ */ #include "conf.h" /* From src/main.c */ extern unsigned char is_master; static void sess_cleanup(int flags) { /* Clear the scoreboard entry. */ if (ServerType == SERVER_STANDALONE) { /* For standalone daemons, we only clear the scoreboard slot if we are * an exiting child process. */ if (!is_master) { if (pr_scoreboard_entry_del(TRUE) < 0 && errno != EINVAL && errno != ENOENT) { pr_log_debug(DEBUG1, "error deleting scoreboard entry: %s", strerror(errno)); } } } else if (ServerType == SERVER_INETD) { /* For inetd-spawned daemons, we always clear the scoreboard slot. */ if (pr_scoreboard_entry_del(TRUE) < 0 && errno != EINVAL && errno != ENOENT) { pr_log_debug(DEBUG1, "error deleting scoreboard entry: %s", strerror(errno)); } } /* If session.user is set, we have a valid login. */ if (session.user && session.wtmp_log) { const char *sess_ttyname; sess_ttyname = pr_session_get_ttyname(session.pool); log_wtmp(sess_ttyname, "", pr_netaddr_get_sess_remote_name(), pr_netaddr_get_sess_remote_addr()); } /* These are necessary in order that cleanups associated with these pools * (and their subpools) are properly run. */ if (session.d) { pr_inet_close(session.pool, session.d); session.d = NULL; } if (session.c) { pr_inet_close(session.pool, session.c); session.c = NULL; } /* Run all the exit handlers */ pr_event_generate("core.exit", NULL); if (!is_master || (ServerType == SERVER_INETD && !(flags & PR_SESS_END_FL_SYNTAX_CHECK))) { pr_log_pri(PR_LOG_INFO, "%s session closed.", pr_session_get_protocol(PR_SESS_PROTO_FL_LOGOUT)); } log_closesyslog(); } void pr_session_disconnect(module *m, int reason_code, const char *details) { session.disconnect_reason = reason_code; session.disconnect_module = m; if (details != NULL && session.notes != NULL) { /* Stash any extra details in the session.notes table */ if (pr_table_add_dup(session.notes, "core.disconnect-details", (char *) details, 0) < 0) { int xerrno = errno; if (xerrno != EEXIST) { pr_log_debug(DEBUG5, "error stashing 'core.disconnect-details' in " "session.notes: %s", strerror(xerrno)); } } } pr_session_end(0); } void pr_session_end(int flags) { int exitcode = 0; sess_cleanup(flags); if (flags & PR_SESS_END_FL_NOEXIT) { return; } #ifdef PR_USE_DEVEL destroy_pool(session.pool); if (is_master) { main_server = NULL; free_pools(); pr_proctitle_free(); } #endif /* PR_USE_DEVEL */ #ifdef PR_DEVEL_PROFILE /* Populating the gmon.out gprof file requires that the process exit * via exit(3) or by returning from main(). Using _exit(2) doesn't allow * the process the time to write its profile data out. */ exit(exitcode); #else _exit(exitcode); #endif /* PR_DEVEL_PROFILE */ } const char *pr_session_get_disconnect_reason(char **details) { const char *reason_str = NULL; switch (session.disconnect_reason) { case PR_SESS_DISCONNECT_UNSPECIFIED: reason_str = "Unknown/unspecified"; break; case PR_SESS_DISCONNECT_CLIENT_QUIT: reason_str = "Quit"; break; case PR_SESS_DISCONNECT_CLIENT_EOF: reason_str = "Read EOF from client"; break; case PR_SESS_DISCONNECT_SESSION_INIT_FAILED: reason_str = "Session initialized failed"; break; case PR_SESS_DISCONNECT_SIGNAL: reason_str = "Terminated by signal"; break; case PR_SESS_DISCONNECT_NOMEM: reason_str = "Low memory"; break; case PR_SESS_DISCONNECT_SERVER_SHUTDOWN: reason_str = "Server shutting down"; break; case PR_SESS_DISCONNECT_TIMEOUT: reason_str = "Timeout exceeded"; break; case PR_SESS_DISCONNECT_BANNED: reason_str = "Banned"; break; case PR_SESS_DISCONNECT_CONFIG_ACL: reason_str = "Configured policy"; break; case PR_SESS_DISCONNECT_MODULE_ACL: reason_str = "Module-specific policy"; break; case PR_SESS_DISCONNECT_BAD_CONFIG: reason_str = "Server misconfiguration"; break; case PR_SESS_DISCONNECT_BY_APPLICATION: reason_str = "Application error"; break; } if (details != NULL) { *details = pr_table_get(session.notes, "core.disconnect-details", NULL); } return reason_str; } const char *pr_session_get_protocol(int flags) { const char *sess_proto; sess_proto = pr_table_get(session.notes, "protocol", NULL); if (sess_proto == NULL) { sess_proto = "ftp"; } if (!(flags & PR_SESS_PROTO_FL_LOGOUT)) { /* Return the protocol as is. */ return sess_proto; } /* Otherwise, we need to return either "FTP" or "SSH2", for consistency. */ if (strncmp(sess_proto, "ftp", 4) == 0 || strncmp(sess_proto, "ftps", 5) == 0) { return "FTP"; } else if (strncmp(sess_proto, "ssh2", 5) == 0 || strncmp(sess_proto, "sftp", 5) == 0 || strncmp(sess_proto, "scp", 4) == 0 || strncmp(sess_proto, "publickey", 10) == 0) { return "SSH2"; } /* Should never reach here, but just in case... */ return "unknown"; } void pr_session_send_banner(server_rec *s, int flags) { config_rec *c = NULL; char *display = NULL; const char *serveraddress = NULL; config_rec *masq = NULL; display = get_param_ptr(s->conf, "DisplayConnect", FALSE); if (display != NULL) { if (pr_display_file(display, NULL, R_220, flags) < 0) { pr_log_debug(DEBUG6, "unable to display DisplayConnect file '%s': %s", display, strerror(errno)); } } serveraddress = pr_netaddr_get_ipstr(session.c->local_addr); masq = find_config(s->conf, CONF_PARAM, "MasqueradeAddress", FALSE); if (masq != NULL) { pr_netaddr_t *masq_addr = (pr_netaddr_t *) masq->argv[0]; serveraddress = pr_netaddr_get_ipstr(masq_addr); } c = find_config(s->conf, CONF_PARAM, "ServerIdent", FALSE); if (c == NULL || *((unsigned char *) c->argv[0]) == TRUE) { unsigned char *defer_welcome; defer_welcome = get_param_ptr(s->conf, "DeferWelcome", FALSE); if (c && c->argc > 1) { char *server_ident = c->argv[1]; if (strstr(server_ident, "%L") != NULL) { server_ident = sreplace(session.pool, server_ident, "%L", pr_netaddr_get_ipstr(session.c->local_addr), NULL); } if (strstr(server_ident, "%V") != NULL) { server_ident = sreplace(session.pool, server_ident, "%V", main_server->ServerFQDN, NULL); } if (strstr(server_ident, "%v") != NULL) { server_ident = sreplace(session.pool, server_ident, "%v", main_server->ServerName, NULL); } if (flags & PR_DISPLAY_FL_SEND_NOW) { pr_response_send(R_220, "%s", server_ident); } else { pr_response_add(R_220, "%s", server_ident); } } else if (defer_welcome && *defer_welcome == TRUE) { if (flags & PR_DISPLAY_FL_SEND_NOW) { pr_response_send(R_220, "ProFTPD " PROFTPD_VERSION_TEXT " Server ready."); } else { pr_response_add(R_220, "ProFTPD " PROFTPD_VERSION_TEXT " Server ready."); } } else { if (flags & PR_DISPLAY_FL_SEND_NOW) { pr_response_send(R_220, "ProFTPD " PROFTPD_VERSION_TEXT " Server (%s) [%s]", s->ServerName, serveraddress); } else { pr_response_add(R_220, "ProFTPD " PROFTPD_VERSION_TEXT " Server (%s) [%s]", s->ServerName, serveraddress); } } } else { if (flags & PR_DISPLAY_FL_SEND_NOW) { pr_response_send(R_220, _("%s FTP server ready"), serveraddress); } else { pr_response_add(R_220, _("%s FTP server ready"), serveraddress); } } } int pr_session_set_idle(void) { char *user = NULL; pr_scoreboard_entry_update(session.pid, PR_SCORE_BEGIN_IDLE, time(NULL), PR_SCORE_CMD, "%s", "idle", NULL, NULL); pr_scoreboard_entry_update(session.pid, PR_SCORE_CMD_ARG, "%s", "", NULL, NULL); if (session.user) { user = session.user; } else { user = "(authenticating)"; } pr_proctitle_set("%s - %s: IDLE", user, session.proc_prefix); return 0; } int pr_session_set_protocol(const char *sess_proto) { int count, res; if (sess_proto == NULL) { errno = EINVAL; return -1; } count = pr_table_exists(session.notes, "protocol"); if (count > 0) { res = pr_table_set(session.notes, pstrdup(session.pool, "protocol"), pstrdup(session.pool, sess_proto), 0); if (res == 0) { /* Update the scoreboard entry for this session with the protocol. */ pr_scoreboard_entry_update(session.pid, PR_SCORE_PROTOCOL, sess_proto, NULL); } return res; } res = pr_table_add(session.notes, pstrdup(session.pool, "protocol"), pstrdup(session.pool, sess_proto), 0); if (res == 0) { /* Update the scoreboard entry for this session with the protocol. */ pr_scoreboard_entry_update(session.pid, PR_SCORE_PROTOCOL, sess_proto, NULL); } return res; } static const char *sess_ttyname = NULL; const char *pr_session_get_ttyname(pool *p) { char ttybuf[32]; const char *sess_proto, *tty_proto = NULL; if (p == NULL) { errno = EINVAL; return NULL; } if (sess_ttyname) { /* Return the cached name. */ return pstrdup(p, sess_ttyname); } sess_proto = pr_table_get(session.notes, "protocol", NULL); if (sess_proto) { if (strncmp(sess_proto, "ftp", 4) == 0 || strncmp(sess_proto, "ftps", 5) == 0) { #if (defined(BSD) && (BSD >= 199103)) tty_proto = "ftp"; #else tty_proto = "ftpd"; #endif } else if (strncmp(sess_proto, "ssh2", 5) == 0 || strncmp(sess_proto, "sftp", 5) == 0 || strncmp(sess_proto, "scp", 4) == 0 || strncmp(sess_proto, "publickey", 10) == 0) { /* Just use the plain "ssh" string for the tty name for these cases. */ tty_proto = "ssh"; /* Cache the originally constructed tty name for any later retrievals. */ sess_ttyname = pstrdup(session.pool, tty_proto); return pstrdup(p, sess_ttyname); } } if (tty_proto == NULL) { #if (defined(BSD) && (BSD >= 199103)) tty_proto = "ftp"; #else tty_proto = "ftpd"; #endif } memset(ttybuf, '\0', sizeof(ttybuf)); #if (defined(BSD) && (BSD >= 199103)) snprintf(ttybuf, sizeof(ttybuf), "%s%ld", tty_proto, (long) (session.pid ? session.pid : getpid())); #else snprintf(ttybuf, sizeof(ttybuf), "%s%d", tty_proto, (int) (session.pid ? session.pid : getpid())); #endif /* Cache the originally constructed tty name for any later retrievals. */ sess_ttyname = pstrdup(session.pool, ttybuf); return pstrdup(p, sess_ttyname); } proftpd-dfsg-1.3.5~rc3/src/proftpd.conf.5.in0000644000175000017500000000242712021707642020437 0ustar frankiefrankie.TH proftpd.conf 5 .SH NAME proftpd.conf \- ProFTPD server configuration file .SH DESCRIPTION .PP The .B proftpd(8) daemon reads its configuration file, typically stored in one of the following locations: .LP .I /etc/proftpd.conf .br .I /etc/proftpd/proftpd.conf .br .I /usr/local/etc/proftpd.conf .TP or passed to proftpd with the -c command-line option. .PP The .B proftpd.conf configuration file contains .I directives , one per line. Lines starting with # and empty lines are comments and are ignored. Directives are case-insensitive, whereas values are case-sensitive. Values may be enclosed in double-quotes (") if they contain spaces. .PP The possible directives and their descriptions are described online at .BR http://www.proftpd.org/docs/directives/linked/by-name.html .RE .SH FILES .PD 0 .B @SBINDIR@/proftpd .br .B @SYSCONFDIR@/proftpd.conf .PP .PD .SH AUTHORS .PP ProFTPD is written and maintained by a number of people, full credits can be found on .BR http://www.proftpd.org/credits.html .PD .SH "SEE ALSO" .BR proftpd(8) .PP Full documentation on ProFTPD, including configuration and FAQs, is available at .BR http://www.proftpd.org/ .PP For help/support, try the ProFTPD mailing lists, detailed on .BR http://www.proftpd.org/lists.html .PP Report bugs at .BR http://bugs.proftpd.org/ proftpd-dfsg-1.3.5~rc3/src/parser.c0000644000175000017500000004361412111071400016767 0ustar frankiefrankie/* * ProFTPD - FTP server daemon * Copyright (c) 2004-2013 The ProFTPD Project team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * As a special exemption, The ProFTPD Project team and other respective * copyright holders give permission to link this program with OpenSSL, and * distribute the resulting executable, without including the source code * for OpenSSL in the source distribution. */ /* Configuration parser * $Id: parser.c,v 1.38 2013/02/20 06:53:52 castaglia Exp $ */ #include "conf.h" extern xaset_t *server_list; extern pool *global_config_pool; static pool *parser_pool = NULL; static array_header *parser_confstack = NULL; static config_rec **parser_curr_config = NULL; static array_header *parser_servstack = NULL; static server_rec **parser_curr_server = NULL; static unsigned int parser_sid = 1; static xaset_t **parser_server_list = NULL; static const char *trace_channel = "config"; struct config_src { struct config_src *cs_next; pool *cs_pool; pr_fh_t *cs_fh; unsigned int cs_lineno; }; static unsigned int parser_curr_lineno = 0; /* Note: the parser seems to be touchy about this particular value. If * you see strange segfaults occurring in the mergedown() function, it * might be because this pool size is too small. */ #define PARSER_CONFIG_SRC_POOL_SZ 512 static struct config_src *parser_sources = NULL; /* Private functions */ static void add_config_ctxt(config_rec *c) { if (!*parser_curr_config) *parser_curr_config = c; else { parser_curr_config = (config_rec **) push_array(parser_confstack); *parser_curr_config = c; } } static struct config_src *add_config_source(pr_fh_t *fh) { pool *p = pr_pool_create_sz(parser_pool, PARSER_CONFIG_SRC_POOL_SZ); struct config_src *cs = pcalloc(p, sizeof(struct config_src)); pr_pool_tag(p, "configuration source pool"); cs->cs_next = NULL; cs->cs_pool = p; cs->cs_fh = fh; cs->cs_lineno = 0; if (!parser_sources) parser_sources = cs; else { cs->cs_next = parser_sources; parser_sources = cs; } return cs; } static char *get_config_word(pool *p, char *word) { size_t wordlen; /* Should this word be replaced with a value from the environment? * If so, tmp will contain the expanded value, otherwise tmp will * contain a string duped from the given pool. */ wordlen = strlen(word); if (wordlen > 7) { char *ptr = NULL; /* Does the given word use the environment syntax? * * In the simple (and most common) case, the entire word is the variable * syntax. But we also need to check for cases where the environment * variable syntax is embedded within the word string. */ if (strncmp(word, "%{env:", 6) == 0 && word[wordlen-1] == '}') { char *env; word[wordlen-1] = '\0'; env = pr_env_get(p, word + 6); return env ? pstrdup(p, env) : ""; } /* This is in a while loop in order to handle a) multiple different * variables, and b) cases where the substituted value is itself a * variable. (Hopefully no one is so clever as to want to actually * _use_ the latter approach.) */ ptr = strstr(word, "%{env:"); while (ptr != NULL) { char *env, *key, *ptr2, *var; unsigned int keylen; pr_signals_handle(); ptr2 = strchr(ptr + 6, '}'); if (ptr2 == NULL) { /* No terminating marker; continue on to the next potential * variable in the word. */ ptr2 = ptr + 6; ptr = strstr(ptr2, "%{env:"); continue; } keylen = (ptr2 - ptr - 6); var = pstrndup(p, ptr, (ptr2 - ptr) + 1); key = pstrndup(p, ptr + 6, keylen); env = pr_env_get(p, key); if (env == NULL) { /* No value in the environment; continue on to the next potential * variable in the word. */ ptr = strstr(ptr2, "%{env:"); continue; } word = sreplace(p, word, var, env, NULL); ptr = strstr(word, "%{env:"); } } return pstrdup(p, word); } static void remove_config_source(void) { struct config_src *cs = parser_sources; if (cs) { parser_sources = cs->cs_next; destroy_pool(cs->cs_pool); } return; } /* Public API */ int pr_parser_cleanup(void) { if (parser_pool) { if (parser_servstack->nelts > 1 || (parser_curr_config && *parser_curr_config)) { errno = EPERM; return -1; } destroy_pool(parser_pool); parser_pool = NULL; } parser_servstack = NULL; parser_curr_server = NULL; parser_confstack = NULL; parser_curr_config = NULL; /* Reset the SID counter. */ parser_sid = 1; return 0; } config_rec *pr_parser_config_ctxt_close(int *empty) { config_rec *c = *parser_curr_config; /* Note that if the current config is empty, it should simply be removed. * Such empty configs can happen for sections that * contain no directives, for example. */ if (parser_curr_config == (config_rec **) parser_confstack->elts) { if (c != NULL && (!c->subset || !c->subset->xas_list)) { xaset_remove(c->set, (xasetmember_t *) c); destroy_pool(c->pool); if (empty) { *empty = TRUE; } } if (*parser_curr_config) { *parser_curr_config = NULL; } return NULL; } if (c != NULL && (!c->subset || !c->subset->xas_list)) { xaset_remove(c->set, (xasetmember_t *) c); destroy_pool(c->pool); if (empty) { *empty = TRUE; } } parser_curr_config--; parser_confstack->nelts--; return *parser_curr_config; } config_rec *pr_parser_config_ctxt_get(void) { if (parser_curr_config) return *parser_curr_config; errno = ENOENT; return NULL; } config_rec *pr_parser_config_ctxt_open(const char *name) { config_rec *c = NULL, *parent = *parser_curr_config; pool *c_pool = NULL, *parent_pool = NULL; xaset_t **set = NULL; if (!name) { errno = EINVAL; return NULL; } if (parent) { parent_pool = parent->pool; set = &parent->subset; } else { parent_pool = (*parser_curr_server)->pool; set = &(*parser_curr_server)->conf; } /* Allocate a sub-pool for this config_rec. * * Note: special exception for configs: the parent pool is * 'global_config_pool' (a pool just for that context), not the pool of the * parent server. This keeps config recs from being freed * prematurely, and helps to avoid memory leaks. */ if (strncasecmp(name, "", 9) == 0) { if (!global_config_pool) { global_config_pool = make_sub_pool(permanent_pool); pr_pool_tag(global_config_pool, " Pool"); } parent_pool = global_config_pool; } c_pool = make_sub_pool(parent_pool); pr_pool_tag(c_pool, "sub-config pool"); c = (config_rec *) pcalloc(c_pool, sizeof(config_rec)); if (!*set) { pool *set_pool = make_sub_pool(parent_pool); *set = xaset_create(set_pool, NULL); (*set)->pool = set_pool; } xaset_insert(*set, (xasetmember_t *) c); c->pool = c_pool; c->set = *set; c->parent = parent; c->name = pstrdup(c->pool, name); if (parent) { if (parent->config_type == CONF_DYNDIR) c->flags |= CF_DYNAMIC; } add_config_ctxt(c); return c; } unsigned int pr_parser_get_lineno(void) { return parser_curr_lineno; } int pr_parser_parse_file(pool *p, const char *path, config_rec *start, int flags) { pr_fh_t *fh; struct stat st; struct config_src *cs; cmd_rec *cmd; pool *tmp_pool; char *report_path; if (path == NULL) { errno = EINVAL; return -1; } tmp_pool = make_sub_pool(p ? p : permanent_pool); pr_pool_tag(tmp_pool, "parser file pool"); report_path = (char *) path; if (session.chroot_path) report_path = pdircat(tmp_pool, session.chroot_path, path, NULL); if (!(flags & PR_PARSER_FL_DYNAMIC_CONFIG)) pr_trace_msg(trace_channel, 3, "parsing '%s' configuration", report_path); fh = pr_fsio_open(path, O_RDONLY); if (fh == NULL) { int xerrno = errno; destroy_pool(tmp_pool); errno = xerrno; return -1; } /* Stat the opened file to determine the optimal buffer size for IO. */ memset(&st, 0, sizeof(st)); if (pr_fsio_fstat(fh, &st) < 0) { int xerrno = errno; pr_fsio_close(fh); destroy_pool(tmp_pool); errno = xerrno; return -1; } if (S_ISDIR(st.st_mode)) { pr_fsio_close(fh); destroy_pool(tmp_pool); errno = EISDIR; return -1; } /* Check for world-writable files (and later, files in world-writable * directories). * * For now, just warn about these; later, we will be more draconian. */ if (st.st_mode & S_IWOTH) { pr_log_pri(PR_LOG_WARNING, "warning: config file '%s' is world-writable", path); } fh->fh_iosz = st.st_blksize; /* Push the configuration information onto the stack of configuration * sources. */ cs = add_config_source(fh); if (start) add_config_ctxt(start); while ((cmd = pr_parser_parse_line(tmp_pool)) != NULL) { pr_signals_handle(); if (cmd->argc) { conftable *conftab; char found = FALSE; cmd->server = *parser_curr_server; cmd->config = *parser_curr_config; conftab = pr_stash_get_symbol(PR_SYM_CONF, cmd->argv[0], NULL, &cmd->stash_index); while (conftab) { modret_t *mr; pr_signals_handle(); cmd->argv[0] = conftab->directive; pr_trace_msg(trace_channel, 7, "dispatching directive '%s' to module mod_%s", conftab->directive, conftab->m->name); mr = pr_module_call(conftab->m, conftab->handler, cmd); if (mr != NULL) { if (MODRET_ISERROR(mr)) { if (!(flags & PR_PARSER_FL_DYNAMIC_CONFIG)) { pr_log_pri(PR_LOG_ERR, "Fatal: %s on line %u of '%s'", MODRET_ERRMSG(mr), cs->cs_lineno, report_path); exit(1); } else { pr_log_pri(PR_LOG_WARNING, "warning: %s on line %u of '%s'", MODRET_ERRMSG(mr), cs->cs_lineno, report_path); } } } if (!MODRET_ISDECLINED(mr)) { found = TRUE; } conftab = pr_stash_get_symbol(PR_SYM_CONF, cmd->argv[0], conftab, &cmd->stash_index); } if (cmd->tmp_pool) destroy_pool(cmd->tmp_pool); if (!found) { if (!(flags & PR_PARSER_FL_DYNAMIC_CONFIG)) { pr_log_pri(PR_LOG_ERR, "Fatal: unknown configuration directive " "'%s' on line %u of '%s'", cmd->argv[0], cs->cs_lineno, report_path); exit(1); } else { pr_log_pri(PR_LOG_WARNING, "warning: unknown configuration directive " "'%s' on line %u of '%s'", cmd->argv[0], cs->cs_lineno, report_path); } } } destroy_pool(cmd->pool); } /* Pop this configuration stream from the stack. */ remove_config_source(); pr_fsio_close(fh); destroy_pool(tmp_pool); return 0; } cmd_rec *pr_parser_parse_line(pool *p) { register unsigned int i; char buf[PR_TUNABLE_BUFFER_SIZE+1], *arg = "", *word = NULL; cmd_rec *cmd = NULL; pool *sub_pool = NULL; array_header *arr = NULL; if (p == NULL) { errno = EINVAL; return NULL; } memset(buf, '\0', sizeof(buf)); while (pr_parser_read_line(buf, sizeof(buf)-1) != NULL) { char *bufp = buf; pr_signals_handle(); /* Build a new pool for the command structure and array */ sub_pool = make_sub_pool(p); pr_pool_tag(sub_pool, "parser cmd subpool"); cmd = pcalloc(sub_pool, sizeof(cmd_rec)); cmd->pool = sub_pool; cmd->stash_index = -1; /* Add each word to the array */ arr = make_array(cmd->pool, 4, sizeof(char **)); while ((word = pr_str_get_word(&bufp, 0)) != NULL) { char *tmp; tmp = get_config_word(cmd->pool, word); *((char **) push_array(arr)) = tmp; cmd->argc++; } /* Terminate the array with a NULL. */ *((char **) push_array(arr)) = NULL; /* The array header's job is done, we can forget about it and * it will get purged when the command's pool is destroyed. */ cmd->argv = (char **) arr->elts; /* Perform a fixup on configuration directives so that: * * -argv[0]-- -argv[1]-- ----argv[2]----- *