added the ability to clone a repo via a bundle... tonnes of fun that
[gwvp.git] / gwvplib / gwvpgitcontrol.php
1 <?php
2
3 $CALL_ME_FUNCTIONS["gitcontrol"] = "gwvp_gitControlCallMe";
4
5 //$MENU_ITEMS["20repos"]["text"] = "Repo Admin";
6 //$MENU_ITEMS["20repos"]["link"] = "$BASE_URL/admin/repos";
7
8 function gwvp_gitControlCallMe()
9 {
10         if(isset($_REQUEST["q"])) {
11                 $query = $_REQUEST["q"];
12                 $qspl = explode("/", $query);
13                 if(isset($qspl[0])) {
14                         if($qspl[0] == "git") {
15                                 return "gwvp_gitBackendInterface";
16                         }
17                 } 
18                 else return false;
19         }
20         
21         return false;
22         
23 }
24
25 function gwvp_repoPermissionCheck($repo, $user)
26 {
27         return true;
28 }
29
30 function gwvp_gitBackendInterface()
31 {
32         global $repo_base, $BASE_URL;
33         
34         $repo = "";
35         $newloc = "/";
36         if(isset($_REQUEST["q"])) {
37                 $query = $_REQUEST["q"];
38                 $qspl = explode("/", $query);
39                 $repo = $qspl[1];
40                 for($i=2; $i < count($qspl); $i++) {
41                         $newloc .= "/".$qspl[$i];
42                 }
43         }
44         
45         $actual_repo_name = preg_replace("/\.git$/", "", $repo); 
46         
47         $user = gwvp_checkBasicAuthLogin();
48
49         if(!$user) {
50                 error_log("User is set to false, so its anonymouse");
51         } else {
52                 error_log("user is $user");
53         }
54         
55         // must remember that $user of false is anonymous when we code gwvp_repoPerm'sCheck()
56         if(!gwvp_repoPermissionCheck($actual_repo_name, $user)) {
57                 error_log("perms check fails - start auth");
58                 if(isset($_SERVER["PHP_AUTH_USER"])) {
59                         error_log("have auth - push 403");
60                         gwvp_fourZeroThree();
61                 } else {
62                         error_log("push auth");
63                         gwvp_AskForBasicAuth();
64                         return;
65                 }
66         }
67         
68         // we need to quite a bit of parsing in here. The "repo" will always be /git/repo.git
69         // but if we get here from a browser, we need to forward back to a normal repo viewer
70         // the only way i can think of doing this is to check the useragent for the word "git"
71         
72         /*
73          * here we need to
74          * 1) figure out the repo its acessing
75          * 2) figure out the perms on the repo
76          * 3) determine if its a pull or a push
77          * - if its a pull, we just serve straight from the fs
78          * - if its a push, we go thru git-http-backend
79          * 4) if it requiers auth, we push to auth
80          * 
81          */
82         $agent = "git-unknown";
83         $isgitagent = false;
84         
85         // tested the user agent bit with jgit from eclipse and normal git... seems to work
86         if(isset($_SERVER["HTTP_USER_AGENT"])) {
87                 $agent = $_SERVER["HTTP_USER_AGENT"];
88                 error_log("in git backend with user agent $agent");
89                 if(stristr($agent, "git")!==false) {
90                         $isgitagent = true;
91                 }
92         }
93         
94         
95                 
96         /* dont need this code right now
97         if($isgitagent) echo "GIT: i am a git backened interface for a repo $repo, agent $agent";
98         else echo "NOT GIT: i am a git backened interface for a repo $repo, agent $agent";
99         */
100         
101         // now we need to rebuild the actual request or do we?
102         //$basegit = "$BASE_URL/git/something.git";
103         //$newloc = preg_replace("/^$basegit/", "", $_SERVER["REQUEST_URI"]);
104         
105         if(file_exists("$repo_base/$repo/$newloc")) {
106                 error_log("would ask $repo,$actual_repo_name for $repo/$newloc from $repo_base/$repo/$newloc");
107                 $fh = fopen("$repo_base/$repo/$newloc", "rb");
108                 
109                 error_log("pushing file");
110                 while(!feof($fh)) {
111                         echo fread($fh, 8192);
112                 }
113         } else {
114                 echo "would ask $repo,$actual_repo_name for $repo/$newloc from $repo_base/$repo/$newloc, NE";
115                 header('HTTP/1.0 404 No Such Thing');
116                 return;
117         }
118 }
119
120
121
122 function gwvp_repoExists($name)
123 {
124         global $repo_base;
125         
126         if(file_exists("$repo_base/$name.git")) return true;
127         else return false;
128 }
129
130 function gwvp_createGitRepo($name, $bundle=null)
131 {
132         global $repo_base;
133         
134         // phew, this works, but i tell you this - bundles arent quite as nice as they should be
135         if($bundle == null) {
136                 error_log("would create $repo_base/$name.git");
137                 exec("/usr/bin/git init $repo_base/$name.git --bare > /tmp/gitlog 2>&1");
138                 chdir("$repo_base/$name.git");
139                 exec("/usr/bin/git update-server-info");
140         } else {
141                 error_log("create via mirror on $repo_base/$name.git");
142                 exec("/usr/bin/git clone --mirror $bundle $repo_base/$name.git > /tmp/gitlog 2>&1");
143                 chdir("$repo_base/$name.git");
144                 exec("/usr/bin/git update-server-info");
145         }
146         
147         return true;
148 }
149 ?>