Update proftpd to 1.3.5a

This commit is contained in:
Martin Matuska 2015-06-10 19:22:37 +00:00
parent 648dc65d79
commit eda41d9a86
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=389130
5 changed files with 9 additions and 629 deletions

View file

@ -5,7 +5,7 @@ PORTNAME?= proftpd
.if !defined(DISTVERSION) .if !defined(DISTVERSION)
PORTVERSION?= ${PROFTPD_VERSION} PORTVERSION?= ${PROFTPD_VERSION}
.endif .endif
PORTREVISION?= 7 PORTREVISION?= 0
CATEGORIES?= ftp CATEGORIES?= ftp
MASTER_SITES= ftp://ftp.proftpd.org/distrib/source/ \ MASTER_SITES= ftp://ftp.proftpd.org/distrib/source/ \
https://github.com/downloads/proftpd/proftpd.github.com/ \ https://github.com/downloads/proftpd/proftpd.github.com/ \
@ -26,7 +26,7 @@ BUILD_DEPENDS+= ${LOCALBASE}/sbin/proftpd:${PORTSDIR}/ftp/proftpd
RUN_DEPENDS+= ${LOCALBASE}/sbin/proftpd:${PORTSDIR}/ftp/proftpd RUN_DEPENDS+= ${LOCALBASE}/sbin/proftpd:${PORTSDIR}/ftp/proftpd
.endif .endif
PROFTPD_VERSION= 1.3.5 PROFTPD_VERSION= 1.3.5a
.if defined(_BUILDING_PROFTPD_MODULE) .if defined(_BUILDING_PROFTPD_MODULE)
DISTFILES+= ${DISTNAME}${EXTRACT_SUFX} DISTFILES+= ${DISTNAME}${EXTRACT_SUFX}

View file

@ -1,6 +1,7 @@
SHA256 (proftpd-1.3.5.tar.gz) = c10316fb003bd25eccbc08c77dd9057e053693e6527ffa2ea2cc4e08ccb87715 SHA256 (proftpd-1.3.5a.tar.gz) = a1f48df8539c414ec56e0cea63dcf4b8e16e606c05f10156f030a4a67fae5696
SIZE (proftpd-1.3.5.tar.gz) = 7594509 SIZE (proftpd-1.3.5a.tar.gz) = 29988477
SHA256 (mod_clamav-v0.13.tar.gz) = 7f60bebbb58836319bf249be77540efc6667a55caca8aaba164e6a61cd0c3db7 SHA256 (mod_clamav-v0.13.tar.gz) = 7f60bebbb58836319bf249be77540efc6667a55caca8aaba164e6a61cd0c3db7
SIZE (mod_clamav-v0.13.tar.gz) = 11683 SIZE (mod_clamav-v0.13.tar.gz) = 11683
SHA256 (mod_sql_tds-4.13.tar.gz) = 9d9fb6c4b9a952739a84e166ed8b0d93f539c7bcf73e32923318e00cbd7eea08 SHA256 (mod_sql_tds-4.13.tar.gz) = 9d9fb6c4b9a952739a84e166ed8b0d93f539c7bcf73e32923318e00cbd7eea08
SIZE (mod_sql_tds-4.13.tar.gz) = 11688 SIZE (mod_sql_tds-4.13.tar.gz) = 11688

View file

