diff --git a/helpers/DATA/rpl b/helpers/DATA/rpl
new file mode 100755
index 0000000000000000000000000000000000000000..d52885057103f96f67522842faf9ed1e83301fab
--- /dev/null
+++ b/helpers/DATA/rpl
@@ -0,0 +1,310 @@
+#!/usr/bin/python
+
+import optparse, sys, os, tempfile, re
+try: import readline
+except ImportError: pass
+from stat import *
+
+def show_license(*eat):
+	print """rpl - replace strings in files
+Copyright (C) 2004-2005 Goran Weinholt <weinholt@debian.org>
+Copyright (C) 2004 Christian Haggstrom <chm@c00.info>
+
+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 St, Fifth Floor, Boston, MA  02110-1301 USA
+"""
+	sys.exit(0)
+
+def get_files(filenames, recurse, suffixen, verbose, hidden_files):
+	new_files = []
+	for filename in filenames:
+		try:
+			perms = os.lstat(filename)
+		except OSError, e:
+			sys.stderr.write("\nrpl: Unable to read permissions of %s."
+							 % filename)
+			sys.stderr.write("\nrpl: Error: %s" % e)
+			sys.stderr.write("\nrpl: SKIPPING %s\n\n" % filename)
+			continue
+
+		if S_ISDIR(perms.st_mode):
+			if recurse:
+				if verbose:
+					sys.stderr.write("Scanning Directory: %s\n" % filename)
+				for f in os.listdir(filename):
+					if not hidden_files and f.startswith('.'):
+						if verbose:
+							sys.stderr.write("Skipping: %s (hidden)\n"
+											 % os.path.join(filename, f))
+						continue
+					new_files += get_files([os.path.join(filename, f)],
+										   recurse, suffixen, verbose,
+										   hidden_files)
+			else:
+				if verbose:
+					sys.stderr.write("Directory: %s skipped.\n" % filename)
+				continue
+		elif S_ISREG(perms.st_mode):
+			if suffixen != [] and \
+				   not True in [ filename.endswith(s) for s in suffixen ]:
+				sys.stderr.write("Skipping: %s (suffix not in list)\n"
+								 % filename)
+				continue
+			new_files += [(filename, perms)]
+		else:
+			sys.stderr.write("Skipping: %s (not a regular file)\n"
+							 % filename)
+	return new_files
+
+def unescape(s):
+	regex = re.compile(r'\\([0-7]{1,3}|x[0-9a-fA-F]{2}|[nrtvafb\\])')
+	return regex.sub(lambda match: eval('"%s"' % match.group()), s)
+
+def blockrepl(instream, outstream, regex, before, after, blocksize=None):
+	patlen = len(before)
+	sum = 0
+	if not blocksize: blocksize = 2*patlen
+	tonext = ''
+	while 1:
+		block = instream.read(blocksize)
+		if not block: break
+		parts = regex.split(tonext+block)
+		sum += len(parts)-1
+		lastpart = parts[-1]
+		if lastpart:
+			tonext = lastpart[-patlen:]
+			parts[-1] = lastpart[:-len(tonext)]
+		else:
+			tonext = ''
+		outstream.write(after.join(parts))
+	outstream.write(tonext)
+	return sum
+
+def main():
+	# First we parse the command line arguments...
+	usage = "usage: %prog [options] old_string new_string target_file(s)"
+	parser = optparse.OptionParser(usage, version="%prog 1.5.2")
+	parser.add_option("-L", "--license", action="callback",
+					  callback=show_license, help="show the software license")
+	parser.add_option("-x", metavar="SUFFIX",
+					  action="append", dest="suffixen", default=[],
+					  help="specify file suffix to match")
+	parser.add_option("-i", "--ignore-case",
+					  action="store_true", dest="ignore_case", default=False,
+					  help="do a case insensitive match")
+	parser.add_option("-w", "--whole-words",
+					  action="store_true", dest="whole_words", default=False,
+					  help="whole words (old_string matches on word boundaries only)")
+	parser.add_option("-b", "--backup",
+					  action="store_true", dest="do_backup", default=False,
+					  help="make a backup before overwriting files")
+	parser.add_option("-q", "--quiet",
+					  action="store_true", dest="quiet", default=False,
+					  help="quiet mode")
+	parser.add_option("-v", "--verbose",
+					  action="store_true", dest="verbose", default=False,
+					  help="verbose mode")
+	parser.add_option("-s", "--dry-run",
+					  action="store_true", dest="dry_run", default=False,
+					  help="simulation mode")
+	parser.add_option("-R", "--recursive",
+					  action="store_true", dest="recurse", default=False,
+					  help="recurse into subdirectories")
+	parser.add_option("-e", "--escape",
+					  action="store_true", dest="escapes", default=False,
+					  help="expand escapes in old_string and new_string")
+	parser.add_option("-p", "--prompt",
+					  action="store_true", dest="prompt", default=False,
+					  help="prompt before modifying each file")
+	parser.add_option("-f", "--force",
+					  action="store_true", dest="force", default=False,
+					  help="ignore errors when trying to preserve permissions")
+	parser.add_option("-d", "--keep-times",
+					  action="store_true", dest="keep_times", default=False,
+					  help="keep the modification times on modified files")
+	parser.add_option("-t", "--use-tmpdir",
+					  action="store_true", dest="use_tmpdir", default=False,
+					  help="use $TMPDIR for storing temporary files")
+	parser.add_option("-a", "--all",
+					  action="store_true", dest="hidden_files", default=False,
+					  help="do not ignore files and directories starting with .")
+	(opts, args) = parser.parse_args()
+
+	# args should now contain old_str, new_str and a list of files/dirs
+	if len(args) < 3:
+		parser.error("must have at least three arguments")
+	if args[0] == "":
+		parser.error("must have something to replace")
+
+	old_str = args[0]
+	new_str = args[1]
+	files = args[2:]
+
+	# See if all the files actually exist
+	for file in files:
+		if not os.path.exists(file):
+			sys.stderr.write("\nrpl: File \"%s\" not found.\n" % file)
+			sys.exit(os.EX_DATAERR)
+
+	if new_str == "" and not opts.quiet:
+		sys.stderr.write("Really DELETE all occurences of %s " % old_str)
+		if opts.ignore_case:
+			sys.stderr.write("(ignoring case)? (Y/[N]) ")
+		else:
+			sys.stderr.write("(case sensitive)? (Y/[N]) ")
+		line = raw_input()
+		if line != "" and line[0] in "nN":
+			sys.stderr.write("\nrpl:  User cancelled operation.\n")
+			sys.exit(os.EX_TEMPFAIL)
+
+	# Tell the user what is going to happen
+	if opts.dry_run:
+		sys.stderr.write("Simulating replacement of \"%s\" with \"%s\" "
+						 % (old_str, new_str))
+	else:
+		sys.stderr.write("Replacing \"%s\" with \"%s\" " % (old_str, new_str))
+	if opts.ignore_case: sys.stderr.write("(ignoring case) ")
+	else:                sys.stderr.write("(case sensitive) ")
+	if opts.whole_words: sys.stderr.write("(whole words only)\n")
+	else:                sys.stderr.write("(partial words matched)\n")
+	if opts.dry_run and not opts.quiet:
+		sys.stderr.write("The files listed below would be modified in a replace operation.\n")
+
+	if opts.escapes:
+		old_str = unescape(old_str)
+		new_str = unescape(new_str)
+	if opts.whole_words:
+		regex = re.compile(r"(?:(?<=\s)|^)" + re.escape(old_str) + r"(?=\s|$)",
+						   opts.ignore_case and re.I or 0)
+	else:
+		regex = re.compile(re.escape(old_str), opts.ignore_case and re.I or 0)
+
+	total_matches = 0
+	files = get_files(files, opts.recurse, opts.suffixen, opts.verbose, opts.hidden_files)
+	for filename, perms in files:
+		# Open the input file
+		try: f = open(filename, "rb")
+		except IOError, e:
+			sys.stderr.write("\nrpl: Unable to open %s for reading." % fn)
+			sys.stderr.write("\nrpl: Error: %s" % e)
+			sys.stderr.write("\nrpl: SKIPPING %s\n\n" % fn)
+			continue
+
+		# Find out where we should put the temporary file
+		if opts.use_tmpdir: tempfile.tempdir = None
+		else:               tempfile.tempdir = os.path.dirname(filename)
+
+		# Create the output file
+		try:
+			o, tmp_path = tempfile.mkstemp("", ".tmp.")
+			o = os.fdopen(o, "wb")
+		except OSError, e:
+			sys.stderr.write("\nrpl: Unable to create temp file.")
+			sys.stderr.write("\nrpl: Error: %s" % e)
+			sys.stderr.write("\nrpl: (Type \"rpl -h\" and consider \"-t\" to specify temp file location.)")
+			sys.stderr.write("\nrpl: SKIPPING %s\n\n" % filename)
+			continue
+
+		# Set permissions and owner
+		try:
+			os.chown(tmp_path, perms.st_uid, perms.st_gid)
+			os.chmod(tmp_path, perms.st_mode)
+		except OSError, e:
+			sys.stderr.write("\nrpl: Unable to set owner/group/perms of %s"
+							 % filename)
+			sys.stderr.write("\nrpl: Error: %s" % e)
+			if opts.force:
+				sys.stderr.write("\nrpl: WARNING: New owner/group/perms may not match!\n\n")
+			else:
+				sys.stderr.write("\nrpl: SKIPPING %s!\n\n" % filename)
+				os.unlink(tmp_path)
+				continue
+				
+		if opts.verbose and not opts.dry_run:
+			sys.stderr.write("Processing:  %s\n" % filename)
+		elif not opts.quiet and not opts.dry_run:
+			sys.stderr.write(".")
+			sys.stderr.flush()
+
+		# Do the actual work now
+		matches = blockrepl(f, o, regex, old_str, new_str, 1024)
+
+		f.close()
+		o.close()
+
+		if matches == 0:
+			os.unlink(tmp_path)
+			continue
+
+		if opts.dry_run:
+			try:
+				fn = os.path.realpath(filename)
+			except OSError, e:
+				fn = filename
+			if not opts.quiet: sys.stderr.write("  %s\n" % fn)
+			os.unlink(tmp_path)
+			total_matches += matches
+			continue
+
+		if opts.prompt:
+			sys.stderr.write("\nSave '%s' ? ([Y]/N) " % filename)
+			line = ""
+			while line == "" or line[0] not in "Yy\nnN":
+				line = raw_input()
+			if line[0] in "nN":
+				sys.stderr.write("Not Saved.\n")
+				os.unlink(tmp_path)
+				continue
+			sys.stderr.write("Saved.\n")
+
+		if opts.do_backup:
+			try: os.rename(filename, filename + "~")
+			except OSError, e:
+				sys.stderr.write("rpl: An error occured renaming %s to %s." % (filename, filename + "~"))
+				sys.stderr.write("\nrpl: Error: %s" % e)
+				continue
+
+		# Rename the file
+		try: os.rename(tmp_path, filename)
+		except OSError, e:
+			sys.stderr.write("rpl: An error occured replacing %s with %s."
+							 % (tmp_path, filename))
+			sys.stderr.write("\nrpl: Error: %s" % e)
+			os.unlink(tmp_path)
+			continue
+
+		# Restore the times
+		if opts.keep_times:
+			try: os.utime(filename, (perms.st_atime, perms.st_mtime))
+			except OSError, e:
+				sys.stderr.write("\nrpl: An error occured setting the access time and mod time of the file %s.", filename)
+				sys.stderr.write("\nrpl: Error: %s" % e)
+		total_matches += matches
+
+	# We're about to exit, give a summary
+	if not opts.quiet:
+		if opts.dry_run:
+			sys.stderr.write("\nA Total of %lu matches found in %lu file%s searched."
+							 % (total_matches,
+								len(files),
+								len(files) != 1 and "s" or ""))
+			sys.stderr.write("\nNone replaced (simulation mode).\n")
+		else:
+			sys.stderr.write("\nA Total of %lu matches replaced in %lu file%s searched.\n"
+							 % (total_matches,
+								len(files),
+								len(files) != 1 and "s" or ""))
+
+if __name__ == "__main__":
+	main()
diff --git a/helpers/config b/helpers/config
index c667e0f64624d4fa82f2b18551bebcfa62a6150a..91fe0a419449f4e04676558392895416cd90f78d 100755
--- a/helpers/config
+++ b/helpers/config
@@ -50,6 +50,8 @@ DEVELMIRROR=http://devel.trisquel.info/trisquel/$CODENAME
 LOCALMIRROR=http://archive.trisquel.info/trisquel
 LOCAL_APT=`mktemp -d` 
 
+alias rpl=$PWD/DATA/rpl
+
 pkgversion(){
 	dpkg-parsechangelog --show-field Version
 }