ADDED .cvs/.old_cvsroot/checkoutlist Index: .cvs/.old_cvsroot/checkoutlist ================================================================== --- .cvs/.old_cvsroot/checkoutlist +++ .cvs/.old_cvsroot/checkoutlist @@ -0,0 +1,14 @@ +# The "checkoutlist" file is used to support additional version controlled +# administrative files in $CVSROOT/CVSROOT, such as template files. +# +# The first entry on a line is a filename which will be checked out from +# the corresponding RCS file in the $CVSROOT/CVSROOT directory. +# The remainder of the line is an error message to use if the file cannot +# be checked out. +# +# File format: +# +# [] +# +# comment lines begin with '#' +syncmail ADDED .cvs/.old_cvsroot/commitinfo Index: .cvs/.old_cvsroot/commitinfo ================================================================== --- .cvs/.old_cvsroot/commitinfo +++ .cvs/.old_cvsroot/commitinfo @@ -0,0 +1,15 @@ +# The "commitinfo" file is used to control pre-commit checks. +# The filter on the right is invoked with the repository and a list +# of files to check. A non-zero exit of the filter program will +# cause the commit to be aborted. +# +# The first entry on a line is a regular expression which is tested +# against the directory that the change is being committed to, relative +# to the $CVSROOT. For the first match that is found, then the remainder +# of the line is the name of the filter to run. +# +# If the repository name does not match any of the regular expressions in this +# file, the "DEFAULT" line is used, if it is specified. +# +# If the name "ALL" appears as a regular expression it is always used +# in addition to the first matching regex or "DEFAULT". ADDED .cvs/.old_cvsroot/config Index: .cvs/.old_cvsroot/config ================================================================== --- .cvs/.old_cvsroot/config +++ .cvs/.old_cvsroot/config @@ -0,0 +1,11 @@ +# Set this to "no" if pserver shouldn't check system users/passwords +#SystemAuth=no + +# Set `PreservePermissions' to `yes' to save file status information +# in the repository. +#PreservePermissions=no + +# Set `TopLevelAdmin' to `yes' to create a CVS directory at the top +# level of the new working directory when using the `cvs checkout' +# command. +#TopLevelAdmin=no ADDED .cvs/.old_cvsroot/cvswrappers Index: .cvs/.old_cvsroot/cvswrappers ================================================================== --- .cvs/.old_cvsroot/cvswrappers +++ .cvs/.old_cvsroot/cvswrappers @@ -0,0 +1,23 @@ +# This file affects handling of files based on their names. +# +# The -t/-f options allow one to treat directories of files +# as a single file, or to transform a file in other ways on +# its way in and out of CVS. +# +# The -m option specifies whether CVS attempts to merge files. +# +# The -k option specifies keyword expansion (e.g. -kb for binary). +# +# Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers) +# +# wildcard [option value][option value]... +# +# where option is one of +# -f from cvs filter value: path to filter +# -t to cvs filter value: path to filter +# -m update methodology value: MERGE or COPY +# -k expansion mode value: b, o, kkv, &c +# +# and value is a single-quote delimited value. +# For example: +#*.gif -k 'b' ADDED .cvs/.old_cvsroot/editinfo Index: .cvs/.old_cvsroot/editinfo ================================================================== --- .cvs/.old_cvsroot/editinfo +++ .cvs/.old_cvsroot/editinfo @@ -0,0 +1,21 @@ +# The "editinfo" file is used to allow verification of logging +# information. It works best when a template (as specified in the +# rcsinfo file) is provided for the logging procedure. Given a +# template with locations for, a bug-id number, a list of people who +# reviewed the code before it can be checked in, and an external +# process to catalog the differences that were code reviewed, the +# following test can be applied to the code: +# +# Making sure that the entered bug-id number is correct. +# Validating that the code that was reviewed is indeed the code being +# checked in (using the bug-id number or a seperate review +# number to identify this particular code set.). +# +# If any of the above test failed, then the commit would be aborted. +# +# Actions such as mailing a copy of the report to each reviewer are +# better handled by an entry in the loginfo file. +# +# One thing that should be noted is the the ALL keyword is not +# supported. There can be only one entry that matches a given +# repository. ADDED .cvs/.old_cvsroot/loginfo Index: .cvs/.old_cvsroot/loginfo ================================================================== --- .cvs/.old_cvsroot/loginfo +++ .cvs/.old_cvsroot/loginfo @@ -0,0 +1,30 @@ +# The "loginfo" file controls where "cvs commit" log information +# is sent. The first entry on a line is a regular expression which must match +# the directory that the change is being made to, relative to the +# $CVSROOT. If a match is found, then the remainder of the line is a filter +# program that should expect log information on its standard input. +# +# If the repository name does not match any of the regular expressions in this +# file, the "DEFAULT" line is used, if it is specified. +# +# If the name ALL appears as a regular expression it is always used +# in addition to the first matching regex or DEFAULT. +# +# You may specify a format string as part of the +# filter. The string is composed of a `%' followed +# by a single format character, or followed by a set of format +# characters surrounded by `{' and `}' as separators. The format +# characters are: +# +# s = file name +# V = old version number (pre-checkin) +# v = new version number (post-checkin) +# +# For example: +#DEFAULT (echo ""; id; echo %s; date; cat) >> $CVSROOT/CVSROOT/commitlog +# or +#DEFAULT (echo ""; id; echo %{sVv}; date; cat) >> $CVSROOT/CVSROOT/commitlog + +# Lines to mail changes +CVSROOT $CVSROOT/CVSROOT/syncmail %{sVv} gawthrop@users.sourceforge.net +DEFAULT $CVSROOT/CVSROOT/syncmail %{sVv} mtt-checkins@lists.sourceforge.net ADDED .cvs/.old_cvsroot/modules Index: .cvs/.old_cvsroot/modules ================================================================== --- .cvs/.old_cvsroot/modules +++ .cvs/.old_cvsroot/modules @@ -0,0 +1,26 @@ +# Three different line formats are valid: +# key -a aliases... +# key [options] directory +# key [options] directory files... +# +# Where "options" are composed of: +# -i prog Run "prog" on "cvs commit" from top-level of module. +# -o prog Run "prog" on "cvs checkout" of module. +# -e prog Run "prog" on "cvs export" of module. +# -t prog Run "prog" on "cvs rtag" of module. +# -u prog Run "prog" on "cvs update" of module. +# -d dir Place module in directory "dir" instead of module name. +# -l Top-level directory only -- do not recurse. +# +# NOTE: If you change any of the "Run" options above, you'll have to +# release and re-checkout any working directories of these modules. +# +# And "directory" is a path to a directory relative to $CVSROOT. +# +# The "-a" option specifies an alias. An alias is interpreted as if +# everything on the right of the "-a" had been typed on the command line. +# +# You can encode a module within a module by using the special '&' +# character to interpose another module into the current module. This +# can be useful for creating a module that consists of many directories +# spread out over the entire source repository. ADDED .cvs/.old_cvsroot/notify Index: .cvs/.old_cvsroot/notify ================================================================== --- .cvs/.old_cvsroot/notify +++ .cvs/.old_cvsroot/notify @@ -0,0 +1,12 @@ +# The "notify" file controls where notifications from watches set by +# "cvs watch add" or "cvs edit" are sent. The first entry on a line is +# a regular expression which is tested against the directory that the +# change is being made to, relative to the $CVSROOT. If it matches, +# then the remainder of the line is a filter program that should contain +# one occurrence of %s for the user to notify, and information on its +# standard input. +# +# "ALL" or "DEFAULT" can be used in place of the regular expression. +# +# For example: +#ALL mail %s -s "CVS notification" ADDED .cvs/.old_cvsroot/rcsinfo Index: .cvs/.old_cvsroot/rcsinfo ================================================================== --- .cvs/.old_cvsroot/rcsinfo +++ .cvs/.old_cvsroot/rcsinfo @@ -0,0 +1,13 @@ +# The "rcsinfo" file is used to control templates with which the editor +# is invoked on commit and import. +# +# The first entry on a line is a regular expression which is tested +# against the directory that the change is being made to, relative to the +# $CVSROOT. For the first match that is found, then the remainder of the +# line is the name of the file that contains the template. +# +# If the repository name does not match any of the regular expressions in this +# file, the "DEFAULT" line is used, if it is specified. +# +# If the name "ALL" appears as a regular expression it is always used +# in addition to the first matching regex or "DEFAULT". ADDED .cvs/.old_cvsroot/syncmail Index: .cvs/.old_cvsroot/syncmail ================================================================== --- .cvs/.old_cvsroot/syncmail +++ .cvs/.old_cvsroot/syncmail @@ -0,0 +1,459 @@ +#! /usr/bin/python + +# Copyright (c) 2002, 2003, Barry Warsaw, Fred Drake, and contributors +# All rights reserved. +# See the accompanying LICENSE file for details. + +# Compatibility: Python 2.2.3, tied to the version of Python on SourceForge's +# authenticated CVS server. + +"""Complicated notification for CVS checkins. + +This script is used to provide email notifications of changes to the CVS +repository. These email changes will include context diffs of the changes. +Really big diffs will be trimmed. + +This script is run from a CVS loginfo file (see $CVSROOT/CVSROOT/loginfo). To +set this up, create a loginfo entry that looks something like this: + + mymodule /path/to/this/script %%s some-email-addr@your.domain + +In this example, whenever a checkin that matches `mymodule' is made, this +script is invoked, which will generate the diff containing email, and send it +to some-email-addr@your.domain. + + Note: This module used to also do repository synchronizations via + rsync-over-ssh, but since the repository has been moved to SourceForge, + this is no longer necessary. The syncing functionality has been ripped + out in the 3.0, which simplifies it considerably. Access the 2.x versions + to refer to this functionality. Because of this, the script is misnamed. + +It no longer makes sense to run this script from the command line. Doing so +will only print out this usage information. + +Usage: + + %(PROGRAM)s [options] <%%S> email-addr [email-addr ...] + +Where options are: + + --cvsroot= + Use as the environment variable CVSROOT. Otherwise this + variable must exist in the environment. + + --context=# + -C # + Include # lines of context around lines that differ (default: 2). + + -c + Produce a context diff (default). + + -m hostname + --mailhost hostname + The hostname of an available SMTP server. The default is + 'localhost'. + + -u + Produce a unified diff (smaller). + + -S TEXT + --subject-prefix=TEXT + Prepend TEXT to the email subject line. + + -R ADDR + --reply-to=ADDR + Add a "Reply-To: ADDR" header to the email message. + + --quiet / -q + Don't print as much status to stdout. + + --fromhost=hostname + -f hostname + The hostname that email messages appear to be coming from. The From: + header of the outgoing message will look like user@hostname. By + default, hostname is the machine's fully qualified domain name. + + --help / -h + Print this text. + +The rest of the command line arguments are: + + <%%S> + CVS %%s loginfo expansion. When invoked by CVS, this will be a single + string containing the directory the checkin is being made in, relative + to $CVSROOT, followed by the list of files that are changing. If the + %%s in the loginfo file is %%{sVv}, context diffs for each of the + modified files are included in any email messages that are generated. + + email-addrs + At least one email address. +""" +__version__ = '1.2' + +import os +import sys +import re +import time +import string +import getopt +import smtplib +import pwd +import socket + +try: + from socket import getfqdn +except ImportError: + def getfqdn(): + # Python 1.5.2 :( + hostname = socket.gethostname() + byaddr = socket.gethostbyaddr(socket.gethostbyname(hostname)) + aliases = byaddr[1] + aliases.insert(0, byaddr[0]) + aliases.insert(0, hostname) + for fqdn in aliases: + if '.' in fqdn: + break + else: + fqdn = 'localhost.localdomain' + return fqdn + + +from cStringIO import StringIO + +# Which SMTP server to do we connect to? +MAILHOST = 'localhost' +MAILPORT = 25 + +# Diff trimming stuff +DIFF_HEAD_LINES = 20 +DIFF_TAIL_LINES = 20 +DIFF_TRUNCATE_IF_LARGER = 1000 + +COMMASPACE = ', ' + +PROGRAM = sys.argv[0] + +BINARY_EXPLANATION_LINES = [ + "(This appears to be a binary file; contents omitted.)\n" + ] + +NOVERSION = "Couldn't generate diff; no version number found for file: %s" +BACKSLASH = "Couldn't generate diff: backslash in filespec's filename: %s" + + + +def usage(code, msg=''): + print __doc__ % globals() + if msg: + print msg + sys.exit(code) + + + +def calculate_diff(entry, contextlines): + file = entry.name + oldrev = entry.revision + newrev = entry.new_revision + + # Make sure we can find a CVS version number + if oldrev is None and newrev is None: + return NOVERSION % file + + if string.find(file, "'") <> -1: + # Those crazy users put single-quotes in their file names! Now we + # have to escape everything that is meaningful inside double-quotes. + filestr = string.replace(file, '\\', '\\\\') + filestr = string.replace(filestr, '`', '\`') + filestr = string.replace(filestr, '"', '\"') + filestr = string.replace(filestr, '$', '\$') + # and quote it with double-quotes. + filestr = '"' + filestr + '"' + else: + # quote it with single-quotes. + filestr = "'" + file + "'" + if oldrev is None: + # File is being added. + try: + if os.path.exists(file): + fp = open(file) + else: + update_cmd = "cvs -fn update -r %s -p %s" % (newrev, filestr) + fp = os.popen(update_cmd) + lines = fp.readlines() + fp.close() + # Is this a binary file? Let's look at the first few + # lines to figure it out: + for line in lines[:5]: + for c in string.rstrip(line): + if c in string.whitespace: + continue + if c < ' ' or c > chr(127): + lines = BINARY_EXPLANATION_LINES[:] + break + lines.insert(0, '--- NEW FILE: %s ---\n' % file) + except IOError, e: + lines = ['***** Error reading new file: ', + str(e), '\n***** file: ', file, ' cwd: ', os.getcwd()] + elif newrev is None: + lines = ['--- %s DELETED ---\n' % file] + else: + # File has been changed. + # This /has/ to happen in the background, otherwise we'll run into CVS + # lock contention. What a crock. + if contextlines > 0: + difftype = "-C " + str(contextlines) + else: + difftype = "-u" + diffcmd = "/usr/bin/cvs -f diff -kk %s --minimal -r %s -r %s %s" \ + % (difftype, oldrev, newrev, filestr) + fp = os.popen(diffcmd) + lines = fp.readlines() + # ignore the error code, it always seems to be 1 :( + fp.close() + if len(lines) > DIFF_TRUNCATE_IF_LARGER: + removedlines = len(lines) - DIFF_HEAD_LINES - DIFF_TAIL_LINES + del lines[DIFF_HEAD_LINES:-DIFF_TAIL_LINES] + lines.insert(DIFF_HEAD_LINES, + '[...%d lines suppressed...]\n' % removedlines) + return string.join(lines, '') + + + +rfc822_specials_re = re.compile(r'[\(\)\<\>\@\,\;\:\\\"\.\[\]]') + +def quotename(name): + if name and rfc822_specials_re.search(name): + return '"%s"' % string.replace(name, '"', '\\"') + else: + return name + + + +def blast_mail(subject, people, entries, contextlines, fromhost, replyto): + # cannot wait for child process or that will cause parent to retain cvs + # lock for too long. Urg! + if not os.fork(): + # in the child + # give up the lock you cvs thang! + time.sleep(2) + # Create the smtp connection to the localhost + conn = smtplib.SMTP() + conn.connect(MAILHOST, MAILPORT) + user = pwd.getpwuid(os.getuid())[0] + name = string.split(pwd.getpwuid(os.getuid())[4], ',')[0] + domain = fromhost or getfqdn() + address = '%s@%s' % (user, domain) + s = StringIO() + sys.stdout = s + datestamp = time.strftime('%a, %d %b %Y %H:%M:%S +0000', + time.gmtime(time.time())) + try: + vars = {'address' : address, + 'name' : quotename(name), + 'people' : string.join(people, COMMASPACE), + 'subject' : subject, + 'version' : __version__, + 'date' : datestamp, + } + print '''\ +From: %(name)s <%(address)s> +To: %(people)s''' % vars + if replyto: + print 'Reply-To: %s' % replyto + print '''\ +Subject: %(subject)s +Date: %(date)s +X-Mailer: Python syncmail %(version)s +''' % vars + s.write(sys.stdin.read()) + # append the diffs if available + print + for entry in entries: + print calculate_diff(entry, contextlines) + finally: + sys.stdout = sys.__stdout__ + resp = conn.sendmail(address, people, s.getvalue()) + conn.close() + os._exit(0) + + + +class CVSEntry: + def __init__(self, name, revision, timestamp, conflict, options, tagdate): + self.name = name + self.revision = revision + self.timestamp = timestamp + self.conflict = conflict + self.options = options + self.tagdate = tagdate + +def get_entry(prefix, mapping, line, filename): + line = string.strip(line) + parts = string.split(line, "/") + _, name, revision, timestamp, options, tagdate = parts + key = namekey(prefix, name) + try: + entry = mapping[key] + except KeyError: + if revision == "0": + revision = None + if string.find(timestamp, "+") != -1: + timestamp, conflict = tuple(string.split(timestamp, "+")) + else: + conflict = None + entry = CVSEntry(key, revision, timestamp, conflict, + options, tagdate) + mapping[key] = entry + return entry + +def namekey(prefix, name): + if prefix: + return os.path.join(prefix, name) + else: + return name + +def load_change_info(prefix=None): + if prefix is not None: + entries_fn = os.path.join(prefix, "CVS", "Entries") + else: + entries_fn = os.path.join("CVS", "Entries") + entries_log_fn = entries_fn + ".Log" + mapping = {} + f = open(entries_fn) + while 1: + line = f.readline() + if not line: + break +## if string.strip(line) == "D": +## continue + # we could recurse down subdirs, except the Entries.Log files + # we need haven't been written to the subdirs yet, so it + # doesn't do us any good +## if line[0] == "D": +## name = string.split(line, "/")[1] +## dirname = namekey(prefix, name) +## if os.path.isdir(dirname): +## m = load_change_info(dirname) +## mapping.update(m) + if line[0] == "/": + # normal file + get_entry(prefix, mapping, line, entries_fn) + # else: bogus Entries line + f.close() + if os.path.isfile(entries_log_fn): + f = open(entries_log_fn) + while 1: + line = f.readline() + if not line: + break + if line[1:2] != ' ': + # really old version of CVS + break + entry = get_entry(prefix, mapping, line[2:], entries_log_fn) + parts = string.split(line, "/")[1:] + if line[0] == "A": + # adding a file + entry.new_revision = parts[1] + elif line[0] == "R": + # removing a file + entry.new_revision = None + f.close() + for entry in mapping.values(): + if not hasattr(entry, "new_revision"): + print 'confused about file', entry.name, '-- ignoring' + del mapping[entry.name] + return mapping + +def load_branch_name(): + tag_fn = os.path.join("CVS", "Tag") + if os.path.isfile(tag_fn): + f = open(tag_fn) + line = string.strip(f.readline()) + f.close() + if line[:1] == "T": + return line[1:] + return None + +# scan args for options +def main(): + # XXX Should really move all the options to an object, just to + # avoid threading so many positional args through everything. + try: + opts, args = getopt.getopt( + sys.argv[1:], 'hC:cuS:R:qf:m:', + ['fromhost=', 'context=', 'cvsroot=', 'mailhost=', + 'subject-prefix=', 'reply-to=', + 'help', 'quiet']) + except getopt.error, msg: + usage(1, msg) + + # parse the options + contextlines = 2 + verbose = 1 + subject_prefix = "" + replyto = None + fromhost = None + for opt, arg in opts: + if opt in ('-h', '--help'): + usage(0) + elif opt == '--cvsroot': + os.environ['CVSROOT'] = arg + elif opt in ('-C', '--context'): + contextlines = int(arg) + elif opt == '-c': + if contextlines <= 0: + contextlines = 2 + elif opt == '-u': + contextlines = 0 + elif opt in ('-S', '--subject-prefix'): + subject_prefix = arg + elif opt in ('-R', '--reply-to'): + replyto = arg + elif opt in ('-q', '--quiet'): + verbose = 0 + elif opt in ('-f', '--fromhost'): + fromhost = arg + elif opt in ('-m', '--mailhost'): + global MAILHOST + MAILHOST = arg + + # What follows is the specification containing the files that were + # modified. The argument actually must be split, with the first component + # containing the directory the checkin is being made in, relative to + # $CVSROOT, followed by the list of files that are changing. + if not args: + usage(1, 'No CVS module specified') + changes = load_change_info() + branch = load_branch_name() + subject = subject_prefix + args[0] + specs = string.split(args[0]) + del args[0] + + # The remaining args should be the email addresses + if not args: + usage(1, 'No recipients specified') + + # Now do the mail command + people = args + + if specs[-3:] == ['-', 'Imported', 'sources']: + print 'Not sending email for imported sources.' + return + + if verbose: +## print 'Python version', sys.version +## os.system("type python1.6; type python2;" +## " type python2.0; type python2.1; type python2.2;" +## " type rcsdiff; type rlog") + print 'Mailing %s...' % string.join(people, COMMASPACE) + print 'Generating notification message...' + blast_mail(subject, people, changes.values(), + contextlines, fromhost, replyto) + if verbose: + print 'Generating notification message... done.' + + + +if __name__ == '__main__': + main() + sys.exit(0) ADDED .cvs/.old_cvsroot/taginfo Index: .cvs/.old_cvsroot/taginfo ================================================================== --- .cvs/.old_cvsroot/taginfo +++ .cvs/.old_cvsroot/taginfo @@ -0,0 +1,20 @@ +# The "taginfo" file is used to control pre-tag checks. +# The filter on the right is invoked with the following arguments: +# +# $1 -- tagname +# $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d +# $3 -- repository +# $4-> file revision [file revision ...] +# +# A non-zero exit of the filter program will cause the tag to be aborted. +# +# The first entry on a line is a regular expression which is tested +# against the directory that the change is being committed to, relative +# to the $CVSROOT. For the first match that is found, then the remainder +# of the line is the name of the filter to run. +# +# If the repository name does not match any of the regular expressions in this +# file, the "DEFAULT" line is used, if it is specified. +# +# If the name "ALL" appears as a regular expression it is always used +# in addition to the first matching regex or "DEFAULT". ADDED .cvs/.old_cvsroot/verifymsg Index: .cvs/.old_cvsroot/verifymsg ================================================================== --- .cvs/.old_cvsroot/verifymsg +++ .cvs/.old_cvsroot/verifymsg @@ -0,0 +1,21 @@ +# The "verifymsg" file is used to allow verification of logging +# information. It works best when a template (as specified in the +# rcsinfo file) is provided for the logging procedure. Given a +# template with locations for, a bug-id number, a list of people who +# reviewed the code before it can be checked in, and an external +# process to catalog the differences that were code reviewed, the +# following test can be applied to the code: +# +# Making sure that the entered bug-id number is correct. +# Validating that the code that was reviewed is indeed the code being +# checked in (using the bug-id number or a seperate review +# number to identify this particular code set.). +# +# If any of the above test failed, then the commit would be aborted. +# +# Actions such as mailing a copy of the report to each reviewer are +# better handled by an entry in the loginfo file. +# +# One thing that should be noted is the the ALL keyword is not +# supported. There can be only one entry that matches a given +# repository. ADDED .cvs/.old_mttroot_cvsroot/checkoutlist Index: .cvs/.old_mttroot_cvsroot/checkoutlist ================================================================== --- .cvs/.old_mttroot_cvsroot/checkoutlist +++ .cvs/.old_mttroot_cvsroot/checkoutlist @@ -0,0 +1,14 @@ +# The "checkoutlist" file is used to support additional version controlled +# administrative files in $CVSROOT/CVSROOT, such as template files. +# +# The first entry on a line is a filename which will be checked out from +# the corresponding RCS file in the $CVSROOT/CVSROOT directory. +# The remainder of the line is an error message to use if the file cannot +# be checked out. +# +# File format: +# +# [] +# +# comment lines begin with '#' +syncmail ADDED .cvs/.old_mttroot_cvsroot/commitinfo Index: .cvs/.old_mttroot_cvsroot/commitinfo ================================================================== --- .cvs/.old_mttroot_cvsroot/commitinfo +++ .cvs/.old_mttroot_cvsroot/commitinfo @@ -0,0 +1,15 @@ +# The "commitinfo" file is used to control pre-commit checks. +# The filter on the right is invoked with the repository and a list +# of files to check. A non-zero exit of the filter program will +# cause the commit to be aborted. +# +# The first entry on a line is a regular expression which is tested +# against the directory that the change is being committed to, relative +# to the $CVSROOT. For the first match that is found, then the remainder +# of the line is the name of the filter to run. +# +# If the repository name does not match any of the regular expressions in this +# file, the "DEFAULT" line is used, if it is specified. +# +# If the name "ALL" appears as a regular expression it is always used +# in addition to the first matching regex or "DEFAULT". ADDED .cvs/.old_mttroot_cvsroot/config Index: .cvs/.old_mttroot_cvsroot/config ================================================================== --- .cvs/.old_mttroot_cvsroot/config +++ .cvs/.old_mttroot_cvsroot/config @@ -0,0 +1,11 @@ +# Set this to "no" if pserver shouldn't check system users/passwords +#SystemAuth=no + +# Set `PreservePermissions' to `yes' to save file status information +# in the repository. +#PreservePermissions=no + +# Set `TopLevelAdmin' to `yes' to create a CVS directory at the top +# level of the new working directory when using the `cvs checkout' +# command. +#TopLevelAdmin=no ADDED .cvs/.old_mttroot_cvsroot/cvswrappers Index: .cvs/.old_mttroot_cvsroot/cvswrappers ================================================================== --- .cvs/.old_mttroot_cvsroot/cvswrappers +++ .cvs/.old_mttroot_cvsroot/cvswrappers @@ -0,0 +1,23 @@ +# This file affects handling of files based on their names. +# +# The -t/-f options allow one to treat directories of files +# as a single file, or to transform a file in other ways on +# its way in and out of CVS. +# +# The -m option specifies whether CVS attempts to merge files. +# +# The -k option specifies keyword expansion (e.g. -kb for binary). +# +# Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers) +# +# wildcard [option value][option value]... +# +# where option is one of +# -f from cvs filter value: path to filter +# -t to cvs filter value: path to filter +# -m update methodology value: MERGE or COPY +# -k expansion mode value: b, o, kkv, &c +# +# and value is a single-quote delimited value. +# For example: +#*.gif -k 'b' ADDED .cvs/.old_mttroot_cvsroot/editinfo Index: .cvs/.old_mttroot_cvsroot/editinfo ================================================================== --- .cvs/.old_mttroot_cvsroot/editinfo +++ .cvs/.old_mttroot_cvsroot/editinfo @@ -0,0 +1,21 @@ +# The "editinfo" file is used to allow verification of logging +# information. It works best when a template (as specified in the +# rcsinfo file) is provided for the logging procedure. Given a +# template with locations for, a bug-id number, a list of people who +# reviewed the code before it can be checked in, and an external +# process to catalog the differences that were code reviewed, the +# following test can be applied to the code: +# +# Making sure that the entered bug-id number is correct. +# Validating that the code that was reviewed is indeed the code being +# checked in (using the bug-id number or a seperate review +# number to identify this particular code set.). +# +# If any of the above test failed, then the commit would be aborted. +# +# Actions such as mailing a copy of the report to each reviewer are +# better handled by an entry in the loginfo file. +# +# One thing that should be noted is the the ALL keyword is not +# supported. There can be only one entry that matches a given +# repository. ADDED .cvs/.old_mttroot_cvsroot/loginfo Index: .cvs/.old_mttroot_cvsroot/loginfo ================================================================== --- .cvs/.old_mttroot_cvsroot/loginfo +++ .cvs/.old_mttroot_cvsroot/loginfo @@ -0,0 +1,31 @@ +# The "loginfo" file controls where "cvs commit" log information +# is sent. The first entry on a line is a regular expression which must match +# the directory that the change is being made to, relative to the +# $CVSROOT. If a match is found, then the remainder of the line is a filter +# program that should expect log information on its standard input. +# +# If the repository name does not match any of the regular expressions in this +# file, the "DEFAULT" line is used, if it is specified. +# +# If the name ALL appears as a regular expression it is always used +# in addition to the first matching regex or DEFAULT. +# +# You may specify a format string as part of the +# filter. The string is composed of a `%' followed +# by a single format character, or followed by a set of format +# characters surrounded by `{' and `}' as separators. The format +# characters are: +# +# s = file name +# V = old version number (pre-checkin) +# v = new version number (post-checkin) +# +# For example: +#DEFAULT (echo ""; id; echo %s; date; cat) >> $CVSROOT/CVSROOT/commitlog +# or +#DEFAULT (echo ""; id; echo %{sVv}; date; cat) >> $CVSROOT/CVSROOT/commitlog + +# Lines to mail changes +CVSROOT $CVSROOT/CVSROOT/syncmail %{sVv} mtt@gawthrop.net +DEFAULT $CVSROOT/CVSROOT/syncmail %{sVv} mtt-cvs@lists.sourceforge.net + ADDED .cvs/.old_mttroot_cvsroot/modules Index: .cvs/.old_mttroot_cvsroot/modules ================================================================== --- .cvs/.old_mttroot_cvsroot/modules +++ .cvs/.old_mttroot_cvsroot/modules @@ -0,0 +1,26 @@ +# Three different line formats are valid: +# key -a aliases... +# key [options] directory +# key [options] directory files... +# +# Where "options" are composed of: +# -i prog Run "prog" on "cvs commit" from top-level of module. +# -o prog Run "prog" on "cvs checkout" of module. +# -e prog Run "prog" on "cvs export" of module. +# -t prog Run "prog" on "cvs rtag" of module. +# -u prog Run "prog" on "cvs update" of module. +# -d dir Place module in directory "dir" instead of module name. +# -l Top-level directory only -- do not recurse. +# +# NOTE: If you change any of the "Run" options above, you'll have to +# release and re-checkout any working directories of these modules. +# +# And "directory" is a path to a directory relative to $CVSROOT. +# +# The "-a" option specifies an alias. An alias is interpreted as if +# everything on the right of the "-a" had been typed on the command line. +# +# You can encode a module within a module by using the special '&' +# character to interpose another module into the current module. This +# can be useful for creating a module that consists of many directories +# spread out over the entire source repository. ADDED .cvs/.old_mttroot_cvsroot/notify Index: .cvs/.old_mttroot_cvsroot/notify ================================================================== --- .cvs/.old_mttroot_cvsroot/notify +++ .cvs/.old_mttroot_cvsroot/notify @@ -0,0 +1,12 @@ +# The "notify" file controls where notifications from watches set by +# "cvs watch add" or "cvs edit" are sent. The first entry on a line is +# a regular expression which is tested against the directory that the +# change is being made to, relative to the $CVSROOT. If it matches, +# then the remainder of the line is a filter program that should contain +# one occurrence of %s for the user to notify, and information on its +# standard input. +# +# "ALL" or "DEFAULT" can be used in place of the regular expression. +# +# For example: +#ALL mail %s -s "CVS notification" ADDED .cvs/.old_mttroot_cvsroot/rcsinfo Index: .cvs/.old_mttroot_cvsroot/rcsinfo ================================================================== --- .cvs/.old_mttroot_cvsroot/rcsinfo +++ .cvs/.old_mttroot_cvsroot/rcsinfo @@ -0,0 +1,13 @@ +# The "rcsinfo" file is used to control templates with which the editor +# is invoked on commit and import. +# +# The first entry on a line is a regular expression which is tested +# against the directory that the change is being made to, relative to the +# $CVSROOT. For the first match that is found, then the remainder of the +# line is the name of the file that contains the template. +# +# If the repository name does not match any of the regular expressions in this +# file, the "DEFAULT" line is used, if it is specified. +# +# If the name "ALL" appears as a regular expression it is always used +# in addition to the first matching regex or "DEFAULT". ADDED .cvs/.old_mttroot_cvsroot/syncmail Index: .cvs/.old_mttroot_cvsroot/syncmail ================================================================== --- .cvs/.old_mttroot_cvsroot/syncmail +++ .cvs/.old_mttroot_cvsroot/syncmail @@ -0,0 +1,459 @@ +#! /usr/bin/python + +# Copyright (c) 2002, 2003, Barry Warsaw, Fred Drake, and contributors +# All rights reserved. +# See the accompanying LICENSE file for details. + +# Compatibility: Python 2.2.3, tied to the version of Python on SourceForge's +# authenticated CVS server. + +"""Complicated notification for CVS checkins. + +This script is used to provide email notifications of changes to the CVS +repository. These email changes will include context diffs of the changes. +Really big diffs will be trimmed. + +This script is run from a CVS loginfo file (see $CVSROOT/CVSROOT/loginfo). To +set this up, create a loginfo entry that looks something like this: + + mymodule /path/to/this/script %%s some-email-addr@your.domain + +In this example, whenever a checkin that matches `mymodule' is made, this +script is invoked, which will generate the diff containing email, and send it +to some-email-addr@your.domain. + + Note: This module used to also do repository synchronizations via + rsync-over-ssh, but since the repository has been moved to SourceForge, + this is no longer necessary. The syncing functionality has been ripped + out in the 3.0, which simplifies it considerably. Access the 2.x versions + to refer to this functionality. Because of this, the script is misnamed. + +It no longer makes sense to run this script from the command line. Doing so +will only print out this usage information. + +Usage: + + %(PROGRAM)s [options] <%%S> email-addr [email-addr ...] + +Where options are: + + --cvsroot= + Use as the environment variable CVSROOT. Otherwise this + variable must exist in the environment. + + --context=# + -C # + Include # lines of context around lines that differ (default: 2). + + -c + Produce a context diff (default). + + -m hostname + --mailhost hostname + The hostname of an available SMTP server. The default is + 'localhost'. + + -u + Produce a unified diff (smaller). + + -S TEXT + --subject-prefix=TEXT + Prepend TEXT to the email subject line. + + -R ADDR + --reply-to=ADDR + Add a "Reply-To: ADDR" header to the email message. + + --quiet / -q + Don't print as much status to stdout. + + --fromhost=hostname + -f hostname + The hostname that email messages appear to be coming from. The From: + header of the outgoing message will look like user@hostname. By + default, hostname is the machine's fully qualified domain name. + + --help / -h + Print this text. + +The rest of the command line arguments are: + + <%%S> + CVS %%s loginfo expansion. When invoked by CVS, this will be a single + string containing the directory the checkin is being made in, relative + to $CVSROOT, followed by the list of files that are changing. If the + %%s in the loginfo file is %%{sVv}, context diffs for each of the + modified files are included in any email messages that are generated. + + email-addrs + At least one email address. +""" +__version__ = '1.2' + +import os +import sys +import re +import time +import string +import getopt +import smtplib +import pwd +import socket + +try: + from socket import getfqdn +except ImportError: + def getfqdn(): + # Python 1.5.2 :( + hostname = socket.gethostname() + byaddr = socket.gethostbyaddr(socket.gethostbyname(hostname)) + aliases = byaddr[1] + aliases.insert(0, byaddr[0]) + aliases.insert(0, hostname) + for fqdn in aliases: + if '.' in fqdn: + break + else: + fqdn = 'localhost.localdomain' + return fqdn + + +from cStringIO import StringIO + +# Which SMTP server to do we connect to? +MAILHOST = 'localhost' +MAILPORT = 25 + +# Diff trimming stuff +DIFF_HEAD_LINES = 20 +DIFF_TAIL_LINES = 20 +DIFF_TRUNCATE_IF_LARGER = 1000 + +COMMASPACE = ', ' + +PROGRAM = sys.argv[0] + +BINARY_EXPLANATION_LINES = [ + "(This appears to be a binary file; contents omitted.)\n" + ] + +NOVERSION = "Couldn't generate diff; no version number found for file: %s" +BACKSLASH = "Couldn't generate diff: backslash in filespec's filename: %s" + + + +def usage(code, msg=''): + print __doc__ % globals() + if msg: + print msg + sys.exit(code) + + + +def calculate_diff(entry, contextlines): + file = entry.name + oldrev = entry.revision + newrev = entry.new_revision + + # Make sure we can find a CVS version number + if oldrev is None and newrev is None: + return NOVERSION % file + + if string.find(file, "'") <> -1: + # Those crazy users put single-quotes in their file names! Now we + # have to escape everything that is meaningful inside double-quotes. + filestr = string.replace(file, '\\', '\\\\') + filestr = string.replace(filestr, '`', '\`') + filestr = string.replace(filestr, '"', '\"') + filestr = string.replace(filestr, '$', '\$') + # and quote it with double-quotes. + filestr = '"' + filestr + '"' + else: + # quote it with single-quotes. + filestr = "'" + file + "'" + if oldrev is None: + # File is being added. + try: + if os.path.exists(file): + fp = open(file) + else: + update_cmd = "cvs -fn update -r %s -p %s" % (newrev, filestr) + fp = os.popen(update_cmd) + lines = fp.readlines() + fp.close() + # Is this a binary file? Let's look at the first few + # lines to figure it out: + for line in lines[:5]: + for c in string.rstrip(line): + if c in string.whitespace: + continue + if c < ' ' or c > chr(127): + lines = BINARY_EXPLANATION_LINES[:] + break + lines.insert(0, '--- NEW FILE: %s ---\n' % file) + except IOError, e: + lines = ['***** Error reading new file: ', + str(e), '\n***** file: ', file, ' cwd: ', os.getcwd()] + elif newrev is None: + lines = ['--- %s DELETED ---\n' % file] + else: + # File has been changed. + # This /has/ to happen in the background, otherwise we'll run into CVS + # lock contention. What a crock. + if contextlines > 0: + difftype = "-C " + str(contextlines) + else: + difftype = "-u" + diffcmd = "/usr/bin/cvs -f diff -kk %s --minimal -r %s -r %s %s" \ + % (difftype, oldrev, newrev, filestr) + fp = os.popen(diffcmd) + lines = fp.readlines() + # ignore the error code, it always seems to be 1 :( + fp.close() + if len(lines) > DIFF_TRUNCATE_IF_LARGER: + removedlines = len(lines) - DIFF_HEAD_LINES - DIFF_TAIL_LINES + del lines[DIFF_HEAD_LINES:-DIFF_TAIL_LINES] + lines.insert(DIFF_HEAD_LINES, + '[...%d lines suppressed...]\n' % removedlines) + return string.join(lines, '') + + + +rfc822_specials_re = re.compile(r'[\(\)\<\>\@\,\;\:\\\"\.\[\]]') + +def quotename(name): + if name and rfc822_specials_re.search(name): + return '"%s"' % string.replace(name, '"', '\\"') + else: + return name + + + +def blast_mail(subject, people, entries, contextlines, fromhost, replyto): + # cannot wait for child process or that will cause parent to retain cvs + # lock for too long. Urg! + if not os.fork(): + # in the child + # give up the lock you cvs thang! + time.sleep(2) + # Create the smtp connection to the localhost + conn = smtplib.SMTP() + conn.connect(MAILHOST, MAILPORT) + user = pwd.getpwuid(os.getuid())[0] + name = string.split(pwd.getpwuid(os.getuid())[4], ',')[0] + domain = fromhost or getfqdn() + address = '%s@%s' % (user, domain) + s = StringIO() + sys.stdout = s + datestamp = time.strftime('%a, %d %b %Y %H:%M:%S +0000', + time.gmtime(time.time())) + try: + vars = {'address' : address, + 'name' : quotename(name), + 'people' : string.join(people, COMMASPACE), + 'subject' : subject, + 'version' : __version__, + 'date' : datestamp, + } + print '''\ +From: %(name)s <%(address)s> +To: %(people)s''' % vars + if replyto: + print 'Reply-To: %s' % replyto + print '''\ +Subject: %(subject)s +Date: %(date)s +X-Mailer: Python syncmail %(version)s +''' % vars + s.write(sys.stdin.read()) + # append the diffs if available + print + for entry in entries: + print calculate_diff(entry, contextlines) + finally: + sys.stdout = sys.__stdout__ + resp = conn.sendmail(address, people, s.getvalue()) + conn.close() + os._exit(0) + + + +class CVSEntry: + def __init__(self, name, revision, timestamp, conflict, options, tagdate): + self.name = name + self.revision = revision + self.timestamp = timestamp + self.conflict = conflict + self.options = options + self.tagdate = tagdate + +def get_entry(prefix, mapping, line, filename): + line = string.strip(line) + parts = string.split(line, "/") + _, name, revision, timestamp, options, tagdate = parts + key = namekey(prefix, name) + try: + entry = mapping[key] + except KeyError: + if revision == "0": + revision = None + if string.find(timestamp, "+") != -1: + timestamp, conflict = tuple(string.split(timestamp, "+")) + else: + conflict = None + entry = CVSEntry(key, revision, timestamp, conflict, + options, tagdate) + mapping[key] = entry + return entry + +def namekey(prefix, name): + if prefix: + return os.path.join(prefix, name) + else: + return name + +def load_change_info(prefix=None): + if prefix is not None: + entries_fn = os.path.join(prefix, "CVS", "Entries") + else: + entries_fn = os.path.join("CVS", "Entries") + entries_log_fn = entries_fn + ".Log" + mapping = {} + f = open(entries_fn) + while 1: + line = f.readline() + if not line: + break +## if string.strip(line) == "D": +## continue + # we could recurse down subdirs, except the Entries.Log files + # we need haven't been written to the subdirs yet, so it + # doesn't do us any good +## if line[0] == "D": +## name = string.split(line, "/")[1] +## dirname = namekey(prefix, name) +## if os.path.isdir(dirname): +## m = load_change_info(dirname) +## mapping.update(m) + if line[0] == "/": + # normal file + get_entry(prefix, mapping, line, entries_fn) + # else: bogus Entries line + f.close() + if os.path.isfile(entries_log_fn): + f = open(entries_log_fn) + while 1: + line = f.readline() + if not line: + break + if line[1:2] != ' ': + # really old version of CVS + break + entry = get_entry(prefix, mapping, line[2:], entries_log_fn) + parts = string.split(line, "/")[1:] + if line[0] == "A": + # adding a file + entry.new_revision = parts[1] + elif line[0] == "R": + # removing a file + entry.new_revision = None + f.close() + for entry in mapping.values(): + if not hasattr(entry, "new_revision"): + print 'confused about file', entry.name, '-- ignoring' + del mapping[entry.name] + return mapping + +def load_branch_name(): + tag_fn = os.path.join("CVS", "Tag") + if os.path.isfile(tag_fn): + f = open(tag_fn) + line = string.strip(f.readline()) + f.close() + if line[:1] == "T": + return line[1:] + return None + +# scan args for options +def main(): + # XXX Should really move all the options to an object, just to + # avoid threading so many positional args through everything. + try: + opts, args = getopt.getopt( + sys.argv[1:], 'hC:cuS:R:qf:m:', + ['fromhost=', 'context=', 'cvsroot=', 'mailhost=', + 'subject-prefix=', 'reply-to=', + 'help', 'quiet']) + except getopt.error, msg: + usage(1, msg) + + # parse the options + contextlines = 2 + verbose = 1 + subject_prefix = "" + replyto = None + fromhost = None + for opt, arg in opts: + if opt in ('-h', '--help'): + usage(0) + elif opt == '--cvsroot': + os.environ['CVSROOT'] = arg + elif opt in ('-C', '--context'): + contextlines = int(arg) + elif opt == '-c': + if contextlines <= 0: + contextlines = 2 + elif opt == '-u': + contextlines = 0 + elif opt in ('-S', '--subject-prefix'): + subject_prefix = arg + elif opt in ('-R', '--reply-to'): + replyto = arg + elif opt in ('-q', '--quiet'): + verbose = 0 + elif opt in ('-f', '--fromhost'): + fromhost = arg + elif opt in ('-m', '--mailhost'): + global MAILHOST + MAILHOST = arg + + # What follows is the specification containing the files that were + # modified. The argument actually must be split, with the first component + # containing the directory the checkin is being made in, relative to + # $CVSROOT, followed by the list of files that are changing. + if not args: + usage(1, 'No CVS module specified') + changes = load_change_info() + branch = load_branch_name() + subject = subject_prefix + args[0] + specs = string.split(args[0]) + del args[0] + + # The remaining args should be the email addresses + if not args: + usage(1, 'No recipients specified') + + # Now do the mail command + people = args + + if specs[-3:] == ['-', 'Imported', 'sources']: + print 'Not sending email for imported sources.' + return + + if verbose: +## print 'Python version', sys.version +## os.system("type python1.6; type python2;" +## " type python2.0; type python2.1; type python2.2;" +## " type rcsdiff; type rlog") + print 'Mailing %s...' % string.join(people, COMMASPACE) + print 'Generating notification message...' + blast_mail(subject, people, changes.values(), + contextlines, fromhost, replyto) + if verbose: + print 'Generating notification message... done.' + + + +if __name__ == '__main__': + main() + sys.exit(0) ADDED .cvs/.old_mttroot_cvsroot/taginfo Index: .cvs/.old_mttroot_cvsroot/taginfo ================================================================== --- .cvs/.old_mttroot_cvsroot/taginfo +++ .cvs/.old_mttroot_cvsroot/taginfo @@ -0,0 +1,20 @@ +# The "taginfo" file is used to control pre-tag checks. +# The filter on the right is invoked with the following arguments: +# +# $1 -- tagname +# $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d +# $3 -- repository +# $4-> file revision [file revision ...] +# +# A non-zero exit of the filter program will cause the tag to be aborted. +# +# The first entry on a line is a regular expression which is tested +# against the directory that the change is being committed to, relative +# to the $CVSROOT. For the first match that is found, then the remainder +# of the line is the name of the filter to run. +# +# If the repository name does not match any of the regular expressions in this +# file, the "DEFAULT" line is used, if it is specified. +# +# If the name "ALL" appears as a regular expression it is always used +# in addition to the first matching regex or "DEFAULT". ADDED .cvs/.old_mttroot_cvsroot/verifymsg Index: .cvs/.old_mttroot_cvsroot/verifymsg ================================================================== --- .cvs/.old_mttroot_cvsroot/verifymsg +++ .cvs/.old_mttroot_cvsroot/verifymsg @@ -0,0 +1,21 @@ +# The "verifymsg" file is used to allow verification of logging +# information. It works best when a template (as specified in the +# rcsinfo file) is provided for the logging procedure. Given a +# template with locations for, a bug-id number, a list of people who +# reviewed the code before it can be checked in, and an external +# process to catalog the differences that were code reviewed, the +# following test can be applied to the code: +# +# Making sure that the entered bug-id number is correct. +# Validating that the code that was reviewed is indeed the code being +# checked in (using the bug-id number or a seperate review +# number to identify this particular code set.). +# +# If any of the above test failed, then the commit would be aborted. +# +# Actions such as mailing a copy of the report to each reviewer are +# better handled by an entry in the loginfo file. +# +# One thing that should be noted is the the ALL keyword is not +# supported. There can be only one entry that matches a given +# repository. DELETED .old_cvsroot/checkoutlist Index: .old_cvsroot/checkoutlist ================================================================== --- .old_cvsroot/checkoutlist +++ .old_cvsroot/checkoutlist @@ -1,14 +0,0 @@ -# The "checkoutlist" file is used to support additional version controlled -# administrative files in $CVSROOT/CVSROOT, such as template files. -# -# The first entry on a line is a filename which will be checked out from -# the corresponding RCS file in the $CVSROOT/CVSROOT directory. -# The remainder of the line is an error message to use if the file cannot -# be checked out. -# -# File format: -# -# [] -# -# comment lines begin with '#' -syncmail DELETED .old_cvsroot/commitinfo Index: .old_cvsroot/commitinfo ================================================================== --- .old_cvsroot/commitinfo +++ .old_cvsroot/commitinfo @@ -1,15 +0,0 @@ -# The "commitinfo" file is used to control pre-commit checks. -# The filter on the right is invoked with the repository and a list -# of files to check. A non-zero exit of the filter program will -# cause the commit to be aborted. -# -# The first entry on a line is a regular expression which is tested -# against the directory that the change is being committed to, relative -# to the $CVSROOT. For the first match that is found, then the remainder -# of the line is the name of the filter to run. -# -# If the repository name does not match any of the regular expressions in this -# file, the "DEFAULT" line is used, if it is specified. -# -# If the name "ALL" appears as a regular expression it is always used -# in addition to the first matching regex or "DEFAULT". DELETED .old_cvsroot/config Index: .old_cvsroot/config ================================================================== --- .old_cvsroot/config +++ .old_cvsroot/config @@ -1,11 +0,0 @@ -# Set this to "no" if pserver shouldn't check system users/passwords -#SystemAuth=no - -# Set `PreservePermissions' to `yes' to save file status information -# in the repository. -#PreservePermissions=no - -# Set `TopLevelAdmin' to `yes' to create a CVS directory at the top -# level of the new working directory when using the `cvs checkout' -# command. -#TopLevelAdmin=no DELETED .old_cvsroot/cvswrappers Index: .old_cvsroot/cvswrappers ================================================================== --- .old_cvsroot/cvswrappers +++ .old_cvsroot/cvswrappers @@ -1,23 +0,0 @@ -# This file affects handling of files based on their names. -# -# The -t/-f options allow one to treat directories of files -# as a single file, or to transform a file in other ways on -# its way in and out of CVS. -# -# The -m option specifies whether CVS attempts to merge files. -# -# The -k option specifies keyword expansion (e.g. -kb for binary). -# -# Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers) -# -# wildcard [option value][option value]... -# -# where option is one of -# -f from cvs filter value: path to filter -# -t to cvs filter value: path to filter -# -m update methodology value: MERGE or COPY -# -k expansion mode value: b, o, kkv, &c -# -# and value is a single-quote delimited value. -# For example: -#*.gif -k 'b' DELETED .old_cvsroot/editinfo Index: .old_cvsroot/editinfo ================================================================== --- .old_cvsroot/editinfo +++ .old_cvsroot/editinfo @@ -1,21 +0,0 @@ -# The "editinfo" file is used to allow verification of logging -# information. It works best when a template (as specified in the -# rcsinfo file) is provided for the logging procedure. Given a -# template with locations for, a bug-id number, a list of people who -# reviewed the code before it can be checked in, and an external -# process to catalog the differences that were code reviewed, the -# following test can be applied to the code: -# -# Making sure that the entered bug-id number is correct. -# Validating that the code that was reviewed is indeed the code being -# checked in (using the bug-id number or a seperate review -# number to identify this particular code set.). -# -# If any of the above test failed, then the commit would be aborted. -# -# Actions such as mailing a copy of the report to each reviewer are -# better handled by an entry in the loginfo file. -# -# One thing that should be noted is the the ALL keyword is not -# supported. There can be only one entry that matches a given -# repository. DELETED .old_cvsroot/loginfo Index: .old_cvsroot/loginfo ================================================================== --- .old_cvsroot/loginfo +++ .old_cvsroot/loginfo @@ -1,30 +0,0 @@ -# The "loginfo" file controls where "cvs commit" log information -# is sent. The first entry on a line is a regular expression which must match -# the directory that the change is being made to, relative to the -# $CVSROOT. If a match is found, then the remainder of the line is a filter -# program that should expect log information on its standard input. -# -# If the repository name does not match any of the regular expressions in this -# file, the "DEFAULT" line is used, if it is specified. -# -# If the name ALL appears as a regular expression it is always used -# in addition to the first matching regex or DEFAULT. -# -# You may specify a format string as part of the -# filter. The string is composed of a `%' followed -# by a single format character, or followed by a set of format -# characters surrounded by `{' and `}' as separators. The format -# characters are: -# -# s = file name -# V = old version number (pre-checkin) -# v = new version number (post-checkin) -# -# For example: -#DEFAULT (echo ""; id; echo %s; date; cat) >> $CVSROOT/CVSROOT/commitlog -# or -#DEFAULT (echo ""; id; echo %{sVv}; date; cat) >> $CVSROOT/CVSROOT/commitlog - -# Lines to mail changes -CVSROOT $CVSROOT/CVSROOT/syncmail %{sVv} gawthrop@users.sourceforge.net -DEFAULT $CVSROOT/CVSROOT/syncmail %{sVv} mtt-checkins@lists.sourceforge.net DELETED .old_cvsroot/modules Index: .old_cvsroot/modules ================================================================== --- .old_cvsroot/modules +++ .old_cvsroot/modules @@ -1,26 +0,0 @@ -# Three different line formats are valid: -# key -a aliases... -# key [options] directory -# key [options] directory files... -# -# Where "options" are composed of: -# -i prog Run "prog" on "cvs commit" from top-level of module. -# -o prog Run "prog" on "cvs checkout" of module. -# -e prog Run "prog" on "cvs export" of module. -# -t prog Run "prog" on "cvs rtag" of module. -# -u prog Run "prog" on "cvs update" of module. -# -d dir Place module in directory "dir" instead of module name. -# -l Top-level directory only -- do not recurse. -# -# NOTE: If you change any of the "Run" options above, you'll have to -# release and re-checkout any working directories of these modules. -# -# And "directory" is a path to a directory relative to $CVSROOT. -# -# The "-a" option specifies an alias. An alias is interpreted as if -# everything on the right of the "-a" had been typed on the command line. -# -# You can encode a module within a module by using the special '&' -# character to interpose another module into the current module. This -# can be useful for creating a module that consists of many directories -# spread out over the entire source repository. DELETED .old_cvsroot/notify Index: .old_cvsroot/notify ================================================================== --- .old_cvsroot/notify +++ .old_cvsroot/notify @@ -1,12 +0,0 @@ -# The "notify" file controls where notifications from watches set by -# "cvs watch add" or "cvs edit" are sent. The first entry on a line is -# a regular expression which is tested against the directory that the -# change is being made to, relative to the $CVSROOT. If it matches, -# then the remainder of the line is a filter program that should contain -# one occurrence of %s for the user to notify, and information on its -# standard input. -# -# "ALL" or "DEFAULT" can be used in place of the regular expression. -# -# For example: -#ALL mail %s -s "CVS notification" DELETED .old_cvsroot/rcsinfo Index: .old_cvsroot/rcsinfo ================================================================== --- .old_cvsroot/rcsinfo +++ .old_cvsroot/rcsinfo @@ -1,13 +0,0 @@ -# The "rcsinfo" file is used to control templates with which the editor -# is invoked on commit and import. -# -# The first entry on a line is a regular expression which is tested -# against the directory that the change is being made to, relative to the -# $CVSROOT. For the first match that is found, then the remainder of the -# line is the name of the file that contains the template. -# -# If the repository name does not match any of the regular expressions in this -# file, the "DEFAULT" line is used, if it is specified. -# -# If the name "ALL" appears as a regular expression it is always used -# in addition to the first matching regex or "DEFAULT". DELETED .old_cvsroot/syncmail Index: .old_cvsroot/syncmail ================================================================== --- .old_cvsroot/syncmail +++ .old_cvsroot/syncmail @@ -1,459 +0,0 @@ -#! /usr/bin/python - -# Copyright (c) 2002, 2003, Barry Warsaw, Fred Drake, and contributors -# All rights reserved. -# See the accompanying LICENSE file for details. - -# Compatibility: Python 2.2.3, tied to the version of Python on SourceForge's -# authenticated CVS server. - -"""Complicated notification for CVS checkins. - -This script is used to provide email notifications of changes to the CVS -repository. These email changes will include context diffs of the changes. -Really big diffs will be trimmed. - -This script is run from a CVS loginfo file (see $CVSROOT/CVSROOT/loginfo). To -set this up, create a loginfo entry that looks something like this: - - mymodule /path/to/this/script %%s some-email-addr@your.domain - -In this example, whenever a checkin that matches `mymodule' is made, this -script is invoked, which will generate the diff containing email, and send it -to some-email-addr@your.domain. - - Note: This module used to also do repository synchronizations via - rsync-over-ssh, but since the repository has been moved to SourceForge, - this is no longer necessary. The syncing functionality has been ripped - out in the 3.0, which simplifies it considerably. Access the 2.x versions - to refer to this functionality. Because of this, the script is misnamed. - -It no longer makes sense to run this script from the command line. Doing so -will only print out this usage information. - -Usage: - - %(PROGRAM)s [options] <%%S> email-addr [email-addr ...] - -Where options are: - - --cvsroot= - Use as the environment variable CVSROOT. Otherwise this - variable must exist in the environment. - - --context=# - -C # - Include # lines of context around lines that differ (default: 2). - - -c - Produce a context diff (default). - - -m hostname - --mailhost hostname - The hostname of an available SMTP server. The default is - 'localhost'. - - -u - Produce a unified diff (smaller). - - -S TEXT - --subject-prefix=TEXT - Prepend TEXT to the email subject line. - - -R ADDR - --reply-to=ADDR - Add a "Reply-To: ADDR" header to the email message. - - --quiet / -q - Don't print as much status to stdout. - - --fromhost=hostname - -f hostname - The hostname that email messages appear to be coming from. The From: - header of the outgoing message will look like user@hostname. By - default, hostname is the machine's fully qualified domain name. - - --help / -h - Print this text. - -The rest of the command line arguments are: - - <%%S> - CVS %%s loginfo expansion. When invoked by CVS, this will be a single - string containing the directory the checkin is being made in, relative - to $CVSROOT, followed by the list of files that are changing. If the - %%s in the loginfo file is %%{sVv}, context diffs for each of the - modified files are included in any email messages that are generated. - - email-addrs - At least one email address. -""" -__version__ = '1.2' - -import os -import sys -import re -import time -import string -import getopt -import smtplib -import pwd -import socket - -try: - from socket import getfqdn -except ImportError: - def getfqdn(): - # Python 1.5.2 :( - hostname = socket.gethostname() - byaddr = socket.gethostbyaddr(socket.gethostbyname(hostname)) - aliases = byaddr[1] - aliases.insert(0, byaddr[0]) - aliases.insert(0, hostname) - for fqdn in aliases: - if '.' in fqdn: - break - else: - fqdn = 'localhost.localdomain' - return fqdn - - -from cStringIO import StringIO - -# Which SMTP server to do we connect to? -MAILHOST = 'localhost' -MAILPORT = 25 - -# Diff trimming stuff -DIFF_HEAD_LINES = 20 -DIFF_TAIL_LINES = 20 -DIFF_TRUNCATE_IF_LARGER = 1000 - -COMMASPACE = ', ' - -PROGRAM = sys.argv[0] - -BINARY_EXPLANATION_LINES = [ - "(This appears to be a binary file; contents omitted.)\n" - ] - -NOVERSION = "Couldn't generate diff; no version number found for file: %s" -BACKSLASH = "Couldn't generate diff: backslash in filespec's filename: %s" - - - -def usage(code, msg=''): - print __doc__ % globals() - if msg: - print msg - sys.exit(code) - - - -def calculate_diff(entry, contextlines): - file = entry.name - oldrev = entry.revision - newrev = entry.new_revision - - # Make sure we can find a CVS version number - if oldrev is None and newrev is None: - return NOVERSION % file - - if string.find(file, "'") <> -1: - # Those crazy users put single-quotes in their file names! Now we - # have to escape everything that is meaningful inside double-quotes. - filestr = string.replace(file, '\\', '\\\\') - filestr = string.replace(filestr, '`', '\`') - filestr = string.replace(filestr, '"', '\"') - filestr = string.replace(filestr, '$', '\$') - # and quote it with double-quotes. - filestr = '"' + filestr + '"' - else: - # quote it with single-quotes. - filestr = "'" + file + "'" - if oldrev is None: - # File is being added. - try: - if os.path.exists(file): - fp = open(file) - else: - update_cmd = "cvs -fn update -r %s -p %s" % (newrev, filestr) - fp = os.popen(update_cmd) - lines = fp.readlines() - fp.close() - # Is this a binary file? Let's look at the first few - # lines to figure it out: - for line in lines[:5]: - for c in string.rstrip(line): - if c in string.whitespace: - continue - if c < ' ' or c > chr(127): - lines = BINARY_EXPLANATION_LINES[:] - break - lines.insert(0, '--- NEW FILE: %s ---\n' % file) - except IOError, e: - lines = ['***** Error reading new file: ', - str(e), '\n***** file: ', file, ' cwd: ', os.getcwd()] - elif newrev is None: - lines = ['--- %s DELETED ---\n' % file] - else: - # File has been changed. - # This /has/ to happen in the background, otherwise we'll run into CVS - # lock contention. What a crock. - if contextlines > 0: - difftype = "-C " + str(contextlines) - else: - difftype = "-u" - diffcmd = "/usr/bin/cvs -f diff -kk %s --minimal -r %s -r %s %s" \ - % (difftype, oldrev, newrev, filestr) - fp = os.popen(diffcmd) - lines = fp.readlines() - # ignore the error code, it always seems to be 1 :( - fp.close() - if len(lines) > DIFF_TRUNCATE_IF_LARGER: - removedlines = len(lines) - DIFF_HEAD_LINES - DIFF_TAIL_LINES - del lines[DIFF_HEAD_LINES:-DIFF_TAIL_LINES] - lines.insert(DIFF_HEAD_LINES, - '[...%d lines suppressed...]\n' % removedlines) - return string.join(lines, '') - - - -rfc822_specials_re = re.compile(r'[\(\)\<\>\@\,\;\:\\\"\.\[\]]') - -def quotename(name): - if name and rfc822_specials_re.search(name): - return '"%s"' % string.replace(name, '"', '\\"') - else: - return name - - - -def blast_mail(subject, people, entries, contextlines, fromhost, replyto): - # cannot wait for child process or that will cause parent to retain cvs - # lock for too long. Urg! - if not os.fork(): - # in the child - # give up the lock you cvs thang! - time.sleep(2) - # Create the smtp connection to the localhost - conn = smtplib.SMTP() - conn.connect(MAILHOST, MAILPORT) - user = pwd.getpwuid(os.getuid())[0] - name = string.split(pwd.getpwuid(os.getuid())[4], ',')[0] - domain = fromhost or getfqdn() - address = '%s@%s' % (user, domain) - s = StringIO() - sys.stdout = s - datestamp = time.strftime('%a, %d %b %Y %H:%M:%S +0000', - time.gmtime(time.time())) - try: - vars = {'address' : address, - 'name' : quotename(name), - 'people' : string.join(people, COMMASPACE), - 'subject' : subject, - 'version' : __version__, - 'date' : datestamp, - } - print '''\ -From: %(name)s <%(address)s> -To: %(people)s''' % vars - if replyto: - print 'Reply-To: %s' % replyto - print '''\ -Subject: %(subject)s -Date: %(date)s -X-Mailer: Python syncmail %(version)s -''' % vars - s.write(sys.stdin.read()) - # append the diffs if available - print - for entry in entries: - print calculate_diff(entry, contextlines) - finally: - sys.stdout = sys.__stdout__ - resp = conn.sendmail(address, people, s.getvalue()) - conn.close() - os._exit(0) - - - -class CVSEntry: - def __init__(self, name, revision, timestamp, conflict, options, tagdate): - self.name = name - self.revision = revision - self.timestamp = timestamp - self.conflict = conflict - self.options = options - self.tagdate = tagdate - -def get_entry(prefix, mapping, line, filename): - line = string.strip(line) - parts = string.split(line, "/") - _, name, revision, timestamp, options, tagdate = parts - key = namekey(prefix, name) - try: - entry = mapping[key] - except KeyError: - if revision == "0": - revision = None - if string.find(timestamp, "+") != -1: - timestamp, conflict = tuple(string.split(timestamp, "+")) - else: - conflict = None - entry = CVSEntry(key, revision, timestamp, conflict, - options, tagdate) - mapping[key] = entry - return entry - -def namekey(prefix, name): - if prefix: - return os.path.join(prefix, name) - else: - return name - -def load_change_info(prefix=None): - if prefix is not None: - entries_fn = os.path.join(prefix, "CVS", "Entries") - else: - entries_fn = os.path.join("CVS", "Entries") - entries_log_fn = entries_fn + ".Log" - mapping = {} - f = open(entries_fn) - while 1: - line = f.readline() - if not line: - break -## if string.strip(line) == "D": -## continue - # we could recurse down subdirs, except the Entries.Log files - # we need haven't been written to the subdirs yet, so it - # doesn't do us any good -## if line[0] == "D": -## name = string.split(line, "/")[1] -## dirname = namekey(prefix, name) -## if os.path.isdir(dirname): -## m = load_change_info(dirname) -## mapping.update(m) - if line[0] == "/": - # normal file - get_entry(prefix, mapping, line, entries_fn) - # else: bogus Entries line - f.close() - if os.path.isfile(entries_log_fn): - f = open(entries_log_fn) - while 1: - line = f.readline() - if not line: - break - if line[1:2] != ' ': - # really old version of CVS - break - entry = get_entry(prefix, mapping, line[2:], entries_log_fn) - parts = string.split(line, "/")[1:] - if line[0] == "A": - # adding a file - entry.new_revision = parts[1] - elif line[0] == "R": - # removing a file - entry.new_revision = None - f.close() - for entry in mapping.values(): - if not hasattr(entry, "new_revision"): - print 'confused about file', entry.name, '-- ignoring' - del mapping[entry.name] - return mapping - -def load_branch_name(): - tag_fn = os.path.join("CVS", "Tag") - if os.path.isfile(tag_fn): - f = open(tag_fn) - line = string.strip(f.readline()) - f.close() - if line[:1] == "T": - return line[1:] - return None - -# scan args for options -def main(): - # XXX Should really move all the options to an object, just to - # avoid threading so many positional args through everything. - try: - opts, args = getopt.getopt( - sys.argv[1:], 'hC:cuS:R:qf:m:', - ['fromhost=', 'context=', 'cvsroot=', 'mailhost=', - 'subject-prefix=', 'reply-to=', - 'help', 'quiet']) - except getopt.error, msg: - usage(1, msg) - - # parse the options - contextlines = 2 - verbose = 1 - subject_prefix = "" - replyto = None - fromhost = None - for opt, arg in opts: - if opt in ('-h', '--help'): - usage(0) - elif opt == '--cvsroot': - os.environ['CVSROOT'] = arg - elif opt in ('-C', '--context'): - contextlines = int(arg) - elif opt == '-c': - if contextlines <= 0: - contextlines = 2 - elif opt == '-u': - contextlines = 0 - elif opt in ('-S', '--subject-prefix'): - subject_prefix = arg - elif opt in ('-R', '--reply-to'): - replyto = arg - elif opt in ('-q', '--quiet'): - verbose = 0 - elif opt in ('-f', '--fromhost'): - fromhost = arg - elif opt in ('-m', '--mailhost'): - global MAILHOST - MAILHOST = arg - - # What follows is the specification containing the files that were - # modified. The argument actually must be split, with the first component - # containing the directory the checkin is being made in, relative to - # $CVSROOT, followed by the list of files that are changing. - if not args: - usage(1, 'No CVS module specified') - changes = load_change_info() - branch = load_branch_name() - subject = subject_prefix + args[0] - specs = string.split(args[0]) - del args[0] - - # The remaining args should be the email addresses - if not args: - usage(1, 'No recipients specified') - - # Now do the mail command - people = args - - if specs[-3:] == ['-', 'Imported', 'sources']: - print 'Not sending email for imported sources.' - return - - if verbose: -## print 'Python version', sys.version -## os.system("type python1.6; type python2;" -## " type python2.0; type python2.1; type python2.2;" -## " type rcsdiff; type rlog") - print 'Mailing %s...' % string.join(people, COMMASPACE) - print 'Generating notification message...' - blast_mail(subject, people, changes.values(), - contextlines, fromhost, replyto) - if verbose: - print 'Generating notification message... done.' - - - -if __name__ == '__main__': - main() - sys.exit(0) DELETED .old_cvsroot/taginfo Index: .old_cvsroot/taginfo ================================================================== --- .old_cvsroot/taginfo +++ .old_cvsroot/taginfo @@ -1,20 +0,0 @@ -# The "taginfo" file is used to control pre-tag checks. -# The filter on the right is invoked with the following arguments: -# -# $1 -- tagname -# $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d -# $3 -- repository -# $4-> file revision [file revision ...] -# -# A non-zero exit of the filter program will cause the tag to be aborted. -# -# The first entry on a line is a regular expression which is tested -# against the directory that the change is being committed to, relative -# to the $CVSROOT. For the first match that is found, then the remainder -# of the line is the name of the filter to run. -# -# If the repository name does not match any of the regular expressions in this -# file, the "DEFAULT" line is used, if it is specified. -# -# If the name "ALL" appears as a regular expression it is always used -# in addition to the first matching regex or "DEFAULT". DELETED .old_cvsroot/verifymsg Index: .old_cvsroot/verifymsg ================================================================== --- .old_cvsroot/verifymsg +++ .old_cvsroot/verifymsg @@ -1,21 +0,0 @@ -# The "verifymsg" file is used to allow verification of logging -# information. It works best when a template (as specified in the -# rcsinfo file) is provided for the logging procedure. Given a -# template with locations for, a bug-id number, a list of people who -# reviewed the code before it can be checked in, and an external -# process to catalog the differences that were code reviewed, the -# following test can be applied to the code: -# -# Making sure that the entered bug-id number is correct. -# Validating that the code that was reviewed is indeed the code being -# checked in (using the bug-id number or a seperate review -# number to identify this particular code set.). -# -# If any of the above test failed, then the commit would be aborted. -# -# Actions such as mailing a copy of the report to each reviewer are -# better handled by an entry in the loginfo file. -# -# One thing that should be noted is the the ALL keyword is not -# supported. There can be only one entry that matches a given -# repository. DELETED .old_mttroot_cvsroot/checkoutlist Index: .old_mttroot_cvsroot/checkoutlist ================================================================== --- .old_mttroot_cvsroot/checkoutlist +++ .old_mttroot_cvsroot/checkoutlist @@ -1,14 +0,0 @@ -# The "checkoutlist" file is used to support additional version controlled -# administrative files in $CVSROOT/CVSROOT, such as template files. -# -# The first entry on a line is a filename which will be checked out from -# the corresponding RCS file in the $CVSROOT/CVSROOT directory. -# The remainder of the line is an error message to use if the file cannot -# be checked out. -# -# File format: -# -# [] -# -# comment lines begin with '#' -syncmail DELETED .old_mttroot_cvsroot/commitinfo Index: .old_mttroot_cvsroot/commitinfo ================================================================== --- .old_mttroot_cvsroot/commitinfo +++ .old_mttroot_cvsroot/commitinfo @@ -1,15 +0,0 @@ -# The "commitinfo" file is used to control pre-commit checks. -# The filter on the right is invoked with the repository and a list -# of files to check. A non-zero exit of the filter program will -# cause the commit to be aborted. -# -# The first entry on a line is a regular expression which is tested -# against the directory that the change is being committed to, relative -# to the $CVSROOT. For the first match that is found, then the remainder -# of the line is the name of the filter to run. -# -# If the repository name does not match any of the regular expressions in this -# file, the "DEFAULT" line is used, if it is specified. -# -# If the name "ALL" appears as a regular expression it is always used -# in addition to the first matching regex or "DEFAULT". DELETED .old_mttroot_cvsroot/config Index: .old_mttroot_cvsroot/config ================================================================== --- .old_mttroot_cvsroot/config +++ .old_mttroot_cvsroot/config @@ -1,11 +0,0 @@ -# Set this to "no" if pserver shouldn't check system users/passwords -#SystemAuth=no - -# Set `PreservePermissions' to `yes' to save file status information -# in the repository. -#PreservePermissions=no - -# Set `TopLevelAdmin' to `yes' to create a CVS directory at the top -# level of the new working directory when using the `cvs checkout' -# command. -#TopLevelAdmin=no DELETED .old_mttroot_cvsroot/cvswrappers Index: .old_mttroot_cvsroot/cvswrappers ================================================================== --- .old_mttroot_cvsroot/cvswrappers +++ .old_mttroot_cvsroot/cvswrappers @@ -1,23 +0,0 @@ -# This file affects handling of files based on their names. -# -# The -t/-f options allow one to treat directories of files -# as a single file, or to transform a file in other ways on -# its way in and out of CVS. -# -# The -m option specifies whether CVS attempts to merge files. -# -# The -k option specifies keyword expansion (e.g. -kb for binary). -# -# Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers) -# -# wildcard [option value][option value]... -# -# where option is one of -# -f from cvs filter value: path to filter -# -t to cvs filter value: path to filter -# -m update methodology value: MERGE or COPY -# -k expansion mode value: b, o, kkv, &c -# -# and value is a single-quote delimited value. -# For example: -#*.gif -k 'b' DELETED .old_mttroot_cvsroot/editinfo Index: .old_mttroot_cvsroot/editinfo ================================================================== --- .old_mttroot_cvsroot/editinfo +++ .old_mttroot_cvsroot/editinfo @@ -1,21 +0,0 @@ -# The "editinfo" file is used to allow verification of logging -# information. It works best when a template (as specified in the -# rcsinfo file) is provided for the logging procedure. Given a -# template with locations for, a bug-id number, a list of people who -# reviewed the code before it can be checked in, and an external -# process to catalog the differences that were code reviewed, the -# following test can be applied to the code: -# -# Making sure that the entered bug-id number is correct. -# Validating that the code that was reviewed is indeed the code being -# checked in (using the bug-id number or a seperate review -# number to identify this particular code set.). -# -# If any of the above test failed, then the commit would be aborted. -# -# Actions such as mailing a copy of the report to each reviewer are -# better handled by an entry in the loginfo file. -# -# One thing that should be noted is the the ALL keyword is not -# supported. There can be only one entry that matches a given -# repository. DELETED .old_mttroot_cvsroot/loginfo Index: .old_mttroot_cvsroot/loginfo ================================================================== --- .old_mttroot_cvsroot/loginfo +++ .old_mttroot_cvsroot/loginfo @@ -1,31 +0,0 @@ -# The "loginfo" file controls where "cvs commit" log information -# is sent. The first entry on a line is a regular expression which must match -# the directory that the change is being made to, relative to the -# $CVSROOT. If a match is found, then the remainder of the line is a filter -# program that should expect log information on its standard input. -# -# If the repository name does not match any of the regular expressions in this -# file, the "DEFAULT" line is used, if it is specified. -# -# If the name ALL appears as a regular expression it is always used -# in addition to the first matching regex or DEFAULT. -# -# You may specify a format string as part of the -# filter. The string is composed of a `%' followed -# by a single format character, or followed by a set of format -# characters surrounded by `{' and `}' as separators. The format -# characters are: -# -# s = file name -# V = old version number (pre-checkin) -# v = new version number (post-checkin) -# -# For example: -#DEFAULT (echo ""; id; echo %s; date; cat) >> $CVSROOT/CVSROOT/commitlog -# or -#DEFAULT (echo ""; id; echo %{sVv}; date; cat) >> $CVSROOT/CVSROOT/commitlog - -# Lines to mail changes -CVSROOT $CVSROOT/CVSROOT/syncmail %{sVv} mtt@gawthrop.net -DEFAULT $CVSROOT/CVSROOT/syncmail %{sVv} mtt-cvs@lists.sourceforge.net - DELETED .old_mttroot_cvsroot/modules Index: .old_mttroot_cvsroot/modules ================================================================== --- .old_mttroot_cvsroot/modules +++ .old_mttroot_cvsroot/modules @@ -1,26 +0,0 @@ -# Three different line formats are valid: -# key -a aliases... -# key [options] directory -# key [options] directory files... -# -# Where "options" are composed of: -# -i prog Run "prog" on "cvs commit" from top-level of module. -# -o prog Run "prog" on "cvs checkout" of module. -# -e prog Run "prog" on "cvs export" of module. -# -t prog Run "prog" on "cvs rtag" of module. -# -u prog Run "prog" on "cvs update" of module. -# -d dir Place module in directory "dir" instead of module name. -# -l Top-level directory only -- do not recurse. -# -# NOTE: If you change any of the "Run" options above, you'll have to -# release and re-checkout any working directories of these modules. -# -# And "directory" is a path to a directory relative to $CVSROOT. -# -# The "-a" option specifies an alias. An alias is interpreted as if -# everything on the right of the "-a" had been typed on the command line. -# -# You can encode a module within a module by using the special '&' -# character to interpose another module into the current module. This -# can be useful for creating a module that consists of many directories -# spread out over the entire source repository. DELETED .old_mttroot_cvsroot/notify Index: .old_mttroot_cvsroot/notify ================================================================== --- .old_mttroot_cvsroot/notify +++ .old_mttroot_cvsroot/notify @@ -1,12 +0,0 @@ -# The "notify" file controls where notifications from watches set by -# "cvs watch add" or "cvs edit" are sent. The first entry on a line is -# a regular expression which is tested against the directory that the -# change is being made to, relative to the $CVSROOT. If it matches, -# then the remainder of the line is a filter program that should contain -# one occurrence of %s for the user to notify, and information on its -# standard input. -# -# "ALL" or "DEFAULT" can be used in place of the regular expression. -# -# For example: -#ALL mail %s -s "CVS notification" DELETED .old_mttroot_cvsroot/rcsinfo Index: .old_mttroot_cvsroot/rcsinfo ================================================================== --- .old_mttroot_cvsroot/rcsinfo +++ .old_mttroot_cvsroot/rcsinfo @@ -1,13 +0,0 @@ -# The "rcsinfo" file is used to control templates with which the editor -# is invoked on commit and import. -# -# The first entry on a line is a regular expression which is tested -# against the directory that the change is being made to, relative to the -# $CVSROOT. For the first match that is found, then the remainder of the -# line is the name of the file that contains the template. -# -# If the repository name does not match any of the regular expressions in this -# file, the "DEFAULT" line is used, if it is specified. -# -# If the name "ALL" appears as a regular expression it is always used -# in addition to the first matching regex or "DEFAULT". DELETED .old_mttroot_cvsroot/syncmail Index: .old_mttroot_cvsroot/syncmail ================================================================== --- .old_mttroot_cvsroot/syncmail +++ .old_mttroot_cvsroot/syncmail @@ -1,459 +0,0 @@ -#! /usr/bin/python - -# Copyright (c) 2002, 2003, Barry Warsaw, Fred Drake, and contributors -# All rights reserved. -# See the accompanying LICENSE file for details. - -# Compatibility: Python 2.2.3, tied to the version of Python on SourceForge's -# authenticated CVS server. - -"""Complicated notification for CVS checkins. - -This script is used to provide email notifications of changes to the CVS -repository. These email changes will include context diffs of the changes. -Really big diffs will be trimmed. - -This script is run from a CVS loginfo file (see $CVSROOT/CVSROOT/loginfo). To -set this up, create a loginfo entry that looks something like this: - - mymodule /path/to/this/script %%s some-email-addr@your.domain - -In this example, whenever a checkin that matches `mymodule' is made, this -script is invoked, which will generate the diff containing email, and send it -to some-email-addr@your.domain. - - Note: This module used to also do repository synchronizations via - rsync-over-ssh, but since the repository has been moved to SourceForge, - this is no longer necessary. The syncing functionality has been ripped - out in the 3.0, which simplifies it considerably. Access the 2.x versions - to refer to this functionality. Because of this, the script is misnamed. - -It no longer makes sense to run this script from the command line. Doing so -will only print out this usage information. - -Usage: - - %(PROGRAM)s [options] <%%S> email-addr [email-addr ...] - -Where options are: - - --cvsroot= - Use as the environment variable CVSROOT. Otherwise this - variable must exist in the environment. - - --context=# - -C # - Include # lines of context around lines that differ (default: 2). - - -c - Produce a context diff (default). - - -m hostname - --mailhost hostname - The hostname of an available SMTP server. The default is - 'localhost'. - - -u - Produce a unified diff (smaller). - - -S TEXT - --subject-prefix=TEXT - Prepend TEXT to the email subject line. - - -R ADDR - --reply-to=ADDR - Add a "Reply-To: ADDR" header to the email message. - - --quiet / -q - Don't print as much status to stdout. - - --fromhost=hostname - -f hostname - The hostname that email messages appear to be coming from. The From: - header of the outgoing message will look like user@hostname. By - default, hostname is the machine's fully qualified domain name. - - --help / -h - Print this text. - -The rest of the command line arguments are: - - <%%S> - CVS %%s loginfo expansion. When invoked by CVS, this will be a single - string containing the directory the checkin is being made in, relative - to $CVSROOT, followed by the list of files that are changing. If the - %%s in the loginfo file is %%{sVv}, context diffs for each of the - modified files are included in any email messages that are generated. - - email-addrs - At least one email address. -""" -__version__ = '1.2' - -import os -import sys -import re -import time -import string -import getopt -import smtplib -import pwd -import socket - -try: - from socket import getfqdn -except ImportError: - def getfqdn(): - # Python 1.5.2 :( - hostname = socket.gethostname() - byaddr = socket.gethostbyaddr(socket.gethostbyname(hostname)) - aliases = byaddr[1] - aliases.insert(0, byaddr[0]) - aliases.insert(0, hostname) - for fqdn in aliases: - if '.' in fqdn: - break - else: - fqdn = 'localhost.localdomain' - return fqdn - - -from cStringIO import StringIO - -# Which SMTP server to do we connect to? -MAILHOST = 'localhost' -MAILPORT = 25 - -# Diff trimming stuff -DIFF_HEAD_LINES = 20 -DIFF_TAIL_LINES = 20 -DIFF_TRUNCATE_IF_LARGER = 1000 - -COMMASPACE = ', ' - -PROGRAM = sys.argv[0] - -BINARY_EXPLANATION_LINES = [ - "(This appears to be a binary file; contents omitted.)\n" - ] - -NOVERSION = "Couldn't generate diff; no version number found for file: %s" -BACKSLASH = "Couldn't generate diff: backslash in filespec's filename: %s" - - - -def usage(code, msg=''): - print __doc__ % globals() - if msg: - print msg - sys.exit(code) - - - -def calculate_diff(entry, contextlines): - file = entry.name - oldrev = entry.revision - newrev = entry.new_revision - - # Make sure we can find a CVS version number - if oldrev is None and newrev is None: - return NOVERSION % file - - if string.find(file, "'") <> -1: - # Those crazy users put single-quotes in their file names! Now we - # have to escape everything that is meaningful inside double-quotes. - filestr = string.replace(file, '\\', '\\\\') - filestr = string.replace(filestr, '`', '\`') - filestr = string.replace(filestr, '"', '\"') - filestr = string.replace(filestr, '$', '\$') - # and quote it with double-quotes. - filestr = '"' + filestr + '"' - else: - # quote it with single-quotes. - filestr = "'" + file + "'" - if oldrev is None: - # File is being added. - try: - if os.path.exists(file): - fp = open(file) - else: - update_cmd = "cvs -fn update -r %s -p %s" % (newrev, filestr) - fp = os.popen(update_cmd) - lines = fp.readlines() - fp.close() - # Is this a binary file? Let's look at the first few - # lines to figure it out: - for line in lines[:5]: - for c in string.rstrip(line): - if c in string.whitespace: - continue - if c < ' ' or c > chr(127): - lines = BINARY_EXPLANATION_LINES[:] - break - lines.insert(0, '--- NEW FILE: %s ---\n' % file) - except IOError, e: - lines = ['***** Error reading new file: ', - str(e), '\n***** file: ', file, ' cwd: ', os.getcwd()] - elif newrev is None: - lines = ['--- %s DELETED ---\n' % file] - else: - # File has been changed. - # This /has/ to happen in the background, otherwise we'll run into CVS - # lock contention. What a crock. - if contextlines > 0: - difftype = "-C " + str(contextlines) - else: - difftype = "-u" - diffcmd = "/usr/bin/cvs -f diff -kk %s --minimal -r %s -r %s %s" \ - % (difftype, oldrev, newrev, filestr) - fp = os.popen(diffcmd) - lines = fp.readlines() - # ignore the error code, it always seems to be 1 :( - fp.close() - if len(lines) > DIFF_TRUNCATE_IF_LARGER: - removedlines = len(lines) - DIFF_HEAD_LINES - DIFF_TAIL_LINES - del lines[DIFF_HEAD_LINES:-DIFF_TAIL_LINES] - lines.insert(DIFF_HEAD_LINES, - '[...%d lines suppressed...]\n' % removedlines) - return string.join(lines, '') - - - -rfc822_specials_re = re.compile(r'[\(\)\<\>\@\,\;\:\\\"\.\[\]]') - -def quotename(name): - if name and rfc822_specials_re.search(name): - return '"%s"' % string.replace(name, '"', '\\"') - else: - return name - - - -def blast_mail(subject, people, entries, contextlines, fromhost, replyto): - # cannot wait for child process or that will cause parent to retain cvs - # lock for too long. Urg! - if not os.fork(): - # in the child - # give up the lock you cvs thang! - time.sleep(2) - # Create the smtp connection to the localhost - conn = smtplib.SMTP() - conn.connect(MAILHOST, MAILPORT) - user = pwd.getpwuid(os.getuid())[0] - name = string.split(pwd.getpwuid(os.getuid())[4], ',')[0] - domain = fromhost or getfqdn() - address = '%s@%s' % (user, domain) - s = StringIO() - sys.stdout = s - datestamp = time.strftime('%a, %d %b %Y %H:%M:%S +0000', - time.gmtime(time.time())) - try: - vars = {'address' : address, - 'name' : quotename(name), - 'people' : string.join(people, COMMASPACE), - 'subject' : subject, - 'version' : __version__, - 'date' : datestamp, - } - print '''\ -From: %(name)s <%(address)s> -To: %(people)s''' % vars - if replyto: - print 'Reply-To: %s' % replyto - print '''\ -Subject: %(subject)s -Date: %(date)s -X-Mailer: Python syncmail %(version)s -''' % vars - s.write(sys.stdin.read()) - # append the diffs if available - print - for entry in entries: - print calculate_diff(entry, contextlines) - finally: - sys.stdout = sys.__stdout__ - resp = conn.sendmail(address, people, s.getvalue()) - conn.close() - os._exit(0) - - - -class CVSEntry: - def __init__(self, name, revision, timestamp, conflict, options, tagdate): - self.name = name - self.revision = revision - self.timestamp = timestamp - self.conflict = conflict - self.options = options - self.tagdate = tagdate - -def get_entry(prefix, mapping, line, filename): - line = string.strip(line) - parts = string.split(line, "/") - _, name, revision, timestamp, options, tagdate = parts - key = namekey(prefix, name) - try: - entry = mapping[key] - except KeyError: - if revision == "0": - revision = None - if string.find(timestamp, "+") != -1: - timestamp, conflict = tuple(string.split(timestamp, "+")) - else: - conflict = None - entry = CVSEntry(key, revision, timestamp, conflict, - options, tagdate) - mapping[key] = entry - return entry - -def namekey(prefix, name): - if prefix: - return os.path.join(prefix, name) - else: - return name - -def load_change_info(prefix=None): - if prefix is not None: - entries_fn = os.path.join(prefix, "CVS", "Entries") - else: - entries_fn = os.path.join("CVS", "Entries") - entries_log_fn = entries_fn + ".Log" - mapping = {} - f = open(entries_fn) - while 1: - line = f.readline() - if not line: - break -## if string.strip(line) == "D": -## continue - # we could recurse down subdirs, except the Entries.Log files - # we need haven't been written to the subdirs yet, so it - # doesn't do us any good -## if line[0] == "D": -## name = string.split(line, "/")[1] -## dirname = namekey(prefix, name) -## if os.path.isdir(dirname): -## m = load_change_info(dirname) -## mapping.update(m) - if line[0] == "/": - # normal file - get_entry(prefix, mapping, line, entries_fn) - # else: bogus Entries line - f.close() - if os.path.isfile(entries_log_fn): - f = open(entries_log_fn) - while 1: - line = f.readline() - if not line: - break - if line[1:2] != ' ': - # really old version of CVS - break - entry = get_entry(prefix, mapping, line[2:], entries_log_fn) - parts = string.split(line, "/")[1:] - if line[0] == "A": - # adding a file - entry.new_revision = parts[1] - elif line[0] == "R": - # removing a file - entry.new_revision = None - f.close() - for entry in mapping.values(): - if not hasattr(entry, "new_revision"): - print 'confused about file', entry.name, '-- ignoring' - del mapping[entry.name] - return mapping - -def load_branch_name(): - tag_fn = os.path.join("CVS", "Tag") - if os.path.isfile(tag_fn): - f = open(tag_fn) - line = string.strip(f.readline()) - f.close() - if line[:1] == "T": - return line[1:] - return None - -# scan args for options -def main(): - # XXX Should really move all the options to an object, just to - # avoid threading so many positional args through everything. - try: - opts, args = getopt.getopt( - sys.argv[1:], 'hC:cuS:R:qf:m:', - ['fromhost=', 'context=', 'cvsroot=', 'mailhost=', - 'subject-prefix=', 'reply-to=', - 'help', 'quiet']) - except getopt.error, msg: - usage(1, msg) - - # parse the options - contextlines = 2 - verbose = 1 - subject_prefix = "" - replyto = None - fromhost = None - for opt, arg in opts: - if opt in ('-h', '--help'): - usage(0) - elif opt == '--cvsroot': - os.environ['CVSROOT'] = arg - elif opt in ('-C', '--context'): - contextlines = int(arg) - elif opt == '-c': - if contextlines <= 0: - contextlines = 2 - elif opt == '-u': - contextlines = 0 - elif opt in ('-S', '--subject-prefix'): - subject_prefix = arg - elif opt in ('-R', '--reply-to'): - replyto = arg - elif opt in ('-q', '--quiet'): - verbose = 0 - elif opt in ('-f', '--fromhost'): - fromhost = arg - elif opt in ('-m', '--mailhost'): - global MAILHOST - MAILHOST = arg - - # What follows is the specification containing the files that were - # modified. The argument actually must be split, with the first component - # containing the directory the checkin is being made in, relative to - # $CVSROOT, followed by the list of files that are changing. - if not args: - usage(1, 'No CVS module specified') - changes = load_change_info() - branch = load_branch_name() - subject = subject_prefix + args[0] - specs = string.split(args[0]) - del args[0] - - # The remaining args should be the email addresses - if not args: - usage(1, 'No recipients specified') - - # Now do the mail command - people = args - - if specs[-3:] == ['-', 'Imported', 'sources']: - print 'Not sending email for imported sources.' - return - - if verbose: -## print 'Python version', sys.version -## os.system("type python1.6; type python2;" -## " type python2.0; type python2.1; type python2.2;" -## " type rcsdiff; type rlog") - print 'Mailing %s...' % string.join(people, COMMASPACE) - print 'Generating notification message...' - blast_mail(subject, people, changes.values(), - contextlines, fromhost, replyto) - if verbose: - print 'Generating notification message... done.' - - - -if __name__ == '__main__': - main() - sys.exit(0) DELETED .old_mttroot_cvsroot/taginfo Index: .old_mttroot_cvsroot/taginfo ================================================================== --- .old_mttroot_cvsroot/taginfo +++ .old_mttroot_cvsroot/taginfo @@ -1,20 +0,0 @@ -# The "taginfo" file is used to control pre-tag checks. -# The filter on the right is invoked with the following arguments: -# -# $1 -- tagname -# $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d -# $3 -- repository -# $4-> file revision [file revision ...] -# -# A non-zero exit of the filter program will cause the tag to be aborted. -# -# The first entry on a line is a regular expression which is tested -# against the directory that the change is being committed to, relative -# to the $CVSROOT. For the first match that is found, then the remainder -# of the line is the name of the filter to run. -# -# If the repository name does not match any of the regular expressions in this -# file, the "DEFAULT" line is used, if it is specified. -# -# If the name "ALL" appears as a regular expression it is always used -# in addition to the first matching regex or "DEFAULT". DELETED .old_mttroot_cvsroot/verifymsg Index: .old_mttroot_cvsroot/verifymsg ================================================================== --- .old_mttroot_cvsroot/verifymsg +++ .old_mttroot_cvsroot/verifymsg @@ -1,21 +0,0 @@ -# The "verifymsg" file is used to allow verification of logging -# information. It works best when a template (as specified in the -# rcsinfo file) is provided for the logging procedure. Given a -# template with locations for, a bug-id number, a list of people who -# reviewed the code before it can be checked in, and an external -# process to catalog the differences that were code reviewed, the -# following test can be applied to the code: -# -# Making sure that the entered bug-id number is correct. -# Validating that the code that was reviewed is indeed the code being -# checked in (using the bug-id number or a seperate review -# number to identify this particular code set.). -# -# If any of the above test failed, then the commit would be aborted. -# -# Actions such as mailing a copy of the report to each reviewer are -# better handled by an entry in the loginfo file. -# -# One thing that should be noted is the the ALL keyword is not -# supported. There can be only one entry that matches a given -# repository.