Bug 57786 - Fix ViewVC pipe errors through use of inetd "cvsnt rcsfile" service

git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1242 6955db30-a419-402b-8a0d-67ecbb4d7f56
remotes/github/custis
vfilippov 2011-03-29 15:14:26 +00:00 committed by Vitaliy Filippov
parent f4f2e432a7
commit 12434cb5b7
4 changed files with 50 additions and 2 deletions

21
bin/cvsnt-rcsfile-inetd.pl Executable file
View File

@ -0,0 +1,21 @@
#!/usr/bin/perl
# Very simple inetd/xinetd "cvsnt rcsfile" service
# Useful for ViewVC as there is an unpleasant non-stable bug, probably somewhere
# inside mod_python or Apache, which SOMETIMES causes cvsnt subprocesses forked
# from mod_python to die. This gives empty diff outputs or different errors like
# "Error: Rlog output ended early. Expected RCS file ..."
# This script removes forking from mod_python code and solves the issue.
# Additional profit of this script is that you can probably browse REMOTE cvs
# repositories, if you expose this service to ViewVC, although it is not tested.
# USAGE: (local) create an inetd service with this script as server listening
# on some port of 127.0.0.1 and put "rcsfile_socket = 127.0.0.1:port"
# into "utilities" section of viewvc.conf
$args = <STDIN>;
$args =~ s/\s+$//so;
@args = $args =~ /\'([^\']+)\'/giso;
# We don't execute shell, so this is mostly safe, not a backdoor :)
exec('/usr/bin/cvsnt', 'rcsfile', @args);

View File

@ -232,6 +232,21 @@ cvsnt =
# cvsnt = K:\Program Files\cvsnt\cvs.exe
# cvsnt = = /usr/bin/cvs
# ViewVC can use an inetd service instead of local "cvsnt rcsfile"
# This is recommended for all UNIX installations which use cvsnt,
# as there is an unpleasant non-stable bug, probably somewhere
# inside mod_python or Apache, which SOMETIMES causes cvsnt subprocesses forked
# from mod_python to die. This gives empty diff outputs or different errors like
# "Error: Rlog output ended early. Expected RCS file ..."
# This script removes forking from mod_python code and solves the issue.
# Additional profit of this script is that you can probably browse REMOTE cvs
# repositories, if you expose this service to ViewVC, although it is not tested.
# See also bin/cvsnt-rcsfile-inetd.pl
#rcsfile_socket = 'host:port'
# Example: rcsfile_socket = '127.0.0.1:8071'
# Subversion command-line client, used for viewing Subversion repositories
svn =
# svn = /usr/bin/svn

View File

@ -254,6 +254,7 @@ class Config:
self.utilities.cvsnt = 'cvs'
else:
self.utilities.cvsnt = None
self.utilities.rcsfile_socket = ''
self.utilities.svn = ''
self.utilities.diff = ''
self.utilities.cvsgraph = ''
@ -351,7 +352,7 @@ class IllegalOverrideSection(ViewVCConfigurationError):
def __str__(self):
return "malformed configuration: illegal %s override section: %s" \
% (self.override_type, self.section_name)
class MalformedRoot(ViewVCConfigurationError):
def __init__(self, config_name, value_given):
Exception.__init__(self, config_name, value_given)

View File

@ -22,6 +22,7 @@ import string
import re
import time
import cvsdb
import socket
# ViewVC libs
import compat
@ -310,7 +311,17 @@ class BinCVSRepository(BaseCVSRepository):
return filtered_revs
def rcs_popen(self, rcs_cmd, rcs_args, mode, capture_err=1):
if self.utilities.cvsnt:
a = []
if self.utilities.rcsfile_socket:
a = self.utilities.rcsfile_socket.split(':')
if len(a) == 2:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((a[0], int(a[1])))
s = s.makefile()
s.write('\''+rcs_cmd+'\' \''+'\' \''.join(rcs_args)+"\'\x0d\x0a")
s.flush()
return s
elif self.utilities.cvsnt:
cmd = self.utilities.cvsnt
args = ['rcsfile', rcs_cmd]
args.extend(list(rcs_args))