@ -1,610 +0,0 @@
Index: contrib/mod_copy.c
===================================================================
--- contrib/mod_copy.c
+++ contrib/mod_copy.c
@@ -2,7 +2,7 @@
* ProFTPD: mod_copy -- a module supporting copying of files on the server
* without transferring the data to the client and back
*
- * Copyright (c) 2009-2012 TJ Saunders
+ * Copyright (c) 2009-2015 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
@@ -25,13 +25,11 @@
*
* This is mod_copy, contrib software for proftpd 1.3.x and above.
* For more information contact TJ Saunders <tj@castaglia.org>.
- *
- * $Id: mod_copy.c,v 1.8 2012/12/27 22:31:29 castaglia Exp $
*/
#include "conf.h"
-#define MOD_COPY_VERSION "mod_copy/0.4"
+#define MOD_COPY_VERSION "mod_copy/0.5"
/* Make sure the version of proftpd is as necessary. */
#if PROFTPD_VERSION_NUMBER < 0x0001030401
@@ -40,6 +38,8 @@
extern pr_response_t *resp_list, *resp_err_list;
+static int copy_engine = TRUE;
+
static const char *trace_channel = "copy";
/* These are copied largely from src/mkhome.c */
@@ -165,7 +165,7 @@ static int copy_symlink(pool *p, const c
src_path, strerror(xerrno));
errno = xerrno;
- return -1;
+ return -1;
}
link_path[len] = '\0';
@@ -471,10 +471,37 @@ static int copy_paths(pool *p, const cha
return 0;
}
+/* Configuration handlers
+ */
+
+/* usage: CopyEngine on|off */
+MODRET set_copyengine(cmd_rec *cmd) {
+ int engine = -1;
+ config_rec *c;
+
+ CHECK_ARGS(cmd, 1);
+ CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL);
+
+ engine = get_boolean(cmd, 1);
+ if (engine == -1) {
+ CONF_ERROR(cmd, "expected Boolean parameter");
+ }
+
+ c = add_config_param(cmd->argv[0], 1, NULL);
+ c->argv[0] = palloc(c->pool, sizeof(int));
+ *((int *) c->argv[0]) = engine;
+
+ return PR_HANDLED(cmd);
+}
+
/* Command handlers
*/
MODRET copy_copy(cmd_rec *cmd) {
+ if (copy_engine == FALSE) {
+ return PR_DECLINED(cmd);
+ }
+
if (cmd->argc < 2) {
return PR_DECLINED(cmd);
}
@@ -539,12 +566,26 @@ MODRET copy_cpfr(cmd_rec *cmd) {
register unsigned int i;
int res;
char *path = "";
+ unsigned char *authenticated = NULL;
+
+ if (copy_engine == FALSE) {
+ return PR_DECLINED(cmd);
+ }
if (cmd->argc < 3 ||
strncasecmp(cmd->argv[1], "CPFR", 5) != 0) {
return PR_DECLINED(cmd);
}
+ authenticated = get_param_ptr(cmd->server->conf, "authenticated", FALSE);
+ if (authenticated == NULL ||
+ *authenticated == FALSE) {
+ pr_response_add_err(R_530, _("Please login with USER and PASS"));
+
+ errno = EPERM;
+ return PR_ERROR(cmd);
+ }
+
CHECK_CMD_MIN_ARGS(cmd, 3);
/* Construct the target file name by concatenating all the parameters after
@@ -594,12 +635,26 @@ MODRET copy_cpfr(cmd_rec *cmd) {
MODRET copy_cpto(cmd_rec *cmd) {
register unsigned int i;
char *from, *to = "";
+ unsigned char *authenticated = NULL;
+
+ if (copy_engine == FALSE) {
+ return PR_DECLINED(cmd);
+ }
if (cmd->argc < 3 ||
strncasecmp(cmd->argv[1], "CPTO", 5) != 0) {
return PR_DECLINED(cmd);
}
+ authenticated = get_param_ptr(cmd->server->conf, "authenticated", FALSE);
+ if (authenticated == NULL ||
+ *authenticated == FALSE) {
+ pr_response_add_err(R_530, _("Please login with USER and PASS"));
+
+ errno = EPERM;
+ return PR_ERROR(cmd);
+ }
+
CHECK_CMD_MIN_ARGS(cmd, 3);
from = pr_table_get(session.notes, "mod_copy.cpfr-path", NULL);
@@ -632,6 +687,10 @@ MODRET copy_cpto(cmd_rec *cmd) {
}
MODRET copy_log_site(cmd_rec *cmd) {
+ if (copy_engine == FALSE) {
+ return PR_DECLINED(cmd);
+ }
+
if (cmd->argc < 3 ||
strncasecmp(cmd->argv[1], "CPTO", 5) != 0) {
return PR_DECLINED(cmd);
@@ -643,23 +702,58 @@ MODRET copy_log_site(cmd_rec *cmd) {
return PR_DECLINED(cmd);
}
+MODRET copy_post_pass(cmd_rec *cmd) {
+ config_rec *c;
+
+ if (copy_engine == FALSE) {
+ return PR_DECLINED(cmd);
+ }
+
+ /* The CopyEngine directive may have been changed for this user by
+ * e.g. mod_ifsession, thus we check again.
+ */
+ c = find_config(main_server->conf, CONF_PARAM, "CopyEngine", FALSE);
+ if (c != NULL) {
+ copy_engine = *((int *) c->argv[0]);
+ }
+
+ return PR_DECLINED(cmd);
+}
+
/* Initialization functions
*/
static int copy_sess_init(void) {
+ config_rec *c;
+
+ c = find_config(main_server->conf, CONF_PARAM, "CopyEngine", FALSE);
+ if (c != NULL) {
+ copy_engine = *((int *) c->argv[0]);
+ }
+
+ if (copy_engine == FALSE) {
+ return 0;
+ }
+
/* Advertise support for the SITE command */
pr_feat_add("SITE COPY");
-
return 0;
}
/* Module API tables
*/
+static conftable copy_conftab[] = {
+ { "CopyEngine", set_copyengine, NULL },
+
+ { NULL }
+};
+
static cmdtable copy_cmdtab[] = {
{ CMD, C_SITE, G_WRITE, copy_copy, FALSE, FALSE, CL_MISC },
{ CMD, C_SITE, G_DIRS, copy_cpfr, FALSE, FALSE, CL_MISC },
{ CMD, C_SITE, G_WRITE, copy_cpto, FALSE, FALSE, CL_MISC },
+ { POST_CMD, C_PASS, G_NONE, copy_post_pass, FALSE, FALSE },
{ LOG_CMD, C_SITE, G_NONE, copy_log_site, FALSE, FALSE },
{ LOG_CMD_ERR, C_SITE, G_NONE, copy_log_site, FALSE, FALSE },
@@ -676,7 +770,7 @@ module copy_module = {
"copy",
/* Module configuration handler table */
- NULL,
+ copy_conftab,
/* Module command handler table */
copy_cmdtab,
Index: doc/contrib/mod_copy.html
===================================================================
--- doc/contrib/mod_copy.html
+++ doc/contrib/mod_copy.html
@@ -1,5 +1,5 @@
-<!-- $Id: mod_copy.html,v 1.1 2010/03/10 19:20:43 castaglia Exp $ -->
-<!-- $Source: /cvsroot/proftp/proftpd/doc/contrib/mod_copy.html,v $ -->
+<!-- $Id: mod_copy.html,v 1.1 2010-03-10 19:20:43 castaglia Exp $ -->
+<!-- $Source: /home/proftpd-core/backup/proftp-cvsroot/proftpd/doc/contrib/mod_copy.html,v $ -->
<html>
<head>
@@ -27,22 +27,40 @@ ProFTPD 1.3.<i>x</i>, and is not compile
instructions are discussed <a href="#Installation">here</a>.
<p>
-The most current version of <code>mod_copy</code> can be found at:
-<pre>
- <a href="http://www.castaglia.org/proftpd/">http://www.castaglia.org/proftpd/</a>
-</pre>
+The most current version of <code>mod_copy</code> is distributed with the
+ProFTPD source code.
<h2>Author</h2>
<p>
Please contact TJ Saunders &lt;tj <i>at</i> castaglia.org&gt; with any
questions, concerns, or suggestions regarding this module.
+<h2>Directives</h2>
+<ul>
+ <li><a href="#CopyEngine">CopyEngine</a>
+</ul>
+
<h2><code>SITE</code> Commands</h2>
<ul>
<li><a href="#SITE_CPFR">SITE CPFR</a>
<li><a href="#SITE_CPTO">SITE CPTO</a>
</ul>
+<p>
+<hr>
+<h2><a name="CopyEngine">CopyEngine</a></h2>
+<strong>Syntax:</strong> CopyEngine <em>on|off</em><br>
+<strong>Default:</strong> CopyEngine on<br>
+<strong>Context:</strong> server config, <code>&lt;VirtualHost&gt;</code>, <code>&lt;Global&gt;</code><br>
+<strong>Module:</strong> mod_radius<br>
+<strong>Compatibility:</strong> 1.3.6rc1 and later
+
+<p>
+The <code>CopyEngine</code> directive enables or disables the module's
+handling of <code>SITE COPY</code> <i>et al</i> commands. If it is set to
+<em>off</em> this module ignores these commands.
+
+<p>
<hr>
<h2><a name="SITE_CPFR">SITE CPFR</a></h2>
This <code>SITE</code> command specifies the source file/directory to use
@@ -118,13 +136,8 @@ your existing server:
<p>
<hr><br>
-Author: <i>$Author: castaglia $</i><br>
-Last Updated: <i>$Date: 2010/03/10 19:20:43 $</i><br>
-
-<br><hr>
-
<font size=2><b><i>
-&copy; Copyright 2009-2010 TJ Saunders<br>
+&copy; Copyright 2009-2015 TJ Saunders<br>
All Rights Reserved<br>
</i></b></font>
Index: tests/t/lib/ProFTPD/Tests/Modules/mod_copy.pm
===================================================================
--- tests/t/lib/ProFTPD/Tests/Modules/mod_copy.pm
+++ tests/t/lib/ProFTPD/Tests/Modules/mod_copy.pm
@@ -21,6 +21,11 @@ my $TESTS = {
test_class => [qw(forking)],
},
+ copy_file_no_login => {
+ order => ++$order,
+ test_class => [qw(bug forking)],
+ },
+
copy_dir => {
order => ++$order,
test_class => [qw(forking)],
@@ -86,6 +91,11 @@ my $TESTS = {
test_class => [qw(forking)],
},
+ copy_cpfr_cpto_no_login => {
+ order => ++$order,
+ test_class => [qw(bug forking)],
+ },
+
copy_cpto_no_cpfr => {
order => ++$order,
test_class => [qw(forking)],
@@ -263,6 +273,137 @@ sub copy_file {
unlink($log_file);
}
+sub copy_file_no_login {
+ my $self = shift;
+ my $tmpdir = $self->{tmpdir};
+
+ my $config_file = "$tmpdir/copy.conf";
+ my $pid_file = File::Spec->rel2abs("$tmpdir/copy.pid");
+ my $scoreboard_file = File::Spec->rel2abs("$tmpdir/copy.scoreboard");
+
+ my $log_file = File::Spec->rel2abs('tests.log');
+
+ my $auth_user_file = File::Spec->rel2abs("$tmpdir/copy.passwd");
+ my $auth_group_file = File::Spec->rel2abs("$tmpdir/copy.group");
+
+ my $user = 'proftpd';
+ my $passwd = 'test';
+ my $group = 'ftpd';
+ my $home_dir = File::Spec->rel2abs($tmpdir);
+ my $uid = 500;
+ my $gid = 500;
+
+ # Make sure that, if we're running as root, that the home directory has
+ # permissions/privs set for the account we create
+ if ($< == 0) {
+ unless (chmod(0755, $home_dir)) {
+ die("Can't set perms on $home_dir to 0755: $!");
+ }
+
+ unless (chown($uid, $gid, $home_dir)) {
+ die("Can't set owner of $home_dir to $uid/$gid: $!");
+ }
+ }
+
+ auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir,
+ '/bin/bash');
+ auth_group_write($auth_group_file, $group, $gid, $user);
+
+ my $src_file = File::Spec->rel2abs("$home_dir/foo.txt");
+ if (open(my $fh, "> $src_file")) {
+ print $fh "Hello, World!\n";
+
+ unless (close($fh)) {
+ die("Can't write $src_file: $!");
+ }
+
+ } else {
+ die("Can't open $src_file: $!");
+ }
+
+ my $dst_file = File::Spec->rel2abs("$home_dir/bar.txt");
+
+ my $config = {
+ PidFile => $pid_file,
+ ScoreboardFile => $scoreboard_file,
+ SystemLog => $log_file,
+
+ AuthUserFile => $auth_user_file,
+ AuthGroupFile => $auth_group_file,
+
+ IfModules => {
+ 'mod_delay.c' => {
+ DelayEngine => 'off',
+ },
+ },
+ };
+
+ my ($port, $config_user, $config_group) = config_write($config_file, $config);
+
+ # Open pipes, for use between the parent and child processes. Specifically,
+ # the child will indicate when it's done with its test by writing a message
+ # to the parent.
+ my ($rfh, $wfh);
+ unless (pipe($rfh, $wfh)) {
+ die("Can't open pipe: $!");
+ }
+
+ my $ex;
+
+ # Fork child
+ $self->handle_sigchld();
+ defined(my $pid = fork()) or die("Can't fork: $!");
+ if ($pid) {
+ eval {
+ my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port);
+
+ eval { $client->site('COPY', 'foo.txt', 'bar.txt') };
+ unless ($@) {
+ die("SITE COPY succeeded unexpectedly");
+ }
+
+ my $resp_code = $client->response_code();
+ my $resp_msg = $client->response_msg();
+
+ my $expected;
+ $expected = 530;
+ $self->assert($expected == $resp_code,
+ test_msg("Expected response code $expected, got $resp_code"));
+
+ $expected = "Please login with USER and PASS";
+ $self->assert($expected eq $resp_msg,
+ test_msg("Expected response message '$expected', got '$resp_msg'"));
+ };
+
+ if ($@) {
+ $ex = $@;
+ }
+
+ $wfh->print("done\n");
+ $wfh->flush();
+
+ } else {
+ eval { server_wait($config_file, $rfh) };
+ if ($@) {
+ warn($@);
+ exit 1;
+ }
+
+ exit 0;
+ }
+
+ # Stop server
+ server_stop($pid_file);
+
+ $self->assert_child_ok($pid);
+
+ if ($ex) {
+ die($ex);
+ }
+
+ unlink($log_file);
+}
+
sub copy_dir {
my $self = shift;
my $tmpdir = $self->{tmpdir};
@@ -2578,6 +2719,153 @@ sub copy_cpfr_cpto {
};
if ($@) {
+ $ex = $@;
+ }
+
+ $wfh->print("done\n");
+ $wfh->flush();
+
+ } else {
+ eval { server_wait($config_file, $rfh) };
+ if ($@) {
+ warn($@);
+ exit 1;
+ }
+
+ exit 0;
+ }
+
+ # Stop server
+ server_stop($pid_file);
+
+ $self->assert_child_ok($pid);
+
+ if ($ex) {
+ die($ex);
+ }
+
+ unlink($log_file);
+}
+
+sub copy_cpfr_cpto_no_login {
+ my $self = shift;
+ my $tmpdir = $self->{tmpdir};
+
+ my $config_file = "$tmpdir/copy.conf";
+ my $pid_file = File::Spec->rel2abs("$tmpdir/copy.pid");
+ my $scoreboard_file = File::Spec->rel2abs("$tmpdir/copy.scoreboard");
+
+ my $log_file = File::Spec->rel2abs('tests.log');
+
+ my $auth_user_file = File::Spec->rel2abs("$tmpdir/copy.passwd");
+ my $auth_group_file = File::Spec->rel2abs("$tmpdir/copy.group");
+
+ my $user = 'proftpd';
+ my $passwd = 'test';
+ my $group = 'ftpd';
+ my $home_dir = File::Spec->rel2abs($tmpdir);
+ my $uid = 500;
+ my $gid = 500;
+
+ # Make sure that, if we're running as root, that the home directory has
+ # permissions/privs set for the account we create
+ if ($< == 0) {
+ unless (chmod(0755, $home_dir)) {
+ die("Can't set perms on $home_dir to 0755: $!");
+ }
+
+ unless (chown($uid, $gid, $home_dir)) {
+ die("Can't set owner of $home_dir to $uid/$gid: $!");
+ }
+ }
+
+ auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir,
+ '/bin/bash');
+ auth_group_write($auth_group_file, $group, $gid, $user);
+
+ my $src_file = File::Spec->rel2abs("$home_dir/foo.txt");
+ if (open(my $fh, "> $src_file")) {
+ print $fh "Hello, World!\n";
+
+ unless (close($fh)) {
+ die("Can't write $src_file: $!");
+ }
+
+ } else {
+ die("Can't open $src_file: $!");
+ }
+
+ my $dst_file = File::Spec->rel2abs("$home_dir/bar.txt");
+
+ my $config = {
+ PidFile => $pid_file,
+ ScoreboardFile => $scoreboard_file,
+ SystemLog => $log_file,
+
+ AuthUserFile => $auth_user_file,
+ AuthGroupFile => $auth_group_file,
+
+ IfModules => {
+ 'mod_delay.c' => {
+ DelayEngine => 'off',
+ },
+ },
+ };
+
+ my ($port, $config_user, $config_group) = config_write($config_file, $config);
+
+ # Open pipes, for use between the parent and child processes. Specifically,
+ # the child will indicate when it's done with its test by writing a message
+ # to the parent.
+ my ($rfh, $wfh);
+ unless (pipe($rfh, $wfh)) {
+ die("Can't open pipe: $!");
+ }
+
+ my $ex;
+
+ # Fork child
+ $self->handle_sigchld();
+ defined(my $pid = fork()) or die("Can't fork: $!");
+ if ($pid) {
+ eval {
+ my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port);
+
+ eval { $client->site('CPFR', 'foo.txt') };
+ unless ($@) {
+ die("SITE CPFR succeeded unexpectedly");
+ }
+
+ my $resp_code = $client->response_code();
+ my $resp_msg = $client->response_msg();
+
+ my $expected;
+ $expected = 530;
+ $self->assert($expected == $resp_code,
+ test_msg("Expected response code $expected, got $resp_code"));
+
+ $expected = "Please login with USER and PASS";
+ $self->assert($expected eq $resp_msg,
+ test_msg("Expected response message '$expected', got '$resp_msg'"));
+
+ eval { $client->site('CPTO', 'bar.txt') };
+ unless ($@) {
+ die("SITE CPTO succeeded unexpectedly");
+ }
+
+ $resp_code = $client->response_code();
+ $resp_msg = $client->response_msg();
+
+ $expected = 530;
+ $self->assert($expected == $resp_code,
+ test_msg("Expected response code $expected, got $resp_code"));
+
+ $expected = "Please login with USER and PASS";
+ $self->assert($expected eq $resp_msg,
+ test_msg("Expected response message '$expected', got '$resp_msg'"));
+ };
+
+ if ($@) {
$ex = $@;
}

View file

@ -1,15 +0,0 @@
--- src/proftpd.8.in.orig Sat Sep 18 07:40:30 2004
+++ src/proftpd.8.in Thu Nov 3 15:35:56 2005
@@ -22,6 +22,12 @@
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

View file

@ -35,7 +35,9 @@ include/proftpd/fsio.h
include/proftpd/ftp.h include/proftpd/ftp.h
include/proftpd/glibc-glob.h include/proftpd/glibc-glob.h
include/proftpd/help.h include/proftpd/help.h
include/proftpd/ident.h
include/proftpd/inet.h include/proftpd/inet.h
include/proftpd/lastlog.h
include/proftpd/libsupp.h include/proftpd/libsupp.h
include/proftpd/log.h include/proftpd/log.h
include/proftpd/memcache.h include/proftpd/memcache.h
@ -75,6 +77,7 @@ include/proftpd/throttle.h
include/proftpd/timers.h include/proftpd/timers.h
include/proftpd/tpl.h include/proftpd/tpl.h
include/proftpd/trace.h include/proftpd/trace.h
include/proftpd/utf8.h
include/proftpd/var.h include/proftpd/var.h
include/proftpd/version.h include/proftpd/version.h
include/proftpd/xferlog.h include/proftpd/xferlog.h
@ -173,4 +176,5 @@ sbin/proftpd
%%NLS%%share/locale/bg_BG/LC_MESSAGES/proftpd.mo %%NLS%%share/locale/bg_BG/LC_MESSAGES/proftpd.mo
%%NLS%%share/locale/fr_FR/LC_MESSAGES/proftpd.mo %%NLS%%share/locale/fr_FR/LC_MESSAGES/proftpd.mo
%%NLS%%share/locale/ko_KR/LC_MESSAGES/proftpd.mo %%NLS%%share/locale/ko_KR/LC_MESSAGES/proftpd.mo
@dir lib/proftpd
@dir %%LOCALSTATEDIR%%/proftpd @dir %%LOCALSTATEDIR%%/proftpd