HEX
Server: Apache
System: Linux SH-FR-PM-y8qo 6.6.80-paas #1 SMP PREEMPT_DYNAMIC Thu Sep 25 11:18:23 UTC 2025 x86_64
User: hosting-user (5000)
PHP: 8.3.28
Disabled: NONE
Upload Files
File: //usr/sbin/git-start
#!/usr/bin/env python3

import sys
import os
import re
import shlex
import subprocess
from os import path

_PATH_PREFIX = '/srv/data/lamp0'

class FatalError(Exception):
    """Fatal error exception"""

    _message = 'unknown error'

    def __init__(self, message_=None):
        super(FatalError, self).__init__(message_ or self._message)

class ArgumentError(FatalError):
    """Argument error exception"""

    _message = 'bad argument'

class RepositoryNotFoundError(FatalError):
    """Repository not found error exception"""

    _message = 'repository not found'

class Vhost(object):
    _VHOST_ROOT = path.join(_PATH_PREFIX, 'web/vhosts')

    def __init__(self, name):
        self._name = name
        self._path = path.join(Vhost._VHOST_ROOT, self._name)

    def exists(self):
        return path.exists(self._path)

    def is_name_valid(self):
        """checks hostname pattern without final dot"""
        if len(self._name) > 255:
            return False
        allowed = re.compile(r'(?!-)[a-z\d\-]{1,63}(?<!-)\Z')
        return all(allowed.match(x) for x in self._name.split('.'))

    @property
    def name(self):
        return self._name

class GitRepository(object):
    _GIT_REPO_ROOT = path.join(_PATH_PREFIX, 'vcs/git')

    def __init__(self, name):
        self._name = name.strip('/')
        if not self._name.endswith('.git'):
            raise ArgumentError
        self._vhost = Vhost(self._name[:-4])
        if not self._vhost.is_name_valid():
            raise ArgumentError
        self._path = path.join(self._GIT_REPO_ROOT, self._name)

    def init(self):
        if path.exists(self._path):
            return
        if not self._vhost.exists():
            raise RepositoryNotFoundError
        self._init()

    @property
    def path(self):
        return self._path

    def _init(self):
        commands = [
            [ # git init
                '/usr/bin/git',
                'init',
                '-q',
                '--shared=group',
                '--bare',
                self._path
            ],
            [ # allow using the force
                '/usr/bin/git',
                '-C',
                self._path,
                'config',
                'receive.denyNonFastForwards',
                'false'
            ],
        ]
        try:
            ret = 0
            for command in commands:
                ret += subprocess.call(command, close_fds=True)
        except OSError as err:
            errno, strerror = err.args
            raise FatalError('%s: %s (%d)' % (command, strerror, errno))
        else:
            if ret:
                sys.exit(ret % 256 or 1)  # Ensure we do not exit with 256
        self._write_gitweb_file('description', '%s project' % (self._vhost.name))
        self._write_gitweb_file('cloneurl', self._name)

    def _write_gitweb_file(self, file_, content):
        filename = path.join(self._path, file_)
        with open(filename, 'w') as f:
            f.write(content)
            f.write('\n')

class GitCommand(object):
    def __init__(self):
        if len(sys.argv) != 3 or sys.argv[1] != '-c':
            raise ArgumentError
        args = shlex.split(sys.argv[2])
        if len(args) < 2:
            raise ArgumentError
        self._cmd = args[0]
        self._repo = GitRepository(args[1])
        self._opt_args = args[2:]

    def execute(self):
        os.environ['HOME'] = '/srv/admin/lamp0/vcs/git'
        args = ['/usr/bin/git-shell', '-c', self._git_shell_command()]
        try:
            os.execvp(args[0], args)
        except OSError as err:
            errno, strerror = err.args
            raise FatalError('%s: %s (%d)' % (args[0], strerror, errno))

    @property
    def repository(self):
        return self._repo

    def _git_shell_command(self):
        args = [self._repo.path]
        args.extend(self._opt_args)
        return '%s %s' % (self._cmd,
                          ' '.join("'%s'" % (arg) for arg in args))

if __name__ == '__main__':
    try:
        cmd = GitCommand()
        cmd.repository.init()
        cmd.execute()
    except FatalError as message:
        sys.exit('fatal: %s' % (message))