--- /dev/null
+ref: refs/heads/master
--- /dev/null
+[core]
+ repositoryformatversion = 0
+ filemode = true
+ bare = true
--- /dev/null
+Unnamed repository; edit this file 'description' to name the repository.
--- /dev/null
+#!/bin/sh
+#
+# An example hook script to check the commit log message taken by
+# applypatch from an e-mail message.
+#
+# The hook should exit with non-zero status after issuing an
+# appropriate message if it wants to stop the commit. The hook is
+# allowed to edit the commit message file.
+#
+# To enable this hook, rename this file to "applypatch-msg".
+
+. git-sh-setup
+test -x "$GIT_DIR/hooks/commit-msg" &&
+ exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"}
+:
--- /dev/null
+#!/bin/sh
+#
+# An example hook script to check the commit log message.
+# Called by "git commit" with one argument, the name of the file
+# that has the commit message. The hook should exit with non-zero
+# status after issuing an appropriate message if it wants to stop the
+# commit. The hook is allowed to edit the commit message file.
+#
+# To enable this hook, rename this file to "commit-msg".
+
+# Uncomment the below to add a Signed-off-by line to the message.
+# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
+# hook is more suited to it.
+#
+# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
+# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
+
+# This example catches duplicate Signed-off-by lines.
+
+test "" = "$(grep '^Signed-off-by: ' "$1" |
+ sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || {
+ echo >&2 Duplicate Signed-off-by lines.
+ exit 1
+}
--- /dev/null
+#!/bin/sh
+#
+# An example hook script to prepare a packed repository for use over
+# dumb transports.
+#
+# To enable this hook, rename this file to "post-update".
+
+exec git update-server-info
--- /dev/null
+#!/bin/sh
+#
+# An example hook script to verify what is about to be committed
+# by applypatch from an e-mail message.
+#
+# The hook should exit with non-zero status after issuing an
+# appropriate message if it wants to stop the commit.
+#
+# To enable this hook, rename this file to "pre-applypatch".
+
+. git-sh-setup
+test -x "$GIT_DIR/hooks/pre-commit" &&
+ exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"}
+:
--- /dev/null
+#!/bin/sh
+#
+# An example hook script to verify what is about to be committed.
+# Called by "git commit" with no arguments. The hook should
+# exit with non-zero status after issuing an appropriate message if
+# it wants to stop the commit.
+#
+# To enable this hook, rename this file to "pre-commit".
+
+if git rev-parse --verify HEAD >/dev/null 2>&1
+then
+ against=HEAD
+else
+ # Initial commit: diff against an empty tree object
+ against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
+fi
+
+# If you want to allow non-ascii filenames set this variable to true.
+allownonascii=$(git config hooks.allownonascii)
+
+# Redirect output to stderr.
+exec 1>&2
+
+# Cross platform projects tend to avoid non-ascii filenames; prevent
+# them from being added to the repository. We exploit the fact that the
+# printable range starts at the space character and ends with tilde.
+if [ "$allownonascii" != "true" ] &&
+ # Note that the use of brackets around a tr range is ok here, (it's
+ # even required, for portability to Solaris 10's /usr/bin/tr), since
+ # the square bracket bytes happen to fall in the designated range.
+ test $(git diff --cached --name-only --diff-filter=A -z $against |
+ LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
+then
+ echo "Error: Attempt to add a non-ascii file name."
+ echo
+ echo "This can cause problems if you want to work"
+ echo "with people on other platforms."
+ echo
+ echo "To be portable it is advisable to rename the file ..."
+ echo
+ echo "If you know what you are doing you can disable this"
+ echo "check using:"
+ echo
+ echo " git config hooks.allownonascii true"
+ echo
+ exit 1
+fi
+
+# If there are whitespace errors, print the offending file names and fail.
+exec git diff-index --check --cached $against --
--- /dev/null
+#!/bin/sh
+#
+# Copyright (c) 2006, 2008 Junio C Hamano
+#
+# The "pre-rebase" hook is run just before "git rebase" starts doing
+# its job, and can prevent the command from running by exiting with
+# non-zero status.
+#
+# The hook is called with the following parameters:
+#
+# $1 -- the upstream the series was forked from.
+# $2 -- the branch being rebased (or empty when rebasing the current branch).
+#
+# This sample shows how to prevent topic branches that are already
+# merged to 'next' branch from getting rebased, because allowing it
+# would result in rebasing already published history.
+
+publish=next
+basebranch="$1"
+if test "$#" = 2
+then
+ topic="refs/heads/$2"
+else
+ topic=`git symbolic-ref HEAD` ||
+ exit 0 ;# we do not interrupt rebasing detached HEAD
+fi
+
+case "$topic" in
+refs/heads/??/*)
+ ;;
+*)
+ exit 0 ;# we do not interrupt others.
+ ;;
+esac
+
+# Now we are dealing with a topic branch being rebased
+# on top of master. Is it OK to rebase it?
+
+# Does the topic really exist?
+git show-ref -q "$topic" || {
+ echo >&2 "No such branch $topic"
+ exit 1
+}
+
+# Is topic fully merged to master?
+not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
+if test -z "$not_in_master"
+then
+ echo >&2 "$topic is fully merged to master; better remove it."
+ exit 1 ;# we could allow it, but there is no point.
+fi
+
+# Is topic ever merged to next? If so you should not be rebasing it.
+only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
+only_next_2=`git rev-list ^master ${publish} | sort`
+if test "$only_next_1" = "$only_next_2"
+then
+ not_in_topic=`git rev-list "^$topic" master`
+ if test -z "$not_in_topic"
+ then
+ echo >&2 "$topic is already up-to-date with master"
+ exit 1 ;# we could allow it, but there is no point.
+ else
+ exit 0
+ fi
+else
+ not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
+ /usr/bin/perl -e '
+ my $topic = $ARGV[0];
+ my $msg = "* $topic has commits already merged to public branch:\n";
+ my (%not_in_next) = map {
+ /^([0-9a-f]+) /;
+ ($1 => 1);
+ } split(/\n/, $ARGV[1]);
+ for my $elem (map {
+ /^([0-9a-f]+) (.*)$/;
+ [$1 => $2];
+ } split(/\n/, $ARGV[2])) {
+ if (!exists $not_in_next{$elem->[0]}) {
+ if ($msg) {
+ print STDERR $msg;
+ undef $msg;
+ }
+ print STDERR " $elem->[1]\n";
+ }
+ }
+ ' "$topic" "$not_in_next" "$not_in_master"
+ exit 1
+fi
+
+<<\DOC_END
+
+This sample hook safeguards topic branches that have been
+published from being rewound.
+
+The workflow assumed here is:
+
+ * Once a topic branch forks from "master", "master" is never
+ merged into it again (either directly or indirectly).
+
+ * Once a topic branch is fully cooked and merged into "master",
+ it is deleted. If you need to build on top of it to correct
+ earlier mistakes, a new topic branch is created by forking at
+ the tip of the "master". This is not strictly necessary, but
+ it makes it easier to keep your history simple.
+
+ * Whenever you need to test or publish your changes to topic
+ branches, merge them into "next" branch.
+
+The script, being an example, hardcodes the publish branch name
+to be "next", but it is trivial to make it configurable via
+$GIT_DIR/config mechanism.
+
+With this workflow, you would want to know:
+
+(1) ... if a topic branch has ever been merged to "next". Young
+ topic branches can have stupid mistakes you would rather
+ clean up before publishing, and things that have not been
+ merged into other branches can be easily rebased without
+ affecting other people. But once it is published, you would
+ not want to rewind it.
+
+(2) ... if a topic branch has been fully merged to "master".
+ Then you can delete it. More importantly, you should not
+ build on top of it -- other people may already want to
+ change things related to the topic as patches against your
+ "master", so if you need further changes, it is better to
+ fork the topic (perhaps with the same name) afresh from the
+ tip of "master".
+
+Let's look at this example:
+
+ o---o---o---o---o---o---o---o---o---o "next"
+ / / / /
+ / a---a---b A / /
+ / / / /
+ / / c---c---c---c B /
+ / / / \ /
+ / / / b---b C \ /
+ / / / / \ /
+ ---o---o---o---o---o---o---o---o---o---o---o "master"
+
+
+A, B and C are topic branches.
+
+ * A has one fix since it was merged up to "next".
+
+ * B has finished. It has been fully merged up to "master" and "next",
+ and is ready to be deleted.
+
+ * C has not merged to "next" at all.
+
+We would want to allow C to be rebased, refuse A, and encourage
+B to be deleted.
+
+To compute (1):
+
+ git rev-list ^master ^topic next
+ git rev-list ^master next
+
+ if these match, topic has not merged in next at all.
+
+To compute (2):
+
+ git rev-list master..topic
+
+ if this is empty, it is fully merged to "master".
+
+DOC_END
--- /dev/null
+#!/bin/sh
+#
+# An example hook script to prepare the commit log message.
+# Called by "git commit" with the name of the file that has the
+# commit message, followed by the description of the commit
+# message's source. The hook's purpose is to edit the commit
+# message file. If the hook fails with a non-zero status,
+# the commit is aborted.
+#
+# To enable this hook, rename this file to "prepare-commit-msg".
+
+# This hook includes three examples. The first comments out the
+# "Conflicts:" part of a merge commit.
+#
+# The second includes the output of "git diff --name-status -r"
+# into the message, just before the "git status" output. It is
+# commented because it doesn't cope with --amend or with squashed
+# commits.
+#
+# The third example adds a Signed-off-by line to the message, that can
+# still be edited. This is rarely a good idea.
+
+case "$2,$3" in
+ merge,)
+ /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;
+
+# ,|template,)
+# /usr/bin/perl -i.bak -pe '
+# print "\n" . `git diff --cached --name-status -r`
+# if /^#/ && $first++ == 0' "$1" ;;
+
+ *) ;;
+esac
+
+# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
+# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
--- /dev/null
+#!/bin/sh
+#
+# An example hook script to blocks unannotated tags from entering.
+# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
+#
+# To enable this hook, rename this file to "update".
+#
+# Config
+# ------
+# hooks.allowunannotated
+# This boolean sets whether unannotated tags will be allowed into the
+# repository. By default they won't be.
+# hooks.allowdeletetag
+# This boolean sets whether deleting tags will be allowed in the
+# repository. By default they won't be.
+# hooks.allowmodifytag
+# This boolean sets whether a tag may be modified after creation. By default
+# it won't be.
+# hooks.allowdeletebranch
+# This boolean sets whether deleting branches will be allowed in the
+# repository. By default they won't be.
+# hooks.denycreatebranch
+# This boolean sets whether remotely creating branches will be denied
+# in the repository. By default this is allowed.
+#
+
+# --- Command line
+refname="$1"
+oldrev="$2"
+newrev="$3"
+
+# --- Safety check
+if [ -z "$GIT_DIR" ]; then
+ echo "Don't run this script from the command line." >&2
+ echo " (if you want, you could supply GIT_DIR then run" >&2
+ echo " $0 <ref> <oldrev> <newrev>)" >&2
+ exit 1
+fi
+
+if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
+ echo "Usage: $0 <ref> <oldrev> <newrev>" >&2
+ exit 1
+fi
+
+# --- Config
+allowunannotated=$(git config --bool hooks.allowunannotated)
+allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
+denycreatebranch=$(git config --bool hooks.denycreatebranch)
+allowdeletetag=$(git config --bool hooks.allowdeletetag)
+allowmodifytag=$(git config --bool hooks.allowmodifytag)
+
+# check for no description
+projectdesc=$(sed -e '1q' "$GIT_DIR/description")
+case "$projectdesc" in
+"Unnamed repository"* | "")
+ echo "*** Project description file hasn't been set" >&2
+ exit 1
+ ;;
+esac
+
+# --- Check types
+# if $newrev is 0000...0000, it's a commit to delete a ref.
+zero="0000000000000000000000000000000000000000"
+if [ "$newrev" = "$zero" ]; then
+ newrev_type=delete
+else
+ newrev_type=$(git cat-file -t $newrev)
+fi
+
+case "$refname","$newrev_type" in
+ refs/tags/*,commit)
+ # un-annotated tag
+ short_refname=${refname##refs/tags/}
+ if [ "$allowunannotated" != "true" ]; then
+ echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
+ echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
+ exit 1
+ fi
+ ;;
+ refs/tags/*,delete)
+ # delete tag
+ if [ "$allowdeletetag" != "true" ]; then
+ echo "*** Deleting a tag is not allowed in this repository" >&2
+ exit 1
+ fi
+ ;;
+ refs/tags/*,tag)
+ # annotated tag
+ if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
+ then
+ echo "*** Tag '$refname' already exists." >&2
+ echo "*** Modifying a tag is not allowed in this repository." >&2
+ exit 1
+ fi
+ ;;
+ refs/heads/*,commit)
+ # branch
+ if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
+ echo "*** Creating a branch is not allowed in this repository" >&2
+ exit 1
+ fi
+ ;;
+ refs/heads/*,delete)
+ # delete branch
+ if [ "$allowdeletebranch" != "true" ]; then
+ echo "*** Deleting a branch is not allowed in this repository" >&2
+ exit 1
+ fi
+ ;;
+ refs/remotes/*,commit)
+ # tracking branch
+ ;;
+ refs/remotes/*,delete)
+ # delete tracking branch
+ if [ "$allowdeletebranch" != "true" ]; then
+ echo "*** Deleting a tracking branch is not allowed in this repository" >&2
+ exit 1
+ fi
+ ;;
+ *)
+ # Anything else (is there anything else?)
+ echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
+ exit 1
+ ;;
+esac
+
+# --- Finished
+exit 0
--- /dev/null
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
--- /dev/null
+756c1add57e06a607772ab479a849314bec41fe9 refs/heads/master
--- /dev/null
+x\ 1M
+Â0\10F]ç\14³\17$LÛ\ 4D\»\12oL&¶b\7f)âí-@¾í{¼çq\1c*\18C»ZD´ï²sä"ÅÖ:××>GbFcM66QdçQ-¡ÈT2Å) Û\b\r§®i¬hl%IãºMM
+kíç\ 2×°>á\ 278r^\1eåÀ|\ 2´Ôykm°Gµâß«*ÿòû0Ý%AÞ\12¼!\rE¸Îå\ 3¯ZV®k\11õ\ 5¤ÈD
\ No newline at end of file
--- /dev/null
+x\ 1ÍÍ
+@\18
áÖ^Å\17\18¤Sí#4&\b,PkÕ\1f:~ÙÐ03i5Atïaå¾íá=<P\19FV¦äW¤²à\12AIë7\ 4i
@ª\11¡X*\b2Áu
®Qå¹Ò)CR»&Æ\18\ 2Í'¾ =9>¶>iÏ\ 1\176a?Ø5ÅTÉ\1c:ÏFk¬\ e³yHþ¾ í\1eÿhò¦ùJ]ÏéÙðñjnr\19ÛÃÚ\12¿67+ÍJÒ
\ No newline at end of file
--- /dev/null
+P pack-d07d7771496ba63a1ed21b17101b417ae41c7c9a.pack
+
--- /dev/null
+756c1add57e06a607772ab479a849314bec41fe9
--- /dev/null
+<?php
+
+require_once("gwvpmini_web.php");
+require_once("gwvpmini_auth.php");
+require_once("gwvpmini_db.php");
+require_once("gwvpmini_setup.php");
+require_once("gwvpmini_gitrepo.php");
+require_once("gwvpmini_gitbackend.php");
+if(gwvpmini_isLoggedIn()) if(gwvpmini_isUserAdmin()) {
+ require_once("gwvpmini_admin.php");
+}
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+
+if(gwvpmini_isLoggedIn()) if(gwvpmini_isUserAdmin()) {
+ $MENU_ITEMS["20repos"]["text"] = "Administration";\r
+ $MENU_ITEMS["20repos"]["link"] = "$BASE_URL/admin";
+ $CALL_ME_FUNCTIONS["admin"] = "gwvpmini_AdminCallMe";
+}
+
+function gwvpmini_AdminCallMe()\r
+{\r
+\r
+ error_log("in admin callme");\r
+ if(isset($_REQUEST["q"])) {\r
+ $query = $_REQUEST["q"];\r
+ $qspl = explode("/", $query);\r
+ if(isset($qspl[0])) {\r
+ if($qspl[0] == "admin") {\r
+ if(isset($qspl[1])) {\r
+ if($qspl[1] == "create") {\r
+ return "gwvpmini_RepoCreate";\r
+ }\r
+ } else {\r
+ error_log("i got here, where next?");\r
+ return "gwvpmini_AdminMainPage";\r
+ }\r
+ } else return false;\r
+ }\r
+ else return false;\r
+ }\r
+\r
+ return false;\r
+}
+
+function gwvpmini_AdminMainPage()
+{
+ gwvpmini_goMainPage("gwvpmini_AdminMainPageBody");
+}
+
+function gwvpmini_AdminMainPageBody()
+{
+ global $BASE_URL;
+
+ echo "<h2>Users</h2>";
+ echo "<table border=\"1\">";
+ echo "<tr><th>Username</th><th>Email Address</th><th>Full Name</th><th>Description</th><th>Control</th></tr>";
+ foreach(gwvpmini_GetUsers() as $key => $val) {
+ $id = $key;
+ $un = $val["username"];
+ $em = $val["email"];
+ $fn = $val["fullname"];
+ $ds = $val["desc"];
+ echo "<tr><td>$un</td><td>$em</td><td>$fn</td><td>$ds</td><td><a href=\"$BASE_URL/admin/removeuser&id=$id\">Remove</a> <a href=\"$BASE_URL/admin/disableuser&id=$id\">Disable</a></td></tr>";
+ }
+ echo "</table>";
+}\r
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+
+session_start();
+
+$CALL_ME_FUNCTIONS["auth"] = "gwvpmini_AuthCallMe";\r
+
+function gwvpmini_AuthCallMe()\r
+{\r
+\r
+ error_log("in repoadmin callme");\r
+ if(isset($_REQUEST["q"])) {\r
+ $query = $_REQUEST["q"];\r
+ $qspl = explode("/", $query);\r
+ if(isset($qspl[0])) {\r
+ if($qspl[0] == "login") {
+ return "gwvpmini_AuthHandleLogin";
+ } else if($qspl[0] == "logout") {
+ return "gwvpmini_AuthHandleLogout";
+ } else return false;\r
+ }\r
+ else return false;\r
+ }\r
+\r
+ return false;\r
+}\r
+
+function gwvpmini_AuthHandleLogout()\r
+{\r
+ global $BASE_URL;\r
+\r
+ unset($_SESSION["isloggedin"]);\r
+ unset($_SESSION["username"]);\r
+ unset($_SESSION["fullname"]);\r
+ unset($_SESSION["usertype"]);\r
+ unset($_SESSION["id"]);\r
+ \r
+ gwvpmini_SendMessage("info", "Logged out");\r
+ header("Location: $BASE_URL");\r
+}\r
+
+
+function gwvpmini_AuthHandleLogin()
+{
+ global $BASE_URL;\r
+ \r
+ $user = "";\r
+ $pass = "";\r
+ if(isset($_REQUEST["username"])) $user = $_REQUEST["username"];\r
+ if(isset($_REQUEST["password"])) $pass = $_REQUEST["password"];\r
+ \r
+ if(gwvpmini_authUserPass($user, $pass) === false) {\r
+ gwvpmini_SendMessage("error", "Login Failed");\r
+ header("Location: $BASE_URL");\r
+ } else {\r
+ $details = gwvpmini_getUser($user);\r
+ $_SESSION["isloggedin"] = true;\r
+ $_SESSION["username"] = "$user";\r
+ $_SESSION["fullname"] = $details["fullname"];\r
+ $_SESSION["id"] = $details["id"];\r
+ gwvpmini_SendMessage("info", "Welcome ".$details["fullname"]." you are logged in");\r
+ header("Location: $BASE_URL");\r
+ return true;\r
+ }\r
+ \r
+
+}
+
+function gwvpmini_SingleLineLoginForm()\r
+{\r
+ global $BASE_URL;\r
+\r
+ echo "<form method=\"post\" action=\"$BASE_URL/login\">Username <input type=\"text\" name=\"username\" class=\"login\">";\r
+ echo " Passowrd <input type=\"text\" name=\"password\" class=\"login\"><input type=\"submit\" name=\"login\" value=\"Login\" class=\"loginbutton\">";\r
+ if(gwvpmini_IsRegistrationEnabled()) echo "<a href=\"$BASE_URL/register\">Register</a></form>";\r
+ else echo "</form><br>";\r
+}\r
+
+
+function gwvpmini_IsRegistrationEnabled()
+{
+ return true;
+}
+
+function gwvpmini_isLoggedIn()
+{
+ global $_SESSION;
+
+ if(isset($_SESSION)) {
+ if(isset($_SESSION["username"])) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+function gwvpmini_AskForBasicAuth()\r
+{\r
+ header('WWW-Authenticate: Basic realm="GIT Repo"');\r
+ header('HTTP/1.1 401 Unauthorized');\r
+}\r
+
+
+function gwvpmini_checkBasicAuthLogin()\r
+{\r
+ $user = false;\r
+ $pass = false;\r
+ if(isset($_SERVER["PHP_AUTH_USER"])) {\r
+ $user = $_SERVER["PHP_AUTH_USER"];\r
+ } else return false;\r
+\r
+ if(isset($_SERVER["PHP_AUTH_PW"])) {\r
+ $pass = $_SERVER["PHP_AUTH_PW"];\r
+ } else return false;\r
+\r
+ error_log("passing basic auth for $user, $pass to backend");\r
+ $auth = gwvpmini_authUserPass($user, $pass);\r
+ if($auth !== false) {\r
+ error_log("auth passes");\r
+ } else {\r
+ error_log("auth failes");\r
+ }\r
+\r
+ return $auth;\r
+}\r
+
+
+function gwvpmini_isUserAdmin($id=-1)
+{
+
+
+ if($id == -1) {
+ if(isset($_SESSION)) if(isset($_SESSION["id"])) $id = $_SESSION["id"];
+ }
+
+ if($id == -1) return false;
+
+ $lev = gwvpmini_userLevel($id);
+
+ if($lev == 1) return true;
+
+ return false;
+}
+
+function gwvpmini_authUserPass($user, $pass)
+{
+ $details = gwvpmini_getUser($user);
+ if($details == false) {
+ error_log("no user details for $user");
+ return false;
+ }
+
+ if(sha1($pass)!=$details["password"]) return false;
+
+ return $details["username"];
+}
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+
+
+global $DB_CONNECTION;\r
+$DB_CONNECTION = false;\r
+\r
+\r
+global $db_url, $db_type;\r
+error_log("in include for database, $db_type, $db_name");
+
+
+function gwvpmini_DBExists()
+{
+ global $WEB_ROOT_FS, $BASE_URL, $data_directory, $db_type, $db_name;
+
+ // oh this isnt working. poo.
+ error_log("checking for $db_name, $db_type");
+
+ if($db_type == "sqlite") {
+ if(file_exists($db_name)) {
+ error_log("Exists");
+ return true;
+ }
+ else {
+ error_log("no exists");
+ return false;
+ }
+ }
+}\r
+
+function gwvpmini_getUser($username=null, $email=null, $id=null)\r
+{\r
+ $conn = gwvpmini_ConnectDB();\r
+\r
+ if($username != null) {\r
+ $res = $conn->query("select * from users where user_username='$username'");\r
+ } else if($email != null) {\r
+ $res = $conn->query("select * from users where user_email='$email'");\r
+ } else if($id != null) {\r
+ $res = $conn->query("select * from users where users_id='$id'");\r
+ } else return false;\r
+\r
+ $returns = false;\r
+ foreach($res as $u_res) {\r
+ $returns["id"] = $u_res["user_id"];\r
+ $returns["fullname"] = $u_res["user_full_name"];\r
+ $returns["password"] = $u_res["user_password"];\r
+ $returns["username"] = $u_res["user_username"];\r
+ $returns["email"] = $u_res["user_email"];\r
+ $returns["desc"] = $u_res["user_desc"];\r
+ $returns["status"] = $u_res["user_status"];\r
+ }\r
+\r
+ return $returns;\r
+\r
+}\r
+
+function gwvpmini_ConnectDB()\r
+{\r
+ global $WEB_ROOT_FS, $BASE_URL, $data_directory, $db_type, $db_name, $DB_CONNECTION;\r
+\r
+ // first check if $DB_CONNECTION IS live\r
+ error_log("in connection $db_type, $db_name");\r
+\r
+ if($DB_CONNECTION != false) return $DB_CONNECTION;\r
+\r
+ if($db_type == "sqlite") {\r
+ $db_url = $db_name;\r
+ if(!file_exists($db_name)) {\r
+ error_log("$db_name does not exist - problem");
+ // TODO: NEED A SETUP AGENT!
+ gwvpmini_dbCreateSQLiteStructure($db_name);
+ gwvpmini_setConfigVal("repodir", "$data_directory/repos");\r
+ }\r
+ }\r
+\r
+ // and here we go with pdo.\r
+ error_log("attmpting to open db, $db_type:$db_url");\r
+ try {\r
+ $DB_CONNECTION = new PDO("$db_type:$db_url");\r
+ } catch(PDOException $exep) {\r
+ error_log("execpt on db open");\r
+ return false;\r
+ }\r
+\r
+ return $DB_CONNECTION;\r
+}\r
+
+
+function gwvpmini_dbCreateSQLiteStructure($dbloc)\r
+{\r
+ $usersql = '\r
+ CREATE TABLE "users" (\r
+ "user_id" INTEGER PRIMARY KEY AUTOINCREMENT,\r
+ "user_full_name" TEXT,\r
+ "user_password" TEXT,\r
+ "user_username" TEXT,\r
+ "user_email" TEXT,\r
+ "user_desc" TEXT,
+ "user_level" TEXT,\r
+ "user_status" TEXT\r
+ )';\r
+\r
+ $initialuser_admin = '
+ insert into "users" values ( null, "Administrator", "'.sha1("password").'", "admin", "admin@localhost", "the admin", "1", "0");\r
+ ';\r
+
+ $initialuser_user = '\r
+ insert into "users" values ( null, "User", "'.sha1("password").'", "user", "user@localhost", "the user", "0", "0");\r
+ ';\r
+ \r
+ $reposql = '\r
+ CREATE TABLE "repos" (\r
+ "repos_id" INTEGER PRIMARY KEY AUTOINCREMENT,\r
+ "repos_name" TEXT,\r
+ "repos_description" TEXT,\r
+ "repos_owner" INTEGER\r
+ )';\r
+\r
+ // this looks like null, <repoid>, <read|visible|write>, user:<uid>|group:<gid>|authed|anon\r
+ // where authed = any authenticated user, anon = everyone (logged in, not logged in, etc)\r
+ // read|visible|write = can clone from repo|can see repo exists and see description but not clone from it|can push to repo\r
+ // TODO: is this sufficient? i have to think about it\r
+\r
+ $configsql = '\r
+ CREATE TABLE "config" (\r
+ "config_name" TEXT,\r
+ "config_value" TEXT\r
+ )';\r
+\r
+ try {\r
+ $DB_CONNECTION = new PDO("sqlite:$dbloc");\r
+ } catch(PDOException $exep) {\r
+ error_log("execpt on db open");\r
+ return false;\r
+ }\r
+
+ $DB_CONNECTION->query($usersql);\r
+ $DB_CONNECTION->query($initialuser_admin);
+ $DB_CONNECTION->query($initialuser_user);
+ $DB_CONNECTION->query($reposql);\r
+ $DB_CONNECTION->query($configsql);\r
+}
+
+function gwvpmini_getConfigVal($confname)\r
+{\r
+ /*\r
+ * $configsql = '\r
+ CREATE TABLE "config" (\r
+ "config_name" TEXT,\r
+ "config_value" TEXT\r
+ )';\r
+\r
+ */\r
+\r
+ $conn = gwvpmini_ConnectDB();\r
+\r
+ $sql = "select config_value from config where config_name='$confname'";\r
+\r
+ $res = $conn->query($sql);\r
+\r
+ $return = null;\r
+ foreach($res as $val) {\r
+ $return = $val["config_value"];\r
+ }\r
+\r
+ return $return;\r
+}\r
+\r
+function gwvpmini_eraseConfigVal($confname)\r
+{\r
+ /*\r
+ * $configsql = '\r
+ CREATE TABLE "config" (\r
+ "config_name" TEXT,\r
+ "config_value" TEXT\r
+ )';\r
+\r
+ */\r
+\r
+ $conn = gwvpmini_ConnectDB();\r
+\r
+ $sql = "delete from config where config_name='$confname'";\r
+\r
+ return $conn->query($sql);\r
+}
+
+function gwvpmini_GetRepoId($reponame)
+{
+
+ /*
+ * $reposql = '
+ CREATE TABLE "repos" (
+ "repos_id" INTEGER PRIMARY KEY AUTOINCREMENT,
+ "repos_name" TEXT,
+ "repos_description" TEXT,
+ "repos_owner" INTEGER
+ )';
+
+ */
+
+ $conn = gwvpmini_ConnectDB();
+
+ $sql = "select repos_id from repos where repos_name='$reponame'";
+
+ $res = $conn->query($sql);
+
+ $retval = -1;
+ if(!$res) return -1;
+ foreach($res as $row) {
+ $reval = (int)$row[0];
+ }
+
+ return $retval;
+}
+\r
+\r
+function gwvpmini_setConfigVal($confname, $confval)\r
+{\r
+ /*\r
+ * $configsql = '\r
+ CREATE TABLE "config" (\r
+ "config_name" TEXT,\r
+ "config_value" TEXT\r
+ )';\r
+\r
+ */\r
+ gwvpmini_eraseConfigVal($confname);\r
+\r
+ $conn = gwvpmini_ConnectDB();\r
+\r
+ $sql = "insert into config values('$confname', '$confval')";\r
+\r
+ return $conn->query($sql);\r
+}
+
+function gwvpmini_AddRepo($name, $desc, $ownerid)
+{
+
+ error_log("addrepo in db for $name, $desc, $ownerid");
+ $conn = gwvpmini_ConnectDB();\r
+ \r
+ $sql = "insert into repos values (null, '$name', '$desc', '$ownerid')";\r
+ \r
+ $conn->query($sql);\r
+}
+
+function gwvpmini_GetUserId($username)
+{
+ $conn = gwvpmini_ConnectDB();\r
+
+ $sql = "select user_id from users where user_username='$username'";
+
+ error_log("userid sql $sql");\r
+
+ $res = $conn->query($sql);
+
+ $retval = false;
+ foreach($res as $row) {
+ $retval = $row[0];
+ }
+
+ return $retval;
+}
+
+function gwvpmini_GetOwnedRepos($username)\r
+{
+ /*
+ * CREATE TABLE "repos" (
+ "repos_id" INTEGER PRIMARY KEY AUTOINCREMENT,
+ "repos_name" TEXT,
+ "repos_description" TEXT,
+ "repos_owner" INTEGER
+ )';
+
+ */
+ $conn = gwvpmini_ConnectDB();
+
+ $uid = gwvpmini_GetUserId($username);
+ $sql = "select * from repos where repos_owner='$uid'";
+ error_log("owned repos sql $sql");
+ $res = $conn->query($sql);
+
+ $retval = false;
+ foreach($res as $row) {
+ $id = $row["repos_id"];
+ $retval[$id]["name"] = $row["repos_name"];
+ $retval[$id]["desc"] = $row["repos_description"];
+ error_log(print_r($row, true));
+ }
+
+ error_log(print_r($retval, true));\r
+ return $retval;\r
+}
+
+function gwvpmini_userLevel($id)
+{
+ $conn = gwvpmini_ConnectDB();
+
+ $sql = "select user_level from users where user_id='$id'";
+
+ $res = $conn->query($sql);
+
+ $lev = -1;
+ if(!$res) return -1;
+ foreach($res as $row) {
+ $lev = (int)$row[0];
+ }
+
+ return $lev;
+}
+
+function gwvpmini_GetUsers()
+{
+ $conn = gwvpmini_ConnectDB();
+
+ /*
+ * CREATE TABLE "users" (
+ "user_id" INTEGER PRIMARY KEY AUTOINCREMENT,
+ "user_full_name" TEXT,
+ "user_password" TEXT,
+ "user_username" TEXT,
+ "user_email" TEXT,
+ "user_desc" TEXT,
+ "user_level" TEXT,
+ "user_status" TEXT
+
+ */\r
+ \r
+ $sql = "select * from users";
+
+ $res = $conn->query($sql);
+
+ $retval = false;
+ foreach($res as $row) {
+ $id = $row["user_id"];
+ $retval[$id]["fullname"] = $row["user_full_name"];
+ $retval[$id]["username"] = $row["user_username"];
+ $retval[$id]["email"] = $row["user_email"];
+ $retval[$id]["desc"] = $row["user_desc"];
+ $retval[$id]["level"] = $row["user_level"];
+ $retval[$id]["status"] = $row["user_status"];
+ }
+
+ return $retval;
+}\r
+
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+
+$CALL_ME_FUNCTIONS["gitcontrol"] = "gwvpmini_gitControlCallMe";
+
+//$MENU_ITEMS["20repos"]["text"] = "Repo Admin";
+//$MENU_ITEMS["20repos"]["link"] = "$BASE_URL/admin/repos";
+
+// TODO: we could actually change backend interface such that is
+// will respond to any url's that contain "repo.git" rather then
+// having to be $BASE_URL/git/repo.git
+function gwvpmini_gitControlCallMe()
+{
+ if(isset($_REQUEST["q"])) {
+ $query = $_REQUEST["q"];
+ $qspl = explode("/", $query);
+ if(isset($qspl[0])) {
+ if($qspl[0] == "git") {
+ return "gwvpmini_gitBackendInterface";
+ }
+ }
+ else return false;
+ }
+
+ return false;
+
+}
+
+
+function gwvpmini_gitBackendInterface()
+{
+ // and this is where i re-code the git backend interface from scratch
+ global $BASE_URL;
+
+ $repo_base = gwvpmini_getConfigVal("repodir");
+
+ // TODO: we need to stop passing the repo name around as "repo.git", it needs to be just "repo"
+
+
+ /* bizare git problem that ignores 403's or continues on with a push despite them
+ error_log("FLAP for ".$_SERVER["REQUEST_URI"]);
+ if(isset($_REQUEST)) {
+ $dump = print_r($_REQUEST, true);
+ error_log("FLAP, $dump");
+ }
+ if(isset($_SERVER["PHP_AUTH_USER"])) {
+ error_log("FLAP: donut hole");
+ }*/
+
+
+
+ $repo = "";
+ $repoid = false;
+ $newloc = "/";
+ if(isset($_REQUEST["q"])) {
+ $query = $_REQUEST["q"];
+ $qspl = explode("/", $query);
+ // TODO do this with
+ $repo = preg_replace("/\.git$/", "", $qspl[1]);
+ $repoid = gwvpmini_GetRepoId($repo);
+ for($i=2; $i < count($qspl); $i++) {
+ $newloc .= "/".$qspl[$i];
+ }
+ }
+
+ if($repoid == false) {
+ gwvpmini_fourZeroFour();
+ return;
+ }
+
+ // we do an update server cause its weird and i cant figure out when it actually needs to happen
+ chdir("$repo_base/$repo.git");
+ exec("/usr/bin/git update-server-info");
+
+
+ // so now we have the repo
+ // next we determine if this is a read or a write
+ $write = false;
+ if(isset($_REQUEST["service"])) {
+ if($_REQUEST["service"] == "git-receive-pack") {
+ error_log("got write as receivepack in post");
+ $write = true;
+ }
+ }
+ if($_SERVER["REQUEST_METHOD"] == "POST") {
+ $write = true;
+ }
+ // THIS MAY CAUSE ISSUES LATER ON but we do it cause the git client ignores our 403 when it uses git-receive-pack after an auth
+ // no, this isnt a solution cause auth'd read attempts will come up as writes...
+ //if(isset($_SERVER["PHP_AUTH_USER"])) {
+ //$write = true;
+ //}
+
+ $perms = 5;
+
+ // if its a write, we push for authentication
+ if($write) {
+ error_log("is write attempt, ask for login");
+ $person = gwvpmini_checkBasicAuthLogin();
+ if($person == false) {
+ gwvpmini_AskForBasicAuth();
+ return;
+ } else {
+ error_log("checking perms for $person against $repoid for repo $repo");
+ // here we pass to the git backend
+ error_log("perms are $perms and im allowed");
+ gwvpmini_callGitBackend($person["username"], $repo);
+ }
+ return;
+ }
+
+
+ // if they're less then read, we need to then check the user auth permissions
+ if($perms < 2) {
+ // we ask for auth
+ $person = gwvpmini_checkBasicAuthLogin();
+ if($person == false) {
+ gwvpmini_AskForBasicAuth();
+ return;
+ } else {
+ }
+ }
+
+ // if we made it this far, we a read and we have permissions to do so, just search the file from the repo
+ if(file_exists("$repo_base/$repo.git/$newloc")) {
+ error_log("would ask $repo for $repo.git/$newloc from $repo_base/$repo.git/$newloc");
+ $fh = fopen("$repo_base/$repo.git/$newloc", "rb");
+
+ error_log("pushing file");
+ while(!feof($fh)) {
+ echo fread($fh, 8192);
+ }
+ } else {
+ //echo "would ask $repo,$actual_repo_name for $repo/$newloc from $repo_base/$repo/$newloc, NE";
+ gwvpmini_fourZeroFour();
+ return;
+ }
+
+}
+
+
+function gwvpmini_gitBackendInterface_old()
+{
+ global $BASE_URL;
+
+ $repo_base = gwvpmini_getConfigVal("repodir");
+
+ $repo = "";
+ $newloc = "/";
+ if(isset($_REQUEST["q"])) {
+ $query = $_REQUEST["q"];
+ $qspl = explode("/", $query);
+ $repo = $qspl[1];
+ for($i=2; $i < count($qspl); $i++) {
+ $newloc .= "/".$qspl[$i];
+ }
+ }
+
+ $actual_repo_name = preg_replace("/\.git$/", "", $repo);
+
+ $user = gwvpmini_checkBasicAuthLogin();
+
+ if(!$user) {
+ error_log("User is set to false, so its anonymouse");
+ } else {
+ error_log("user is $user");
+ }
+
+ // must remember that $user of false is anonymous when we code gwvpmini_repoPerm'sCheck()
+ if(!gwvpmini_repoPermissionCheck($actual_repo_name, $user)) {
+ error_log("perms check fails - start auth");
+ if(isset($_SERVER["PHP_AUTH_USER"])) {
+ error_log("have auth - push 403");
+ gwvpmini_fourZeroThree();
+ } else {
+ error_log("push auth");
+ gwvpmini_AskForBasicAuth();
+ return;
+ }
+ }
+
+ // we need to quite a bit of parsing in here. The "repo" will always be /git/repo.git
+ // but if we get here from a browser, we need to forward back to a normal repo viewer
+ // the only way i can think of doing this is to check the useragent for the word "git"
+
+ /*
+ * here we need to
+ * 1) figure out the repo its acessing
+ * 2) figure out the perms on the repo
+ * 3) determine if its a pull or a push
+ * - if its a pull, we just serve straight from the fs
+ * - if its a push, we go thru git-http-backend
+ * 4) if it requiers auth, we push to auth
+ *
+ */
+ $agent = "git-unknown";
+ $isgitagent = false;
+
+ // tested the user agent bit with jgit from eclipse and normal git... seems to work
+ if(isset($_SERVER["HTTP_USER_AGENT"])) {
+ $agent = $_SERVER["HTTP_USER_AGENT"];
+ error_log("in git backend with user agent $agent");
+ if(stristr($agent, "git")!==false) {
+ $isgitagent = true;
+ }
+ }
+
+
+
+ /* dont need this code right now
+ if($isgitagent) echo "GIT: i am a git backened interface for a repo $repo, agent $agent";
+ else echo "NOT GIT: i am a git backened interface for a repo $repo, agent $agent";
+ */
+
+ // now we need to rebuild the actual request or do we?
+ //$basegit = "$BASE_URL/git/something.git";
+ //$newloc = preg_replace("/^$basegit/", "", $_SERVER["REQUEST_URI"]);
+ chdir("$repo_base/$repo");
+ exec("/usr/bin/git update-server-info");
+
+ if($_SERVER["REQUEST_METHOD"] == "POST") {
+ gwvpmini_AskForBasicAuth();
+ gwvpmini_callGitBackend($repo);
+ return;
+ }
+
+ if(isset($_REQUEST["service"])) {
+ if($_REQUEST["service"] == "git-receive-pack") {
+ // we are a write call - we need auth and we're going to the backend proper
+ gwvpmini_AskForBasicAuth();
+ gwvpmini_callGitBackend($repo);
+ return;
+ }
+ }
+
+
+ if(file_exists("$repo_base/$repo/$newloc")) {
+ error_log("would ask $repo,$actual_repo_name for $repo/$newloc from $repo_base/$repo/$newloc");
+ $fh = fopen("$repo_base/$repo/$newloc", "rb");
+
+ error_log("pushing file");
+ while(!feof($fh)) {
+ echo fread($fh, 8192);
+ }
+ } else {
+ echo "would ask $repo,$actual_repo_name for $repo/$newloc from $repo_base/$repo/$newloc, NE";
+ header('HTTP/1.0 404 No Such Thing');
+ return;
+ }
+}
+
+function gwvpmini_canManageRepo($userid, $repoid)
+{
+ // only the owner or an admin can do these tasks
+ error_log("Checking repoid, $repoid against userid $userid");
+
+ if(gwvpmini_IsUserAdmin(null, null, $userid)) return true;
+ if(gwvpmini_IsRepoOwner($userid, $repoid)) return true;
+ return false;
+}
+
+function gwvpmini_callGitBackend($username, $repo)
+{
+ // this is where things become a nightmare
+ $fh = fopen('php://input', "r");
+
+ $repo_base = gwvpmini_getConfigVal("repodir");\r
+
+
+ $ruri = $_SERVER["REQUEST_URI"];
+ $strrem = "git/$repo.git";
+ $euri = str_replace($strrem, "", $_REQUEST["q"]);
+ //$euri = preg_replace("/^git\/$repo\.git/", "", $_REQUEST["q"]);
+
+
+
+ $rmeth = $_SERVER["REQUEST_METHOD"];
+
+ $qs = "";
+ foreach($_REQUEST as $key => $var) {
+ if($key != "q") {
+ //error_log("adding, $var from $key");
+ if($qs == "") $qs.="$key=$var";
+ else $qs.="&$key=$var";
+ }
+ }
+
+ //sleep(2);
+
+
+
+ // this is where the fun, it ends.
+ $myoutput = "";
+ unset($myoutput);
+
+ // this be nasty!
+
+ // setup env
+ if(isset($procenv)) unset($procenv);
+ $procenv["GATEWAY_INTERFACE"] = "CGI/1.1";
+ $procenv["PATH_TRANSLATED"] = "/$repo_base/$repo.git/$euri";
+ $procenv["REQUEST_METHOD"] = "$rmeth";
+ $procenv["GIT_HTTP_EXPORT_ALL"] = "1";
+ $procenv["QUERY_STRING"] = "$qs";
+ $procenv["HTTP_USER_AGENT"] = "git/1.7.1";
+ $procenv["REMOTE_USER"] = "$username";
+ $procenv["REMOTE_ADDR"] = $_SERVER["REMOTE_ADDR"];
+ $procenv["AUTH_TYPE"] = "Basic";
+
+ if(isset($_SERVER["CONTENT_TYPE"])) {
+ $procenv["CONTENT_TYPE"] = $_SERVER["CONTENT_TYPE"];
+ } else {
+ //$procenv["CONTENT_TYPE"] = "";
+ }
+ if(isset($_SERVER["CONTENT_LENGTH"])) {
+ $procenv["CONTENT_LENGTH"] = $_SERVER["CONTENT_LENGTH"];
+ }
+
+ error_log("path trans'd is /$repo_base/$repo.git/$euri from $ruri with ".$_REQUEST["q"]." $strrem");
+
+
+
+
+ $pwd = "/$repo_base/";
+
+ $proc = proc_open("/usr/lib/git-core/git-http-backend", array(array("pipe","rb"),array("pipe","wb"),array("file","/tmp/err", "a")), $pipes, $pwd, $procenv);
+
+ $untilblank = false;
+ while(!$untilblank&&!feof($pipes[1])) {
+ $lines_t = fgets($pipes[1]);
+ $lines = trim($lines_t);
+ error_log("got line: $lines");
+ if($lines_t == "\r\n") {
+ $untilblank = true;
+ error_log("now blank");
+ } else header($lines);
+ if($lines === false) {
+ error_log("got an unexpexted exit...");
+ exit(0);
+ }
+
+ }
+
+
+ $firstline = true;
+ $continue = true;
+
+ if(!stream_set_blocking($fh,0)) {
+ error_log("cant set input non-blocking");
+ }
+
+ if(!stream_set_blocking($pipes[1],0)) {
+ error_log("cant set pipe1 non-blocking");
+ }
+
+ // i was going to use stream_select, but i feel this works better like this
+ while($continue) {
+ // do client
+ if(!feof($fh)) {
+ $from_client_data = fread($fh,8192);
+ if($from_client_data !== false) fwrite($pipes[0], $from_client_data);
+ fflush($pipes[0]);
+ //fwrite($fl, $from_client_data);
+ $client_len = strlen($from_client_data);
+ } else {
+ error_log("client end");
+ $client_len = 0;
+ }
+
+ // do cgi
+ // sometimes, we get a \r\n from the cgi, i do not know why she swallowed the fly,
+ // but i do know that the fgets for the headers above should have comsued that
+ if(!feof($pipes[1])) {
+ $from_cgi_data_t = fread($pipes[1],8192);
+ $from_cgi_data = $from_cgi_data_t;
+
+ // i dont know if this will solve it... it coudl cause some serious issues elsewhere
+ // TODO: this is a hack, i need to know why the fgets above doesn consume the \r\n even tho it reads it
+ // i.e. why the pointer doesnt increment over it, cause the freads above then get them again.
+ if($firstline) {
+ if(strlen($from_cgi_data_t)>0) {
+ // i dont get why this happens, and its very frustrating.. im not sure if its a bug in php
+ // or something the git-http-backend thing is doing..
+ // TODO: find out why this happens
+ $from_cgi_data = preg_replace("/^\r\n/", "", $from_cgi_data_t);
+ if(strlen($from_cgi_data)!=strlen($from_cgi_data_t)) {
+ error_log("MOOOKS - we did trunc");
+ } else {
+ error_log("MOOOKS - we did not trunc");
+ }
+ $firstline = false;
+ }
+ }
+
+ if($from_cgi_data !== false) {
+ echo $from_cgi_data;
+ flush();
+ }
+ $cgi_len = strlen($from_cgi_data);
+ } else {
+ error_log("cgi end");
+ $cgi_len = 0;
+ }
+
+ if(feof($pipes[1])) $continue = false;
+ else {
+ if($client_len == 0 && $cgi_len == 0) {
+ usleep(200000);
+ error_log("sleep tick");
+ } else {
+ error_log("sizes: $client_len, $cgi_len");
+ if($cgi_len > 0) {
+ error_log("from cgi: \"$from_cgi_data\"");
+ }
+ }
+ }
+
+ }
+
+
+ //fclose($fl);
+ fclose($fh);
+ fclose($pipes[1]);
+ fclose($pipes[0]);
+}
+
+
+
+function gwvpmini_repoExists($name)
+{
+ $repo_base = gwvpmini_getConfigVal("repodir");
+
+ if(file_exists("$repo_base/$name.git")) return true;
+ else return false;
+}
+
+// default perms:
+// 0 - anyone can clone/read, only owner can write
+// 1 - noone can clone/read, repo is visible (i.e. name), only owner can read/write repo
+// 2 - only owner can see anything
+function gwvpmini_createGitRepo($name, $ownerid, $desc)
+{
+ $repo_base = gwvpmini_getConfigVal("repodir");
+
+ // phew, this works, but i tell you this - bundles arent quite as nice as they should be
+ error_log("would create $repo_base/$name.git");
+ exec("/usr/bin/git init $repo_base/$name.git --bare > /tmp/gitlog 2>&1");
+ chdir("$repo_base/$name.git");
+ exec("/usr/bin/git update-server-info");
+
+ // gwvpmini_AddRepo($reponame, $repodesc, $repoowner, $defaultperms = 0)
+ gwvpmini_AddRepo($name, $desc, $ownerid);
+
+ return true;
+}
+
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+global $HOME_PAGE_PROVIDERS;\r
+
+
+$CALL_ME_FUNCTIONS["repoadmin"] = "gwvpmini_RepoCallMe";
+$HOME_PAGE_PROVIDERS["gitlog"] = "gwvpmini_GitLogProvider";\r
+\r
+\r
+// the home_page_provders bit is an array\r
+\r
+$MENU_ITEMS["10repos"]["text"] = "Repos";\r
+$MENU_ITEMS["10repos"]["link"] = "$BASE_URL/repos";
+
+
+function gwvpmini_RepoCallMe()\r
+{\r
+\r
+ error_log("in repoadmin callme - err?");
+ error_log(print_r($_REQUEST, true));\r
+ if(isset($_REQUEST["q"])) {
+ error_log("in repoadmin callme, for Q");\r
+ $query = $_REQUEST["q"];\r
+ $qspl = explode("/", $query);\r
+ if(isset($qspl[0])) {\r
+ if($qspl[0] == "repos") {
+ error_log("in repos call");
+ if(isset($qspl[1])) {
+ if($qspl[1] == "create") {
+ return "gwvpmini_RepoCreate";
+ } else {
+ return "gwvpmini_RepoMainPage";
+ }
+ } else {\r
+ error_log("i got here, where next?");\r
+ return "gwvpmini_RepoMainPage";
+ }\r
+ } else return false;\r
+ }\r
+ else return false;\r
+ }\r
+\r
+ return false;\r
+}\r
+
+
+function gwvpmini_RepoMainPage()\r
+{\r
+ gwvpmini_goMainPage("gwvpmini_RepoMainPageBody");\r
+}\r
+\r
+
+function gwvpmini_RepoMainPageBody()
+{
+ gwvpmini_GitCreateRepoForm();
+ if(gwvpmini_isLoggedIn()) {
+ $repos = gwvpmini_GetOwnedRepos($_SESSION["username"]);
+ if(!$repos) {
+ echo "You currently own no repos<br>";
+ } else {
+ echo "<h2>Your Repos</h2>";
+ echo "<table border=\"1\"><tr><th>Repo Name</th><th>Repo Description</th><th>Last Log</th></tr>";
+ foreach($repos as $repo) {
+ $name = $repo["name"];
+ $desc = $repo["desc"];
+ echo "<tr><td>$name</td><td>$desc</td>";
+ echo "<td>";\r
+ $repo_base = gwvpmini_getConfigVal("repodir");\r
+ $cmd = "git --git-dir=\"$repo_base/$name.git\" log -1 2>&1";\r
+ error_log("CMD: $cmd");\r
+ system("$cmd");\r
+ echo "</td>";
+ echo "</tr>";
+ }
+ echo "</table>";
+ }
+ }
+ return true;
+}
+
+
+function gwvpmini_GitLogProvider()\r
+{\r
+ /*\r
+ * The home page provider will:\r
+ * 1) show the last 10 commits for every repository - though, excluding private repos\r
+ * 2) if loged in, show the last commit on any repo's the user owns\r
+ *\r
+ * So i need a table thats going to list "writes" by user - as in POST writes but only\r
+ * put that info into the stats (doesnt exist) db if the repo is publically readable\r
+ *\r
+ * Or... should we instead just list every repo?\r
+ */
+ echo "<h2>Repo Activity</h2>";
+ if(gwvpmini_isLoggedIn()) {\r
+ $repos = gwvpmini_GetOwnedRepos($_SESSION["username"]);
+ if(!$repos) {
+ echo "You currently own no repos<br>";
+ } else {
+ echo "<h2>Your Repos</h2>";
+ echo "<table border=\"1\"><tr><th>Repo Name</th><th>Repo Description</th><th>Repo Log</th></tr>";
+ foreach($repos as $repo) {
+ $name = $repo["name"];
+ $desc = $repo["desc"];
+ echo "<tr><td>$name</td><td>$desc</td>";
+ echo "<td>";
+ $repo_base = gwvpmini_getConfigVal("repodir");
+ $cmd = "git --git-dir=\"$repo_base/$name.git\" log -1 2>&1";
+ error_log("CMD: $cmd");
+ system("$cmd");
+ echo "</td>";
+ echo "</tr>";
+ }
+ echo "</table>";
+ }\r
+ }
+}
+
+function gwvpmini_GitCreateRepoForm()
+{
+ global $BASE_URL;
+
+ echo "<form method=\"post\" action=\"$BASE_URL/repos/create\">";
+ echo "<table border=\"1\">";
+ echo "<tr><th colspan=\"2\">Create Repo</th></tr>";
+ echo "<tr><th>Repo Name</th><td><input type=\"text\" name=\"reponame\"></td></tr>";
+ echo "<tr><th>Repo Description</th><td><input type=\"text\" name=\"repodesc\"></td></tr>";
+ echo "<tr><td colspan=\"2\"><input type=\"submit\" name=\"Create\" value=\"Create\"></td></tr>";
+ echo "</table>";
+ echo "</form>";
+}\r
+
+function gwvpmini_RepoCreate()
+{
+
+ global $BASE_URL;
+
+ if(gwvpmini_isLoggedIn()) {
+ //gwvpmini_createGitRepo($name, $ownerid, $desc, $bundle=null, $defaultperms=0)
+ if(gwvpmini_HaveRepo($_REQUEST["reponame"])) {
+ gwvpmini_SendMessage("error", "Repo ".$_REQUEST["reponame"]." already exists");\r
+ header("Location: $BASE_URL/repos");
+ } else {
+ gwvpmini_createGitRepo($_REQUEST["reponame"], $_SESSION["id"], $_REQUEST["repodesc"]);
+ gwvpmini_SendMessage("info", "Repo ".$_REQUEST["reponame"]." has been created");
+ header("Location: $BASE_URL/repos");
+ }
+ } else {
+ gwvpmini_SendMessage("info", "Must be logged in to create repo");
+ header("Location: $BASE_URL/repos");
+ }
+}
+
+function gwvpmini_HaveRepo($reponame)
+{
+ $repo_base = gwvpmini_getConfigVal("repodir");
+
+ if(file_exists("$repo_base/$reponame.git")) return true;
+}
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+
+function gwvpmini_goSetup()
+{
+ return true;
+}
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+
+// this function is the initial insertion point for the web calls, here we need to determine where we go
+global $CALL_ME_FUNCTIONS;
+
+// the home_page_provders bit is an array
+global $HOME_PAGE_PROVIDERS;
+
+$MENU_ITEMS["00home"]["text"] = "Home";
+$MENU_ITEMS["00home"]["link"] = "$BASE_URL";
+
+
+
+function gwvpmini_goWeb()
+{
+ global $CALL_ME_FUNCTIONS;
+
+ // first we determine if we have a valid setup and run the installer if not
+ /*if(!gwvpmini_issetup()) {
+ gwvpmini_goSetup();
+ return;
+ }*/
+
+ // next, we go thru the CALL_ME_FUNCTIONS - the purpose of call_me_functions is to determine if a function should be called based on
+ // the functions return (i.e. if function returns false, its not it, otherwise it returns a function name we have to call)
+ // this is important for our plugin structure later on - the key on the array serves an an ordering method
+ ksort($CALL_ME_FUNCTIONS);
+ foreach($CALL_ME_FUNCTIONS as $key => $val) {
+ error_log("checking callmefunction $key as $val");
+ $callme = $val();
+ if($callme !== false) {
+ $callme();
+ return;
+ }
+ }
+
+ // we fell-thru to the main web page builder
+ gwvpmini_goMainPage();
+}
+
+function gwvpmini_SendMessage($messagetype, $message)
+{
+ $_SESSION["messagetype"] = $messagetype;
+ $_SESSION["message"] = $message;
+}
+
+function gwvpmini_goMainPage($bodyFunction = null)
+{
+ // the main page will look pretty simple, a title, a menu then a body
+ global $WEB_ROOT_FS, $BASE_URL;
+
+ // a simple web page layout that loads any css and js files that exist in the css and js directories
+ echo "<html><head><title>GWVP Mini</title>";
+
+ // load css
+ if(file_exists("$WEB_ROOT_FS/css")) {
+ $dh = opendir("$WEB_ROOT_FS/css");
+ if($dh) {
+ while(($file = readdir($dh))!==false) {
+ $mt = preg_match("/.*.css$/", $file);
+ if($mt > 0) {
+ error_log("loading css $file");
+ echo "<link rel=\"stylesheet\" type=\"text/css\" href=\"$BASE_URL/css/$file\">";
+ //echo "required $basedir/$file\n";
+ }
+ }
+ }
+ }
+
+ // load js
+ if(file_exists("$WEB_ROOT_FS/js")) {
+ $dh = opendir("$WEB_ROOT_FS/js");
+ if($dh) {
+ while(($file = readdir($dh))!==false) {
+ $mt = preg_match("/.*.js$/", $file);
+ if($mt > 0) {
+ error_log("loading js $file");
+ echo "<script type=\"text/javascript\" src=\"$BASE_URL/js/$file\"></script>";
+ //echo "required $basedir/$file\n";
+ }
+ }
+ }
+ }
+
+
+ // start body
+ echo "</head><body>";
+
+ echo "<h1>Git over Web Via PHP - Mini Version</h2>";
+
+
+ echo "<table width=\"100%\">";
+
+ if(isset($_SESSION["message"])) {
+ echo "<tr width=\"100%\"><td colspan=\"2\">";
+ gwvpmini_MessageBuilder();
+ echo "</td></tr>";
+ }
+
+ echo "<tr width=\"100%\" bgcolor=\"#ddffdd\"><td>";
+ gwvpmini_MenuBuilder();
+ echo "</td><td align=\"right\">";
+ gwvpmini_LoginBuilder();
+ echo "</td>";
+
+ echo "</tr>";
+
+ echo "<tr><td>";
+ if($bodyFunction == null) {
+ gwvpmini_BodyBuilder();
+ } else {
+ if(function_exists($bodyFunction)) {
+ $bodyFunction();
+ } else {
+ error_log("Got called with non-existant body function, $bodyFunction");
+ gwvpmini_BodyBuilder();
+ }
+ }
+ echo "</td></tr>";
+
+ echo "<tr><td>";
+ gwvpmini_TailBuilder();
+ echo "</td></tr></table></body></html>";
+
+}
+
+
+// builds the message builder if its needed
+function gwvpmini_MessageBuilder()
+{
+ $message = "";
+ $messagetype = "info";
+ if(isset($_SESSION["message"])) $message = $_SESSION["message"];
+ if(isset($_SESSION["messagetype"])) $messagetype = $_SESSION["messagetype"];
+
+ if($message != "") {
+ switch($messagetype) {
+ case "info":
+ echo "<table border=\"1\" width=\"100%\"><tr width=\"100%\"><td bgcolor=\"#AAFFAA\">$message</td></tr></table>";
+ break;
+ case "error":
+ echo "<table border=\"1\" width=\"100%\"><tr width=\"100%\"><td bgcolor=\"#FFAAAA\">$message</td></tr></table>";
+ break;
+ }
+ unset($_SESSION["message"]);
+ if(isset($_SESSION["messagetype"])) unset($_SESSION["messagetype"]);
+ }
+}
+
+// builds the menu structure
+function gwvpmini_MenuBuilder()
+{
+ global $MENU_ITEMS, $BASE_URL;
+
+ ksort($MENU_ITEMS);
+
+ echo "<table border=\"1\"><tr><td><b><i>Menu</i></b></td>";
+ foreach($MENU_ITEMS as $key => $val) {
+ $link = $val["link"];
+ $text = $val["text"];
+
+ // TODO: redo this bit with stristr to find urls - special case for home
+ $menucolor = "";
+ if(isset($_REQUEST["q"])) {
+ $extlink = str_replace("$BASE_URL/", "", $link);
+ error_log("trying to do replace of $BASE_URL in $link, got $extlink for ".$_REQUEST["q"]);
+ if(stristr($_REQUEST["q"], $extlink)!==false) {
+ $menucolor = " bgcolor=\"#ffdddd\"";
+
+ }
+ } else {
+ // special case for home
+ if($link == $BASE_URL) $menucolor = " bgcolor=\"#ffdddd\"";
+ }
+
+
+
+
+ if(isset($val["userlevel"])) {
+ if(gwvpmini_CheckAuthLevel($val["userlevel"])) {
+ echo "<td$menucolor><a href=\"$link\">$text</a></td>";
+ }
+
+ } else {
+ echo "<td$menucolor><a href=\"$link\">$text</a></td>";
+ }
+ }
+ echo "</tr></table>";
+
+}
+
+function gwvpmini_LoginBuilder()
+{
+ global $WEB_ROOT_FS, $BASE_URL;
+
+ $login = gwvpmini_IsLoggedIn();
+ if($login === false) {
+ gwvpmini_SingleLineLoginForm();
+ } else {
+ echo "Hello ".$_SESSION["fullname"]." <a href=\"$BASE_URL/logout\">logout</a>";
+ }
+}
+
+// builds the body structure
+function gwvpmini_BodyBuilder()
+{
+ global $HOME_PAGE_PROVIDERS;
+
+ echo "I AM THE MAIN BODY, FEAR ME!!!! - have no idea whats going to go here";
+ if(isset($HOME_PAGE_PROVIDERS)) {
+ ksort($HOME_PAGE_PROVIDERS);
+ foreach($HOME_PAGE_PROVIDERS as $provider) {
+ error_log("Loading home_page_provider, $provider");
+ $provider();
+ }
+ }
+}
+
+// builds the tail structure
+function gwvpmini_TailBuilder()
+{
+ echo "<font size=\"-1\"><i>Copyright 2011, PJR - licensed under GPL</i></font>";
+}
+
+function gwvpmini_fourZeroThree()
+{
+ error_log("403 called");
+ header("HTTP/1.0 403 Permission Denied");
+}
+
+function gwvpmini_fourZeroFour()
+{
+ error_log("404 called");
+ header("HTTP/1.0 404 No Such Thing");
+}
+
+
+
+?>
\ No newline at end of file
--- /dev/null
+RewriteEngine on
+RewriteBase /src/local/eclipse-workspace/gwvp-mini/www/
+RewriteRule ^index\.php.* - [L,B]
+RewriteCond %{REQUEST_FILENAME} !-f
+RewriteCond %{REQUEST_FILENAME} !-d
+RewriteRule ^(.*)$ index.php?q=$1 [L,QSA,B]
+
--- /dev/null
+<?php
+
+// this config file is going to reduce down to just db connectivity - thats all
+// all other config will be kept in the db, but not just yet
+
+// the config file, this is as exciting as it gets really
+// no longer valid here $repo_base = "/tmp/";
+$data_directory = "$WEB_ROOT_FS/../data";
+$db_type = "sqlite"; // could be mysql or pgsql - but not yet
+$db_name = "$data_directory/gwvpmini.db"; // just a file for sqlite, for anything else is a pdo url without driver, i.e. host=localhost;dbname=whatever;user=asdf;password=asdf
+$db_username = "";
+$db_password = "";
+
+
+error_log("included config file");
+?>
\ No newline at end of file
--- /dev/null
+head {
+ color: #333333;
+}
+body {
+ color: #333333;
+}
+table { border-width: 0px;
+ empty-cells: hide;
+}
+table.formsection, table.sortable, table.ui_table, table.loginform {
+ border-collapse: collapse;
+ border: 1px solid #FFFFFF;
+ width: 100%;
+}
+img, a img { border:0; }
+tr.row0 {background-color:#e8e8ea;}
+tr.row1 {background-color:#f8f8fa;}
+table.formsection thead, table.sortable thead, table.ui_table thead, table.loginform thead {
+background-color:#427ad1;
+border:0px;
+color:#ffffff;
+border: 2px solid #b3b6b0;
+}
+table.formsection tbody, table.sortable tbody, table.ui_table tbody, table.loginform tbody {
+background-color:#EFEFEF;
+}
+tr.maintitle {
+ color: #ffffff;
+ background-color: #427ad1;
+}
+td.maintitle {
+ color: #ffffff;
+ background-color: #427ad1;
+}
+tr.maintitle a, tr.maintitle a:visited {
+ color: #ffffff;
+}
+td.maintitle a, td.maintitle a:visited {
+ color: #ffffff;
+}
+tr.maintitle a:hover {
+ color: #EFEFEF;
+}
+td.maintitle a:hover {
+ color: #EFEFEF;
+}
+a:link { color: #333399;
+ text-decoration: none;
+}
+a:hover, a:visited:hover { color: #6666EE;
+ text-decoration: none;
+}
+a:visited { color: #333399;
+ text-decoration: none;
+}
+body, p, td, br, center { font-size: 10pt;
+ font-family: sans-serif;
+}
+title { color: #333333;
+ font-family: sans-serif;
+}
+h1 { color: #333333;
+ font-size: 150%;
+ font-family: sans-serif;
+}
+h2 { color: #333333;
+ font-size: 130%;
+ font-family: sans-serif;
+}
+h3 { color: #333333;
+ font-size: 125%;
+ font-family: sans-serif;
+}
+h4 { color: #333333;
+ font-size: 120%;
+ font-family: sans-serif;
+}
+th { font-size: small; }
+pre { font-size: 8pt; }
+#main { border-style: solid;
+ border:1px solid #FFFFFF;
+ margin:0;
+ padding:0;
+}
+tr.mainsel { background-color: #ddffbb; }
+tr.mainhigh { background-color: #ffffbb; }
+tr.mainhighsel { background-color: #bbffcc; }
+.itemhidden { display: none; }
+.itemshown { display:block; }
+.barchart { padding: 1px;
+ border: 1px solid #b3b6b0;
+ position:relative;
+}
+.ui_post_header{ font-size: 120%;
+ text-align: center;
+ padding: 4px;
+}
+hr { border: 0;
+ width: 90%;
+ height: 1px;
+ color: #D9D9D9;
+ background-color: #D9D9D9;
+}
+table.wrapper {
+ background-color:#D9D9D9;
+ border:0;
+ padding:0;
+ margin:0;
+ border-collapse:collapse;
+}
+div.wrapper {
+ border:1px solid #D9D9D9;
+ background-color:#F5F5F5;
+ padding:0;
+ margin:0;
+}
+.shrinkwrapper {
+ background-color:#D9D9D9;
+ border:0;
+ padding:0;
+ margin:0;
+ border-collapse:collapse;
+}
+.tabSelected {
+ background-color:#D9D9D9;
+}
+.tabUnselected {
+ background-color:#dadaf8;
+}
+
+input[type=text] {
+ width: 200px;
+ border: 1px solid;
+}
+
+input.login {
+ width: 100px;
+ border: 1px solid;
+}
+
+.loginbutton {
+ border: 1px solid;
+}
+
+form {
+ margin: 0em;
+}
+
+.buttons {
+ border: 1px solid;
+}
+
+.mycheckbox {
+ border: 0px solid;
+ border-color:#000;
+}
+
+.myselect {
+
+ border-color:#000;
+}
+
+#myidselect {
+
+ border-color:#000;
+}
+
+.selectpretty select {
+ border: 1px solid;
+}
+
+input.long {
+ width: 400px;
+}
\ No newline at end of file
--- /dev/null
+<?php
+$WEB_ROOT_FS = realpath(dirname(__FILE__));\r
+$BASE_URL = dirname($_SERVER["PHP_SELF"]);\r
+\r
+global $WEB_ROOT_FS, $BASE_URL, $data_directory, $db_type, $db_name, $db_username, $db_password;\r
+
+if(file_exists("./config.php")) require_once("./config.php");
+else if(file_exists("/etc/gwvpmini/config.php")) require_once("/etc/gwvpmini/config.php");
+else $noconfig = true;
+
+if(file_exists("../gwvpmini/gwvpmini.php")) require_once("../gwvpmini/gwvpmini.php");
+else if(file_exists("/usr/share/gwvpmini/lib/gwvpmini/gwvpmini.php")) require_once("/usr/share/gwvpmini/lib/gwvpmini/gwvpmini.php");
+
+
+
+if(isset($noconfig)) {
+ gwvpmini_goSetup();
+ return;
+}
+
+// need to make this db agnostic
+if(!gwvpmini_DBExists($db_name)) {
+ if(!is_dir("$data_directory/repos")) mkdir("$data_directory/repos");
+
+ error_log("CREATEDATABASE");
+ gwvpmini_dbCreateSQLiteStructure($db_name);
+ gwvpmini_setConfigVal("repodir", "$data_directory/repos");
+}
+
+gwvpmini_goWeb();
+
+/*
+echo "<pre>";
+print_r($_SERVER);
+print_r($_REQUEST);
+print_r($_SESSION);
+echo "</pre>";
+*/
+?>
\ No newline at end of file