cvsweb.php3 6.52 KB
Newer Older
1
<?php
Leigh B. Stoller's avatar
Leigh B. Stoller committed
2
3
#
# EMULAB-COPYRIGHT
4
# Copyright (c) 2000-2007 University of Utah and the Flux Group.
Leigh B. Stoller's avatar
Leigh B. Stoller committed
5
6
7
# All rights reserved.
#

8
9
10
11
12
#
# Wrapper script for cvsweb.cgi
#
chdir("../");
require("defs.php3");
13
include_once("template_defs.php");
14

15
16
17
unset($uid);
unset($repodir);

18
#
19
20
# We look for anon access, and if so, redirect to ops web server.
# WARNING: See the LOGGEDINORDIE() calls below.
21
#
22
23
24
if (($this_user = CheckLogin($check_status))) {
     $uid = $this_user->uid();
}
25
26
27

# Tell system we do not want any headers drawn on errors.
$noheaders = 1;
28

29
30
31
# Use cvsweb or viewvc.
$use_viewvc = 0;

32
33
34
#
# Verify form arguments.
#
35
36
37
38
39
40
41
42
43
44
$optargs = OptionalPageArguments("experiment", PAGEARG_EXPERIMENT,
				 "instance",   PAGEARG_INSTANCE,
				 "template",   PAGEARG_TEMPLATE,
				 "project",    PAGEARG_PROJECT,
				 "embedded",   PAGEARG_BOOLEAN);
if (!isset($embedded)) {
    $embedded = 0;
}

if (isset($project)) {
45
46
47
    if (!$CVSSUPPORT) {
	USERERROR("Project CVS support is not enabled!", 1);
    }
48
49
    $pid = $project->pid();
    
50
    # Redirect now, to avoid phishing.
51
52
    if ($this_user) {
	CheckLoginOrDie();
53
54
55
56
57
58
59
    }
    else {
	$url = $OPSCVSURL . "?cvsroot=$pid";
	
	header("Location: $url");
	return;
    }
60
    if (isset($experiment)) {
61
62
63
	#
	# Wants access to the experiment archive, which is really a repo.
	#
64
65
66
	$pid = $experiment->pid();
	$eid = $experiment->eid();
	
67
	if (! ISADMIN() &&
68
	    ! $experiment->AccessCheck($this_user, $TB_EXPT_READINFO)) {
69
70
71
	    USERERROR("Not enough permission to view '$pid/$eid'", 1);
	}
	# Get the repo index for the experiment.
72
	$query_result =
73
74
75
76
	    DBQueryFatal("select s.archive_idx from experiments as e ".
			 "left join experiment_stats as s on s.exptidx=e.idx ".
			 "where e.pid='$pid' and e.eid='$eid'");
	
77
	if (!mysql_num_rows($query_result)) {
78
79
80
81
82
	    TBERROR("Error getting repo index for '$pid/$eid'", 1);
	}
	$row = mysql_fetch_array($query_result);
	if (!isset($row[0])) {
	    TBERROR("Error getting repo index for '$pid/$eid'", 1);
83
	}
84
85
	$repoidx = $row[0];
	$repodir = "/usr/testbed/exparchive/$repoidx/repo/";
86
	$use_viewvc = 1;
87
88
89
90
91
    }
    else {
	#
	# Wants access to the project repo.
	#
92
	if (! ISADMIN() &&
93
	    ! $project->AccessCheck($this_user, $TB_PROJECT_READINFO)) {
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
            # Then check to see if the project cvs repo is public.
	    $query_result =
		DBQueryFatal("select cvsrepo_public from projects ".
			     "where pid='$pid'");
	    if (!mysql_num_rows($query_result)) {
		TBERROR("Error getting cvsrepo_public bit", 1);
	    }
	    $row = mysql_fetch_array($query_result);
	    if ($row[0] == 0) {
		USERERROR("You are not a member of Project $pid.", 1);
	    }
	}
	$repodir = "$TBCVSREPO_DIR/$pid";
    }
}
109
elseif (isset($experiment) || isset($instance) || isset($template)) {
110
111
112
113
114
    if (!$CVSSUPPORT) {
	USERERROR("Project CVS support is not enabled!", 1);
    }

    # Must be logged in for this!
115
116
    if ($this_user) {
	CheckLoginOrDie();
117
    }
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134

    if (isset($template)) {
	$experiment = $template->GetExperiment();
    }
    
    if (isset($instance)) {
	$pid = $instance->pid();
	$eid = $instance->eid();
	$idx = $instance->exptidx();
	$project = $instance->Project();
    }
    else {
	$pid = $experiment->pid();
	$eid = $experiment->eid();
	$idx = $experiment->idx();
	$project = $experiment->Project();
    }
135
136
137
138
    
    # Need the pid/eid/gid. Access the stats table since we want to provide
    # cvs access to terminated experiments via the archive.
    $query_result =
139
	DBQueryFatal("select s.archive_idx,a.archived ".
140
141
		     "   from experiment_stats as s ".
		     "left join archives as a on a.idx=s.archive_idx ".
142
		     "where s.exptidx='$idx'");
143
    if (!mysql_num_rows($query_result)) {
144
	USERERROR("Experiment '$idx' is not a valid experiment", 1);
145
146
    }
    $row = mysql_fetch_array($query_result);
147
148
    $repoidx  = $row[0];
    $archived = $row[1];
149

150
151
    # Lets do group level check since it might not be a current experiment.
    if (!$archived) {
152
	if (! ISADMIN() &&
153
154
	    ! $project->AccessCheck($this_user, $TB_PROJECT_READINFO)) {
	    USERERROR("Not enough permission to view archive", 1);
155
156
157
158
	}
	$repodir = "/usr/testbed/exparchive/$repoidx/repo/";
    }
    else {
159
	if (! ISADMIN()) {
160
	    USERERROR("Must be administrator to view historical archives!", 1);
161
	}
162
	$repodir = "/usr/testbed/exparchive/Archive/$repoidx/repo/";
163
    }
164
    $use_viewvc = 1;
165
166
}
else {
167
168
    $this_user = CheckLoginOrDie();
    if (! $this_user->cvsweb()) {
169
        USERERROR("You do not have permission to use cvsweb!", 1);
170
171
    }
    unset($pid);
172
173
174
175
176
177
178
179
}

