initial code layout
authorPaul J R <me@pjr.cc>
Tue, 18 Sep 2012 17:14:36 +0000 (03:14 +1000)
committerPaul J R <me@pjr.cc>
Tue, 18 Sep 2012 17:14:36 +0000 (03:14 +1000)
35 files changed:
data/gwvpmini.db [new file with mode: 0644]
data/repos/qwer.git/HEAD [new file with mode: 0644]
data/repos/qwer.git/config [new file with mode: 0644]
data/repos/qwer.git/description [new file with mode: 0644]
data/repos/qwer.git/hooks/applypatch-msg.sample [new file with mode: 0755]
data/repos/qwer.git/hooks/commit-msg.sample [new file with mode: 0755]
data/repos/qwer.git/hooks/post-update.sample [new file with mode: 0755]
data/repos/qwer.git/hooks/pre-applypatch.sample [new file with mode: 0755]
data/repos/qwer.git/hooks/pre-commit.sample [new file with mode: 0755]
data/repos/qwer.git/hooks/pre-rebase.sample [new file with mode: 0755]
data/repos/qwer.git/hooks/prepare-commit-msg.sample [new file with mode: 0755]
data/repos/qwer.git/hooks/update.sample [new file with mode: 0755]
data/repos/qwer.git/info/exclude [new file with mode: 0644]
data/repos/qwer.git/info/refs [new file with mode: 0644]
data/repos/qwer.git/objects/40/97f8848b4b638854909fb4cc1232f23d4bc891 [new file with mode: 0644]
data/repos/qwer.git/objects/75/6c1add57e06a607772ab479a849314bec41fe9 [new file with mode: 0644]
data/repos/qwer.git/objects/b1/bb4a245007dd9a1e1a43b2d1d7db304ec3edf0 [new file with mode: 0644]
data/repos/qwer.git/objects/da/ef7b14a99501d69a28cd0ce4d2991b1fe5898d [new file with mode: 0644]
data/repos/qwer.git/objects/info/packs [new file with mode: 0644]
data/repos/qwer.git/objects/pack/pack-d07d7771496ba63a1ed21b17101b417ae41c7c9a.idx [new file with mode: 0644]
data/repos/qwer.git/objects/pack/pack-d07d7771496ba63a1ed21b17101b417ae41c7c9a.pack [new file with mode: 0644]
data/repos/qwer.git/refs/heads/master [new file with mode: 0644]
gwvpmini/gwvpmini.php [new file with mode: 0644]
gwvpmini/gwvpmini_admin.php [new file with mode: 0644]
gwvpmini/gwvpmini_auth.php [new file with mode: 0644]
gwvpmini/gwvpmini_db.php [new file with mode: 0644]
gwvpmini/gwvpmini_gitbackend.php [new file with mode: 0644]
gwvpmini/gwvpmini_gitrepo.php [new file with mode: 0644]
gwvpmini/gwvpmini_setup.php [new file with mode: 0644]
gwvpmini/gwvpmini_web.php [new file with mode: 0644]
unittests/createlotsofreposandusers.php [new file with mode: 0644]
www/.htaccess [new file with mode: 0644]
www/config.php [new file with mode: 0644]
www/css/normal.css [new file with mode: 0644]
www/index.php [new file with mode: 0644]