$script = "cvsweb.cgi";

#
# Sine PHP helpfully scrubs out environment variables that we _want_, we
# have to pass them to env.....
#
180
181
182
183
184
185
$query = escapeshellcmd($_SERVER["QUERY_STRING"]);
$name = escapeshellcmd($_SERVER["SCRIPT_NAME"]);
$agent = escapeshellcmd($_SERVER["HTTP_USER_AGENT"]);
$encoding = escapeshellcmd($_SERVER["HTTP_ACCEPT_ENCODING"]);

# This is special ...
186
if (isset($_SERVER["PATH_INFO"]) && $_SERVER["PATH_INFO"] != "") {
187
188
189
190
191
    $path = escapeshellcmd($_SERVER["PATH_INFO"]);
}
else {
    $path = '/';
}
192
193

#
194
# Helpfully enough, escapeshellcmd does not escape spaces. Sigh.
195
196
197
198
199
200
201
#
$script = preg_replace("/ /","\\ ",$script);
$query = preg_replace("/ /","\\ ",$query);
$name = preg_replace("/ /","\\ ",$name);
$agent = preg_replace("/ /","\\ ",$agent);
$encoding = preg_replace("/ /","\\ ",$encoding);

202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
#
# A cleanup function to keep the child from becoming a zombie, since
# the script is terminated, but the children are left to roam.
#
$fp = 0;

function SPEWCLEANUP()
{
    global $fp;

    if (!$fp || !connection_aborted()) {
	exit();
    }
    while ($line = fgets($fp)) {
        # Suck it all up.
        ;
    }
    pclose($fp);
    exit();
}
set_time_limit(0);
register_shutdown_function("SPEWCLEANUP");

225
$shellcmd = "env PATH=./cvsweb/ QUERY_STRING=$query PATH_INFO=$path " .
226
            "SCRIPT_NAME=$name HTTP_USER_AGENT=$agent " .
227
228
            "HTTP_ACCEPT_ENCODING=$encoding ";

229
if (isset($repodir)) {
230
    $prog  = ($use_viewvc ? "webviewvc" : "webcvsweb");
231
    $embed = ($embedded ? "--embedded" : "");
232
    
233
234
    # I know, I added an argument to a script that is not supposed to
    # take any. So be it; it was easy.
235
    $shellcmd .= "$TBSUEXEC_PATH $uid $pid $prog $embed --repo=$repodir";
236
237
}
else {
238
    $shellcmd .= "$script";
239
240
}

241
242
243
#TBERROR(print_r($_SERVER, true), 0);
#TBERROR($shellcmd, 0);

244
$fp = popen($shellcmd, 'r');
245
246
247

#
# Yuck. Since we can't tell php to shut up and not print headers, we have to
248
# 'merge' headers from cvsweb with PHP's.
249
#
250
251
252
253
while ($line = fgets($fp)) {
    # This indicates the end of headers
    if ($line == "\r\n") { break; }
    header(rtrim($line));
254
255
}

256
#
257
# Just pass through the rest of cvsweb.cgi's output
258
#
259
260
261
fpassthru($fp);

fclose($fp);
262

263
?>