diff --git a/data/gwvpmini.db b/data/gwvpmini.db
new file mode 100644 (file)
index 0000000..f64baa6
Binary files /dev/null and b/data/gwvpmini.db differ
diff --git a/data/repos/qwer.git/HEAD b/data/repos/qwer.git/HEAD
new file mode 100644 (file)
index 0000000..cb089cd
--- /dev/null
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/data/repos/qwer.git/config b/data/repos/qwer.git/config
new file mode 100644 (file)
index 0000000..07d359d
--- /dev/null
@@ -0,0 +1,4 @@
+[core]
+       repositoryformatversion = 0
+       filemode = true
+       bare = true
diff --git a/data/repos/qwer.git/description b/data/repos/qwer.git/description
new file mode 100644 (file)
index 0000000..498b267
--- /dev/null
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/data/repos/qwer.git/hooks/applypatch-msg.sample b/data/repos/qwer.git/hooks/applypatch-msg.sample
new file mode 100755 (executable)
index 0000000..8b2a2fe
--- /dev/null
@@ -0,0 +1,15 @@
+#!/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+"$@"}
+:
diff --git a/data/repos/qwer.git/hooks/commit-msg.sample b/data/repos/qwer.git/hooks/commit-msg.sample
new file mode 100755 (executable)
index 0000000..b58d118
--- /dev/null
@@ -0,0 +1,24 @@
+#!/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
+}
diff --git a/data/repos/qwer.git/hooks/post-update.sample b/data/repos/qwer.git/hooks/post-update.sample
new file mode 100755 (executable)
index 0000000..ec17ec1
--- /dev/null
@@ -0,0 +1,8 @@
+#!/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
diff --git a/data/repos/qwer.git/hooks/pre-applypatch.sample b/data/repos/qwer.git/hooks/pre-applypatch.sample
new file mode 100755 (executable)
index 0000000..b1f187c
--- /dev/null
@@ -0,0 +1,14 @@
+#!/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+"$@"}
+:
diff --git a/data/repos/qwer.git/hooks/pre-commit.sample b/data/repos/qwer.git/hooks/pre-commit.sample
new file mode 100755 (executable)
index 0000000..18c4829
--- /dev/null
@@ -0,0 +1,50 @@
+#!/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 --
diff --git a/data/repos/qwer.git/hooks/pre-rebase.sample b/data/repos/qwer.git/hooks/pre-rebase.sample
new file mode 100755 (executable)
index 0000000..33730ca
--- /dev/null
@@ -0,0 +1,169 @@
+#!/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
diff --git a/data/repos/qwer.git/hooks/prepare-commit-msg.sample b/data/repos/qwer.git/hooks/prepare-commit-msg.sample
new file mode 100755 (executable)
index 0000000..f093a02
--- /dev/null
@@ -0,0 +1,36 @@
+#!/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"
diff --git a/data/repos/qwer.git/hooks/update.sample b/data/repos/qwer.git/hooks/update.sample
new file mode 100755 (executable)
index 0000000..71ab04e
--- /dev/null
@@ -0,0 +1,128 @@
+#!/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
diff --git a/data/repos/qwer.git/info/exclude b/data/repos/qwer.git/info/exclude
new file mode 100644 (file)
index 0000000..a5196d1
--- /dev/null
@@ -0,0 +1,6 @@
+# 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]
+# *~
diff --git a/data/repos/qwer.git/info/refs b/data/repos/qwer.git/info/refs
new file mode 100644 (file)
index 0000000..ee5ce9e
--- /dev/null
@@ -0,0 +1 @@
+756c1add57e06a607772ab479a849314bec41fe9       refs/heads/master
diff --git a/data/repos/qwer.git/objects/40/97f8848b4b638854909fb4cc1232f23d4bc891 b/data/repos/qwer.git/objects/40/97f8848b4b638854909fb4cc1232f23d4bc891
new file mode 100644 (file)
index 0000000..7d5bd65
Binary files /dev/null and b/data/repos/qwer.git/objects/40/97f8848b4b638854909fb4cc1232f23d4bc891 differ
diff --git a/data/repos/qwer.git/objects/75/6c1add57e06a607772ab479a849314bec41fe9 b/data/repos/qwer.git/objects/75/6c1add57e06a607772ab479a849314bec41fe9
new file mode 100644 (file)
index 0000000..875c96d
--- /dev/null
@@ -0,0 +1,3 @@
+x\ 1ŽM
+Â0\10F]ç\14³\17$“LÛ\ 4D\»\12oL&¶b\7fˆ)âí-ž@¾í{¼çq\1c*\18C»ZD€´ï²sä"ÅÖ:א×>GbFcM66QdçQ-¡ÈT2Ō) Û–\b\r§®i¬hl%IãºMM­
+kíç\ 2×°>á\ 278Žr^\1eåÀ|\ 2´Ôykm‹°G­µâß«*ÿòŠû0Ý%AÞ\12“¼!\rE¸Îå\ 3¯ZV®k\11õ\ 5¤ÈD‹
\ No newline at end of file
diff --git a/data/repos/qwer.git/objects/b1/bb4a245007dd9a1e1a43b2d1d7db304ec3edf0 b/data/repos/qwer.git/objects/b1/bb4a245007dd9a1e1a43b2d1d7db304ec3edf0
new file mode 100644 (file)
index 0000000..535bbeb
Binary files /dev/null and b/data/repos/qwer.git/objects/b1/bb4a245007dd9a1e1a43b2d1d7db304ec3edf0 differ
diff --git a/data/repos/qwer.git/objects/da/ef7b14a99501d69a28cd0ce4d2991b1fe5898d b/data/repos/qwer.git/objects/da/ef7b14a99501d69a28cd0ce4d2991b1fe5898d
new file mode 100644 (file)
index 0000000..e75767b
--- /dev/null
@@ -0,0 +1,2 @@
+x\ 1ÍÍ
+‚@\18…áÖ^Å\17\18”¤Sí#4&\b,PkÕ\1f:~ÙÐ03i5Atïaå¾íá=<™P\19ŒFƒVŒ¦ä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¿6­7+ÍJÒ
\ No newline at end of file
diff --git a/data/repos/qwer.git/objects/info/packs b/data/repos/qwer.git/objects/info/packs
new file mode 100644 (file)
index 0000000..2911f65
--- /dev/null
@@ -0,0 +1,2 @@
+P pack-d07d7771496ba63a1ed21b17101b417ae41c7c9a.pack
+
diff --git a/data/repos/qwer.git/objects/pack/pack-d07d7771496ba63a1ed21b17101b417ae41c7c9a.idx b/data/repos/qwer.git/objects/pack/pack-d07d7771496ba63a1ed21b17101b417ae41c7c9a.idx
new file mode 100644 (file)
index 0000000..1b5356c
Binary files /dev/null and b/data/repos/qwer.git/objects/pack/pack-d07d7771496ba63a1ed21b17101b417ae41c7c9a.idx differ
diff --git a/data/repos/qwer.git/objects/pack/pack-d07d7771496ba63a1ed21b17101b417ae41c7c9a.pack b/data/repos/qwer.git/objects/pack/pack-d07d7771496ba63a1ed21b17101b417ae41c7c9a.pack
new file mode 100644 (file)
index 0000000..3decc2b
Binary files /dev/null and b/data/repos/qwer.git/objects/pack/pack-d07d7771496ba63a1ed21b17101b417ae41c7c9a.pack differ
diff --git a/data/repos/qwer.git/refs/heads/master b/data/repos/qwer.git/refs/heads/master
new file mode 100644 (file)
index 0000000..d55b3f8
--- /dev/null
@@ -0,0 +1 @@
+756c1add57e06a607772ab479a849314bec41fe9
diff --git a/gwvpmini/gwvpmini.php b/gwvpmini/gwvpmini.php
new file mode 100644 (file)
index 0000000..d035b5d
--- /dev/null
@@ -0,0 +1,13 @@
+<?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
diff --git a/gwvpmini/gwvpmini_admin.php b/gwvpmini/gwvpmini_admin.php
new file mode 100644 (file)
index 0000000..353749a
--- /dev/null
@@ -0,0 +1,57 @@
+<?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
diff --git a/gwvpmini/gwvpmini_auth.php b/gwvpmini/gwvpmini_auth.php
new file mode 100644 (file)
index 0000000..342cd71
--- /dev/null
@@ -0,0 +1,158 @@
+<?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
diff --git a/gwvpmini/gwvpmini_db.php b/gwvpmini/gwvpmini_db.php
new file mode 100644 (file)
index 0000000..cf1f6d5
--- /dev/null
@@ -0,0 +1,349 @@
+<?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
diff --git a/gwvpmini/gwvpmini_gitbackend.php b/gwvpmini/gwvpmini_gitbackend.php
new file mode 100644 (file)
index 0000000..17b5788
--- /dev/null
@@ -0,0 +1,457 @@
+<?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
diff --git a/gwvpmini/gwvpmini_gitrepo.php b/gwvpmini/gwvpmini_gitrepo.php
new file mode 100644 (file)
index 0000000..1f42a7f
--- /dev/null
@@ -0,0 +1,160 @@
+<?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
diff --git a/gwvpmini/gwvpmini_setup.php b/gwvpmini/gwvpmini_setup.php
new file mode 100644 (file)
index 0000000..b5856ce
--- /dev/null
@@ -0,0 +1,8 @@
+<?php
+
+function gwvpmini_goSetup()
+{
+       return true;
+}
+
+?>
\ No newline at end of file
diff --git a/gwvpmini/gwvpmini_web.php b/gwvpmini/gwvpmini_web.php
new file mode 100644 (file)
index 0000000..72f95d7
--- /dev/null
@@ -0,0 +1,239 @@
+<?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
diff --git a/unittests/createlotsofreposandusers.php b/unittests/createlotsofreposandusers.php
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/www/.htaccess b/www/.htaccess
new file mode 100644 (file)
index 0000000..9f3570d
--- /dev/null
@@ -0,0 +1,7 @@
+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]
+
diff --git a/www/config.php b/www/config.php
new file mode 100644 (file)
index 0000000..cbdcdf4
--- /dev/null
@@ -0,0 +1,16 @@
+<?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
diff --git a/www/css/normal.css b/www/css/normal.css
new file mode 100644 (file)
index 0000000..586f541
--- /dev/null
@@ -0,0 +1,174 @@
+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
diff --git a/www/index.php b/www/index.php
new file mode 100644 (file)
index 0000000..412c49e
--- /dev/null
@@ -0,0 +1,39 @@
+<?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