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

8
$login_user       = null;
9
$login_status     = CHECKLOGIN_NOTLOGGEDIN;
10
$drewheader       = 0;
11
$noheaders	  = 0;
12
$autorefresh      = 0;
13
$javascript_debug = 0;
14
$currentusage     = 1;
15
$currently_busy   = 0;
16
$sortedtables     = array();
17
$bodyclosestring  = "";
18
19
$navmenu          = null;
$navmenuopen      = FALSE;
20

21
22
23
24
25
26
#
# This has to be set so we can spit out http or https paths properly!
# Thats because browsers do not like a mix of secure and nonsecure.
# 
$BASEPATH	  = "";

Timothy Stack's avatar
   
Timothy Stack committed
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#
# Determine the proper basepath, which depends on whether the page
# was loaded as http or https. This lets us be consistent in the URLs
# we spit back, so that users do not get those pesky warnings. These
# warnings are generated when a page *loads* (say, images, style files),
# a mix of http and https. Links can be mixed, and in fact when there
# is no login active, we want to spit back http for the documentation,
# but https for the start/join pages.
#
if (isset($SSL_PROTOCOL)) {
    $BASEPATH = $TBBASE;
}
else {
    $BASEPATH = $TBDOCBASE;
}

# Blank space dividers in the menus are handled by adding a class to the menu
# item that starts a new group.
45
46
$nextnavbarcl     = null;
$nextsubmenucl    = null;
Timothy Stack's avatar
   
Timothy Stack committed
47

48
49
50
51
52
53
54
# Add a table id to the list of sorted tables to initialize on current page.
function AddSortedTable($id) {
    global $sortedtables;

    $sortedtables[] = $id;
}

55
#
56
57
# TOPBARCELL - Make a cell for the topbar. Actually, the name lies, it can be
# used for cells in a bottombar too.
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#
function TOPBARCELL($contents) {
    echo "<td class=\"topbaropt\">";
    echo "<span class=\"topbaroption\">&nbsp;";
    echo $contents;
    echo "&nbsp;</span>";
    echo "</td>";
    echo "\n";
}

#
# WRITETOPBARBUTTON(text, base, link): Write a button in the topbar
#
function WRITETOPBARBUTTON($text, $base, $link ) {
    $link = "$base/$link";
    TOPBARCELL("<a href=\"$link\">$text</a>");
}
# same as above with "new" gif next to it.
function WRITETOPBARBUTTON_NEW($text, $base, $link ) {
    $link = "$base/$link";
    TOPBARCELL("<a href=\"$link\">$text</a>&nbsp;<img src=\"/new.gif\" />");
}

81
#
82
# Start the primary navmenu.
83
#
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
function NavMenuStart() {
    global $navmenu, $login_user;

    if ($login_user) 
	$navmenu = new menuBar();
}

#
# Start a new navmenu section (a new dropdown menu).
#
function NavMenuSection($id, $title) {
    global $navmenu, $login_user, $navmenuopen;

    if ($login_user)
	$navmenu->addMenu($title, $id);
    else {
	if ($navmenuopen) {
	    echo "</ul>\n";
	}
	$navmenuopen = TRUE;
	STARTSIDEBARMENU($id, $title);
    }
}
function NavMenuSectionEnd() {
    global $navmenu, $login_user, $navmenuopen;

    if (! $login_user) {
	if ($navmenuopen) {
	    echo "</ul>\n";
	}
	$navmenuopen = FALSE;
    }
}

#
# Add a new button to the current dropdown menu.
# 
function NavMenuButton($text, $link = null, $extratext = null,
		       $target = null, $divider = FALSE, $mouseover = null)
{
    global $navmenu, $login_user;

    if ($login_user)
	$navmenu->addItem($link, $text, $target, $divider,
			  $extratext, $mouseover);
    else
	WRITESIDEBARBUTTON($text, $link, $extratext);
	
}
# Ditto, but with a new icon.
function NavMenuButtonNew($text, $link = null, $divider = FALSE)
{
    global $navmenu, $login_user;

    if ($login_user)
139
140
	NavMenuButton($text, $link, "&nbsp;<img src=\"/new.gif\">",
		      null, $divider);
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
    else
	WRITESIDEBARBUTTON($text, $link, "&nbsp;<img src=\"/new.gif\" />");
}
# Ditto, but with a divider
function NavMenuButtonDivider($text, $link = null)
{
    global $navmenu, $login_user;

    if ($login_user) 
	NavMenuButton($text, $link, null, null, TRUE);
    else {
	WRITESIDEBARDIVIDER();
	WRITESIDEBARBUTTON($text, $link);
    }
}

#
# Render the menu ...
# 
function NavMenuRender()
{
    global $navmenu, $navmenuopen, $BASEPATH, $TBBASE, $login_user;

    if (!$login_user) {
	if ($navmenuopen)
	    echo "</ul>\n";
	$navmenuopen = FALSE;
	return;
    }

    $navmenu->writeMenuBar();
}

#
# STARTSIDEBARMENU(). Start a menu section.
#
function STARTSIDEBARMENU($id, $title, $visible = true) {
    $arrow = "";
    $class = "navmenu";
    if (0) {
	$png   = ($visible ? 'menu-expanded.png' : 'menu-collapsed.png');
	$class = ($visible ? 'navmenu' : 'navmenu-collapsed');
	$arrow = "<img class=menuarrow src='$png' ".
	    "onclick=\"return toggle_menu('${id}_list', '${id}_arrow');\" ".
	    "id='${id}_arrow'>";
    }
    echo "<h3 class='menuheader' id='${id}_header'>$arrow $title</h3>";
    echo "<ul class='$class' id='${id}_list'>\n";
189
190
}

191
192
193
194
195
#
# WRITESIDEBARBUTTON(text, link): Write a button on the sidebar menu.
# We do not currently try to match the current selection so that its
# link looks different. Not sure its really necessary.
#
196
function WRITESIDEBARBUTTON($text, $link, $extratext="") {
Timothy Stack's avatar
   
Timothy Stack committed
197
198
199
200
201
202
203
204
    global $nextsidebarcl;
    
    $cl = "";
    if ($nextsidebarcl != "") {
	$cl = "class='$nextsidebarcl'";
	$nextsidebarcl = "";
    }
    echo "<li $cl><a href=\"$link\">$text</a>$extratext</li>\n";
Chad Barb's avatar
   
Chad Barb committed
205
}
206

Chad Barb's avatar
   
Chad Barb committed
207
# same as above with "new" gif next to it.
Timothy Stack's avatar
   
Timothy Stack committed
208
209
210
211
212
function WRITESIDEBARBUTTON_NEW($text, $base, $link) {
    WRITESIDEBARBUTTON($text,
		       $base,
		       $link,
		       "&nbsp;<img src=\"/new.gif\" />");
Chad Barb's avatar
   
Chad Barb committed
213
214
215
216
}

# writes a message to the sidebar, without clickability.
function WRITESIDEBARNOTICE($text) {
Timothy Stack's avatar
   
Timothy Stack committed
217
    echo "<span class='notice'>$text</span>\n";
218
219
220
221
222
223
224
225
226
}

#
# Something like the sidebar, but across the top, with only a few options.
# Think Google. For PlanetLab users, but it would be easy enough to make
# others. Still a work in progress.
#
function WRITEPLABTOPBAR() {
    echo "<table class=\"topbar\" width=\"100%\" cellpadding=\"2\" cellspacing=\"0\" align=\"center\">\n";
227
    global $login_status, $login_user;
228
229
230
    global $TBBASE, $TBDOCBASE, $BASEPATH;
    global $THISHOMEBASE;

231
232
    WRITETOPBARBUTTON("Create a Slice",
        $TBBASE, "plab_ez.php3");
233

234
    WRITETOPBARBUTTON("Nodes",
235
236
237
        $TBBASE, "plabmetrics.php3");

    WRITETOPBARBUTTON("My Testbed",
238
		      $TBBASE, CreateURL("showuser", $login_user));
239
240

    WRITETOPBARBUTTON("Advanced Experiment",
241
        $TBBASE, "beginexp_html.php3");
242

243
244
    if ($login_status & CHECKLOGIN_TRUSTED && $login_user->ApprovalList(0)) {
	WRITESIDEBARBUTTON_NEW("Approve Users",
245
246
247
248
249
250
			       $TBBASE, "approveuser_form.php3");
    }

    WRITETOPBARBUTTON("Log Out", $TBBASE, "logout.php3?next_page=" .
	urlencode($TBBASE . "/login_plab.php3"));

251
252
253
    echo "</table>\n";
    echo "<br>\n";

254
255
}

256
257
258
259
260
261

#
# Put a few things that PlanetLab users should see, but are non-essential,
# across the bottom of the page rather than the top
#
function WRITEPLABBOTTOMBAR() {
262
    global $login_status, $login_user;
263
264
265
    global $TBBASE, $TBDOCBASE, $BASEPATH;
    global $THISHOMEBASE;

266
    if ($login_user) {
267
268
269
270
271
272
	$newsBase = $TBBASE; 
    } else {
	$newsBase = $TBDOCBASE;
    }

    echo "
273
274
275
	   <center>
	   <br>
	   <font size=-1>
276
	   <form method=get action=$TBDOCBASE/search.php3>
277
278
279
280
	   [ <a href='$TBDOCBASE/doc.php3'>
		Documentation</a> : <input name=query size = 15/>
		  <input type=submit style='font-size:10px;' value='Search' /> ]
	   [ <a href='$newsBase/news.php3'>
281
		News</a> ]
282
283
284
285
	   </form>
	   </font>
	   <br>
	   </center>\n";
286
287
288

}

289
290
291
292
293
#
# WRITESIDEBAR(): Write the menu. The actual menu options the user
# sees depends on the login status and the DB status.
#
function WRITESIDEBAR() {
294
    global $login_status, $login_user, $pid, $gid;
295
    global $TBBASE, $TBDOCBASE, $BASEPATH, $WIKISUPPORT, $MAILMANSUPPORT;
296
    global $BUGDBSUPPORT, $BUGDBURL, $CVSSUPPORT, $CHATSUPPORT, $TRACSUPPORT;
297
    global $CHECKLOGIN_WIKINAME, $TBMAINSITE;
298
    global $THISHOMEBASE;
299
    global $EXPOSETEMPLATES;
300
    global $currentusage, $FANCYBANNER, $ELABINELAB, $PLABSUPPORT;
301
    $firstinitstate = TBGetFirstInitState();
302

Chad Barb's avatar
   
Chad Barb committed
303
304
305
306
307
308
309
310
    #
    # get post time of most recent news;
    # get both displayable version and age in days.
    #
    $query_result = 
	DBQueryFatal("SELECT DATE_FORMAT(date, '%M&nbsp;%e') AS prettydate, ".
		     " (TO_DAYS(NOW()) - TO_DAYS(date)) AS age ".
		     "FROM webnews ".
311
		     "WHERE archived=0 ".
Chad Barb's avatar
   
Chad Barb committed
312
313
314
315
316
317
318
319
		     "ORDER BY date DESC ".
		     "LIMIT 1");
    $newsDate = "";
    $newNews  = 0;

    #
    # This is so an admin can use the editing features of news.
    #
320
    if ($login_user) {
Chad Barb's avatar
   
Chad Barb committed
321
322
323
324
325
326
	$newsBase = $TBBASE; 
    } else {
	$newsBase = $TBDOCBASE;
    }

    if ($row = mysql_fetch_array($query_result)) {
327
328
	$newsDate = "(".$row["prettydate"].")";
	if ($row["age"] < 7) {
Chad Barb's avatar
   
Chad Barb committed
329
330
331
332
	    $newNews = 1;
	}
    }

333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
    if ($login_user) {
	echo "<td>\n";
	echo "<div class='midtopcell'>\n";
	echo "<!-- main navigation menu begins -->\n";

	echo "<table id='navmenus' cellspacing='0' cellpadding='0'>".
	    "<tr><td>\n";

	# Logout option on first row.
	if ($login_status & (CHECKLOGIN_LOGGEDIN|CHECKLOGIN_MAYBEVALID)) {
	    echo "<a class=midtopcell ".
		"href='$TBBASE/" . CreateURL("showuser", $login_user) . "'>".
		"My Emulab</a>\n";

	    echo " <font color=grey>|</font> ";

            # Logout option. No longer take up space with an image.
	    echo "<a class=midtopcell ".
		"href='$TBBASE/" . CreateURL("logout", $login_user) . "'>".
		"Logout</a>\n";
	    
	    echo " <font color=grey>|</font> ";

	    # News
	    echo "<a class=midtopcell ".
		"href='$newsBase/news.php3'>News</a>";
	    if ($newNews) {
		echo "&nbsp;<img src=\"/new.gif\">\n";
	    }
	    
	    echo " <font color=grey>|</font> ";

	    echo "<a class=midtopcell href='$TBBASE/emailus.php3'>".
		"Contact Us</a>\n";

	    if (ISADMINISTRATOR()) {
		echo " <font color=grey>|</font> ";

		if (ISADMIN()) {
		    $url = CreateURL("toggle", $login_user,
				     "type", "adminon", "value", 0);
		
		    echo "<a href=\"$TBBASE/$url\">
                             <img src='/redball.gif'
                                  border='0' alt='Admin On'></a>\n";
		}
		else {
		    $url = CreateURL("toggle", $login_user,
				     "type", "adminon", "value", 1);

		    echo "<a href=\"$TBBASE/$url\">
                              <img src='/greenball.gif'
                                   border='0' alt='Admin Off'></a>\n";
		}
	    }
        }
        # The search box.
	echo "<span id='topcellsearchrow'>";
	echo "<table id='topcellsearchtable' cellspacing='0' cellpadding='0'>";
	echo "<form method='get' action='$newsBase/search.php3'>";
	echo "<tr><td>";
	echo "<input class='textInputEmpty' name='query'
                     value='Search Documentation' id='searchbox'
                     onfocus='focus_text(this, \"Search Documentation\")'
                     onblur='blur_text(this, \"Search Documentation\")' />";
	echo "</td><td>";
	echo "<input type='submit' id='searchsub' value=Go />";
	echo "</td></tr>";
        echo "</form>";
        echo "</table>";
	echo "</span>";
	echo "</td></tr>";
	# Extra row to force two rows to top and bottom of midtopcell.
	# See height value for tr/td in the style file.
Leigh B. Stoller's avatar
Leigh B. Stoller committed
407
	echo "<tr id=spacer><td id=spacer></td></tr>";
408
409
410
411
412
413
	echo "<tr><td>";
    }
   
    NavMenuStart();
    NavMenuSection("information", "Information");
    NavMenuButton("Home", "$TBDOCBASE/index.php3?stayhome=1");
414

Chad Barb's avatar
   
Chad Barb committed
415
416
417
418
419
420
    if (0 == strcasecmp($THISHOMEBASE, "emulab.net")) {
	$rootEmulab = 1;
    } else {
	$rootEmulab = 0;
    }
    if ($rootEmulab) {
421
422
	NavMenuButton("Other Emulabs", 
		      "$TBDOCBASE/docwrapper.php3?docname=otheremulabs.html");
Chad Barb's avatar
   
Chad Barb committed
423
    } else {
424
	NavMenuButton("Utah Emulab", "http://www.emulab.net/");
Chad Barb's avatar
   
Chad Barb committed
425
    }
Chad Barb's avatar
   
Chad Barb committed
426

Chad Barb's avatar
   
Chad Barb committed
427
    if ($newNews) {
428
	NavMenuButtonNew("News $newsDate", "$newsBase/news.php3");
Chad Barb's avatar
   
Chad Barb committed
429
    } else {
430
	NavMenuButton("News $newsDate", "$newsBase/news.php3");
Chad Barb's avatar
   
Chad Barb committed
431
432
    }

433
    NavMenuButton("Documentation", "$TBDOCBASE/doc.php3");
Chad Barb's avatar
   
Chad Barb committed
434
435

    if ($rootEmulab) {
436
	# Leave New here about 2 weeks
Jay Lepreau's avatar
Jay Lepreau committed
437
438
        NavMenuButton("Papers and Talks (Jun 4)", "$TBDOCBASE/pubs.php3");
	NavMenuButtonNew("Emulab Software (Jun 26)", "$TBDOCBASE/software.php3");
439
440
441
442
443
444
445
446
447
448
449
450

	NavMenuButton("List People",
		      "$TBDOCBASE/people.php3");
	NavMenuButton("Photo Gallery",
		      "$TBDOCBASE/gallery/gallery.php3");
	NavMenuButton("Emulab Users",
		      "$TBDOCBASE/doc/docwrapper.php3?docname=users.html");
	NavMenuButton("Emulab Sponsors",
		      "$TBDOCBASE/docwrapper.php3?docname=sponsors.html");
    }
    else {
	NavMenuButton("Projects on Emulab", "$TBDOCBASE/projectlist.php3");
Chad Barb's avatar
   
Chad Barb committed
451
    }
Timothy Stack's avatar
   
Timothy Stack committed
452
453
454

    # The search box.  Placed in a table so the text input fills available
    # space.
455
456
457
    if (! $login_user) {
	NavMenuSectionEnd();
	echo "<div id='searchrow'>
458
459
460
        <form method='get' action='$newsBase/search.php3'>
        <table border='0' cellspacing='0' cellpadding='0'><tr>
             <td width='100%'><input class='textInputEmpty' name='query'
461
462
463
464
465
                        value='Search Documentation' id='searchbox'
                        onfocus='focus_text(this, \"Search Documentation\")'
                        onblur='blur_text(this, \"Search Documentation\")' />
               </td>
	     <td><input type='submit' id='searchsub' value=Go /></td>
Timothy Stack's avatar
   
Timothy Stack committed
466
467
468
        </table>
        </form>
	</div>\n";
469
470
    }
    
471
472
473
474
475
476
    #
    # Cons up a nice message.
    # 
    switch ($login_status & CHECKLOGIN_STATUSMASK) {
    case CHECKLOGIN_LOGGEDIN:
	if ($login_status & CHECKLOGIN_PSWDEXPIRED)
Timothy Stack's avatar
   
Timothy Stack committed
477
	    $login_message = "(Password Expired!)";
478
	elseif ($login_status & CHECKLOGIN_UNAPPROVED)
Timothy Stack's avatar
   
Timothy Stack committed
479
480
481
	    $login_message = "(Unapproved!)";
	else
	    $login_message = 0;
482
483
484
485
486
487
488
489
490
491
	break;
    case CHECKLOGIN_TIMEDOUT:
	$login_message = "Login Timed out.";
	break;
    default:
	$login_message = 0;
	break;
    }

    #
Timothy Stack's avatar
   
Timothy Stack committed
492
    # Now the login box.
493
    # We want the links to the login pages to always be https,
494
495
496
    # but the images path depends on whether the page was loaded as
    # http or https, since we do not want to mix them, since they
    # cause warnings.
497
498
499
    #
    if (! ($login_status & (CHECKLOGIN_LOGGEDIN|CHECKLOGIN_MAYBEVALID)) &&
	!NOLOGINS()) {
Timothy Stack's avatar
   
Timothy Stack committed
500
501
502
503
504
	echo "<div id='loginbox'>";

	if ($login_message) {
	    echo "<strong>$login_message</strong>";
	}
505
506
507
508

	if (!$firstinitstate) {
	    echo "<a href=\"$TBBASE/reqaccount.php3\">";
	    echo "<img alt=\"Request Account\" border=0 ";
509
	    echo "src=\"$BASEPATH/requestaccount.gif\" width=\"144\" height=\"32\"></a>";
510

Timothy Stack's avatar
   
Timothy Stack committed
511
	    echo "<strong>or</strong>";
512
513
514
515
	}

	echo "<a href=\"$TBBASE/login.php3\">";
	echo "<img alt=\"logon\" border=0 ";
516
	echo "src=\"$BASEPATH/logon.gif\" width=\"144\" height=\"32\"></a>\n";
517

Timothy Stack's avatar
   
Timothy Stack committed
518
	echo "</div>";
519
520
521
522
523
524
525
        #
        # Login message. Set via 'web/message' site variable
        #
        $message = TBGetSiteVar("web/message");
        if (0 != strcmp($message,"")) {
	    WRITESIDEBARNOTICE($message);
	}
526
527
    }

528
529
530
531
    #
    # Basically, we want to let admin people continue to use
    # the web interface even when nologins set. But, we want to make
    # it clear its disabled.
532
533
    #
    if (!$login_user && NOLOGINS()) {
Timothy Stack's avatar
   
Timothy Stack committed
534
535
	echo "<a id='webdisabled' href='$TBDOCBASE/nologins.php3'>".
	    "Web Interface Temporarily Unavailable</a>";
536
	WRITESIDEBARNOTICE("Please Try Again Later");
537
538
539
540
541
	
        $message = TBGetSiteVar("web/message");
        if ($message != "") {
	    WRITESIDEBARNOTICE($message);
	}
Timothy Stack's avatar
   
Timothy Stack committed
542
543
544
545
    }

    # Start Interaction section if going to spit out interaction options.
    if ($login_status & (CHECKLOGIN_LOGGEDIN|CHECKLOGIN_MAYBEVALID)) {
546
	NavMenuSection("experimentation", "Experimentation");
547
    }
Chad Barb's avatar
   
Chad Barb committed
548

549
    if ($login_status & (CHECKLOGIN_LOGGEDIN|CHECKLOGIN_MAYBEVALID)) {
550
551
	if ($firstinitstate != null) {    
	    if ($firstinitstate == "createproject") {
Russ Fish's avatar
Russ Fish committed
552
		NavMenuButton("<font color=red> Create First Project </font>&nbsp",
553
			      "$TBBASE/newproject.php3");
554
555
556
557
	    }
	    elseif ($firstinitstate == "approveproject") {
		$firstinitpid = TBGetFirstInitPid();
		
558
559
560
		NavMenuButton("Approve First Project",
			      "$TBBASE/approveproject.php3?pid=$firstinitpid".
			      "&approval=approve");
561
562
563
	    }
	}
	elseif ($login_status & CHECKLOGIN_ACTIVE) {
564
	    if ($login_status & CHECKLOGIN_PSWDEXPIRED) {
565
566
		NavMenuButton("Change Your Password",
			      "$TBBASE/moduserinfo.php3");
567
	    }
Leigh B. Stoller's avatar
Leigh B. Stoller committed
568
	    elseif ($login_status & (CHECKLOGIN_WEBONLY|CHECKLOGIN_WIKIONLY)) {
569
570
571
		if ($WIKISUPPORT && $CHECKLOGIN_WIKINAME != "") {
		    $wikiname = $CHECKLOGIN_WIKINAME;
		
572
573
		    NavMenuButton("My Wikis",
				  "gotowiki.php3?redurl=Main/$wikiname");
574
		}
575
576
577
		NavMenuButton("Update User Information",
			      "$TBBASE/" .
			         CreateURL("moduserinfo", $login_user));
578
	    }
579
	    else {
580
581
		NavMenuButton("My Emulab",
			      "$TBBASE/" . CreateURL("showuser", $login_user));
582

583
		#
584
585
586
587
                # Since a user can be a member of more than one project,
                # display this option, and let the form decide if the 
                # user is allowed to do this.
                #
588
589
 		NavMenuButton("Begin an Experiment",
			      "$TBBASE/beginexp_html.php3");
590
591

		if ($EXPOSETEMPLATES) {
592
593
		    NavMenuButton("Create a Template",
				  "$TBBASE/template_create.php");
594
		}
595
596
597
598
599
600

		if ($PLABSUPPORT) {
                    # Put _NEW back when Plab is working again.
		    NavMenuButton("Create a PlanetLab Slice",
				  "$TBBASE/plab_ez.php3");
		}
601

602
		NavMenuButton("Experiment List", "$TBBASE/showexp_list.php3");
603

604
605
606
607
608
		NavMenuButtonDivider("Node Status",
				     "$TBBASE/nodecontrol_list.php3");

		NavMenuButton("List ImageIDs",
			      "$TBBASE/showimageid_list.php3");
609

610
611
		NavMenuButton("List OSIDs",
			      "$TBBASE/showosid_list.php3");
612

613
614
		if ($login_status & CHECKLOGIN_TRUSTED &&
		    $login_user->ApprovalList(0)) {
615
616
617
		    # This includes a divider argument.
		    NavMenuButtonNew("New User Approval",
				     "$TBBASE/approveuser_form.php3", TRUE);
618
		}
619
	    }
620
	}
621
	elseif ($login_status & (CHECKLOGIN_UNVERIFIED|CHECKLOGIN_NEWUSER)) {
622
623
624
625
	    NavMenuButton("New User Verification",
			  "$TBBASE/verifyusr_form.php3");
	    NavMenuButton("Update User Information",
			  "$TBBASE/" . CreateURL("moduserinfo", $login_user));
626
	}
627
	elseif ($login_status & (CHECKLOGIN_UNAPPROVED)) {
628
629
	    NavMenuButton("Update User Information",
			  "$TBBASE/" . CreateURL("moduserinfo", $login_user));
630
	}
631
632
	#
	# Standard options for logged in users!
633
634
	#
	if (!$firstinitstate) {
635
636
637
638
	    NavMenuButtonDivider("Start New Project",
				 "$TBBASE/newproject.php3");
	    NavMenuButton("Join Existing Project",
			  "$TBBASE/joinproject.php3");
639
	}
640
    }
Chad Barb's avatar
Chad Barb committed
641

642
    # And now the Collaboration menu.
Leigh B. Stoller's avatar
Leigh B. Stoller committed
643
644
645
    if (($login_status & (CHECKLOGIN_LOGGEDIN|CHECKLOGIN_MAYBEVALID)) &&
	($WIKISUPPORT || $MAILMANSUPPORT || $BUGDBSUPPORT ||
	 $CVSSUPPORT  || $CHATSUPPORT)) {
646
647

	NavMenuSection("collaboration", "Collaboration");
Timothy Stack's avatar
   
Timothy Stack committed
648

649
650
651
	if ($WIKISUPPORT && $CHECKLOGIN_WIKINAME != "") {
	    $wikiname = $CHECKLOGIN_WIKINAME;
		
652
653
	    NavMenuButton("My Wikis",
			  "$TBBASE/gotowiki.php3?redurl=Main/$wikiname");
654
	}
655
656
	if ($MAILMANSUPPORT || $BUGDBSUPPORT) {
	    if (!isset($pid) || $pid == "") {
657
658
		if (($project = $login_user->FirstApprovedProject())) {
		    $firstpid = $project->pid();
659
660
661
662
		}
	    }
	}
	if ($MAILMANSUPPORT) {
663
664
	     NavMenuButton("My Mailing Lists",
			   "$TBBASE/" . CreateURL("showmmlists", $login_user));
665
666
667
668
669
670
671
672
673
674
	}
	if ($BUGDBSUPPORT) {
	    $bugdburl = "gotobugdb.php3";
		    
	    if (isset($pid) && !empty($pid)) {
		$bugdburl .= "?project_title=$pid";
	    }
	    elseif (isset($firstpid)) {
		$bugdburl .= "?project_title=$firstpid";
	    }
675
	    NavMenuButton("My Bug Databases", "$TBBASE/$bugdburl");
676
677
	}
	if ($CVSSUPPORT) {
678
679
	    NavMenuButton("My CVS Repositories",
			  "$TBBASE/" . CreateURL("listrepos", $login_user));
680
	}
681
	if ($CHATSUPPORT) {
682
683
	    NavMenuButton("My Chat Buddies",
			  "$TBBASE/" . CreateURL("mychat", $login_user));
684
	}
685
686
687
688
689
690
	if ($TBMAINSITE && $TRACSUPPORT) {
	    $geniproject = Project::Lookup("geni");
	    $approved    = 0;
	    
	    if ($geniproject &&
		$geniproject->IsMember($login_user, $approved) && $approved) {
Leigh B. Stoller's avatar
Leigh B. Stoller committed
691
		NavMenuButton("ProtoGENI Trac Wiki",
692
693
694
695
696
697
698
			      "$TBBASE/" . CreateURL("gototrac", $login_user,
						     "wiki", "geni"));
	    }
	    if (STUDLY()) {
		NavMenuButton("Emulab Trac Wiki",
			      "$TBBASE/" . CreateURL("gototrac", $login_user,
						     "wiki", "emulab"));
699
	    }
700
	}
701
    }
702

703
    # Optional ADMIN menu.
704
    if ($login_status & CHECKLOGIN_LOGGEDIN && ISADMIN()) {
705
	NavMenuSection("administration", "Administration");
706
	
707
708
709
710
	NavMenuButton("List Projects",
		      "$TBBASE/showproject_list.php3");
	NavMenuButton("List Users",
		      "$TBBASE/showuser_list.php3");
711

712
713
	NavMenuButton("View Testbed Stats",
		      "$TBBASE/showstats.php3");
714

715
716
	NavMenuButton("Approve New Projects",
		      "$TBBASE/approveproject_list.php3");
717

718
719
	NavMenuButton("Edit Site Variables",
		      "$TBBASE/editsitevars.php3");
720

721
722
	NavMenuButton("Edit Knowledge Base",
		      "$TBBASE/kb-manage.php3");
723
724
725
		    
	$query_result = DBQUeryFatal("select new_node_id from new_nodes");
	if (mysql_num_rows($query_result) > 0) {
726
727
	    NavMenuButtonNew("Add Testbed Nodes",
			     "$TBBASE/newnodes_list.php3");
728
729
	}
	else {
730
731
	    NavMenuButtonNew("Add Testbed Nodes",
			     "$TBBASE/newnodes_list.php3");
732
	}
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
	NavMenuButtonNew("Approve Widearea User",
			 "$TBBASE/approvewauser_form.php3");
    }
    if (0 && $login_user) {
	NavMenuSection("Status", "Status");
	
	$freepcs = TBFreePCs();
	$reload  = TBReloadingPCs();
	$users   = TBLoggedIn();
	$active  = TBActiveExperiments();
	NavMenuButton("Status",
		      "$TBBASE/nodecontrol_list.php3",
		      null, null, FALSE,
		      "$freepcs Free PCs, $reload PCs reloading<br> ".
		      "$users users logged in, $active active experiments");
    }
    # Terminate Interaction menu and render.
    NavMenuRender();
    
    if ($login_user) {
	echo "</td></tr></table>\n";
	
	# Close up div at start of navmenu
	echo "</div>\n";
	echo "</td>\n";
758
    }
759
760
}

761
762
763
764
765
766
#
# Simple version of above, that just writes the given menu.
# 
function WRITESIMPLESIDEBAR($menudefs) {
    $menutitle = $menudefs['title'];
    
Timothy Stack's avatar
   
Timothy Stack committed
767
    echo "<h3 class='menuheader'>$menutitle</h3>
768
          <ul class='navmenu'>";
769
770
771
772
773

    each($menudefs);    
    while (list($key, $val) = each($menudefs)) {
	WRITESIDEBARBUTTON("$key", null, "$val");
    }
Timothy Stack's avatar
   
Timothy Stack committed
774
    echo "</ul>\n";
775
776
}

Chad Barb's avatar
   
Chad Barb committed
777
778
779
#
# spits out beginning part of page
#
780
781
function PAGEBEGINNING( $title, $nobanner = 0, $nocontent = 0,
        $extra_headers = NULL ) {
782
    global $BASEPATH, $TBMAINSITE, $THISHOMEBASE, $ELABINELAB, $FANCYBANNER;
Chad Barb's avatar
Chad Barb committed
783
    global $TBDIR, $WWW;
Chad Barb's avatar
   
Chad Barb committed
784
    global $MAINPAGE;
785
    global $TBDOCBASE;
786
    global $autorefresh, $currentusage, $javascript_debug, $login_user;
Chad Barb's avatar
   
Chad Barb committed
787

788
789
    $MAINPAGE = !strcmp($TBDIR, "/usr/testbed/");

Chad Barb's avatar
   
Chad Barb committed
790
791
792
793
794
    echo "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 
          'http://www.w3.org/TR/html4/loose.dtd'>
	<html>
	  <head>
	    <title>$THISHOMEBASE - $title</title>
795
            <link rel=\"shortcut icon\" href=\"$BASEPATH/favicon.ico\" TYPE=\"image/vnd.microsoft.icon\">
796
            <link rel=\"search\" type=\"application/opensearchdescription+xml\" title=\"$THISHOMEBASE Search\" href=\"emusearch.xml\">
Chad Barb's avatar
   
Chad Barb committed
797
    	    <!-- dumbed-down style sheet for any browser that groks (eg NS47). -->
798
	    <link rel='stylesheet' href='$BASEPATH/common-style.css' type='text/css' />
799
800
    	    <!-- do not import full style sheet into NS47, since it does bad job
            of handling it. NS47 does not understand '@import'. -->
Chad Barb's avatar
   
Chad Barb committed
801
    	    <style type='text/css' media='all'>
802
            <!-- @import url($BASEPATH/style.css); -->
803
            <!-- @import url($BASEPATH/cssmenu-new.css); -->";
804
    
805
    if (1 && !$MAINPAGE) {
Timothy Stack's avatar
   
Timothy Stack committed
806
	echo "<!-- @import url($BASEPATH/style-nonmain.css); -->";
807
    }
Leigh B. Stoller's avatar
Leigh B. Stoller committed
808
    echo "</style>\n";
809
810
    echo "<!-- [if gt IE 6.0]><style type=\"text/css\">".
	".menu ul li a:hover ul { top: 18px; }</style><![endif]> -->\n";
Chad Barb's avatar
   
Chad Barb committed
811
812

    if ($TBMAINSITE) {
813
814
	echo "<meta name=\"keywords\" ".
	           "content=\"network, emulation, internet, emulator, ".
Leigh B. Stoller's avatar
Leigh B. Stoller committed
815
	           "mobile, wireless, robotic\">\n";
816
817
818
819
	echo "<meta name=\"robots\" ".
	           "content=\"NOARCHIVE\">\n";
	echo "<meta name=\"description\" ".
                   "content=\"emulab - network emulation testbed home\">\n";
Leigh B. Stoller's avatar
Leigh B. Stoller committed
820
    }
821
822
823
    if ($extra_headers) {
        echo $extra_headers;
    }
824
825
826
827
    if ($javascript_debug) {
	echo "<script type='text/javascript'
                      src='${BASEPATH}/js/inline-console.js'></script>\n";
    }
828
    echo "</head><body>\n";
829
830
    
    if ($autorefresh) {
831
	echo "<meta HTTP-EQUIV=\"Refresh\" content=\"$autorefresh\">\n";
832
    }
833
834
    echo "<script type='text/javascript' language='javascript'
                  src='${BASEPATH}/emulab_sup.js'></script>\n";
835
836
    echo "<script type='text/javascript' language='javascript'
                  src='${BASEPATH}/sorttable.js'></script>\n";
837
838
    echo "<script type='text/javascript' language='javascript'
                  src='${BASEPATH}/textbox.js'></script>\n";
839

840
    if (!$nobanner) {
841
842
843
844
845
        #
        # We do the banner differently for the Utah site and other sites.
        # The process of generating the fancy Utah banner is kind of 
        # complicated
        #
846
847
848
849
850
851
852
853
854
855
856
	if ($login_user) {
		echo "<div class='topcell'>\n";
	}
	else {
	    if ($FANCYBANNER) {
		echo "<div id='fancybannercell'>\n";
	    }
	    else {
		echo "<div id='bannercell'>\n";
	    }
	}
857
858
859

        # NOTE: This has to come before any images in the div for the float to
        # work correctly.
860
861
862
863
864
865
866
	if ($currentusage && !$login_user) {
	    if ($FANCYBANNER) {
		$class = "transparentusageframe";
	    }
	    else {
		$class = "usageframe";
	    }
867
	    echo "<iframe src='$BASEPATH/currentusage.php3' class='$class'
868
                          scrolling='no' frameborder='0'></iframe>\n";
869
	}
870
871
872
873
874
875
876
877
878
879
880
881
882
	if ($login_user) {
	    #
	    # It is a violation of Emulab licensing restrictions to remove
	    # this logo!
            #
            # NOTE: This has to come before any images in the div for the
	    # float to work correctly.
	    #
	    if (!$TBMAINSITE) {
		echo "<a class='rightsidebuiltwith' ".
		    "href='http://www.emulab.net'>";
		echo "<img src='$BASEPATH/fancy-builtwith.png'></a>\n";
	    }
883
884
885
	    echo "<table id=topcelltable ".
		     "cellspacing=0 cellpadding=0 border=0><tr>";
	    
886
887
888
889
890
	    echo "<td>\n";
	    echo "<a id='topcellimage' href='$TBDOCBASE/index.php3'>";
	    echo "<img border='0' ";
	    echo "alt='$THISHOMEBASE - the network testbed' ";
	    if ($FANCYBANNER)
891
892
		echo "src='$BASEPATH/fancy-sheader-" .
		    strtolower($THISHOMEBASE) . ".png' ";
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
	    elseif ($ELABINELAB) {
		echo "height='54' ";
		echo "src='$BASEPATH/overlay.elabinelab.gif' ";
	    }
	    else {
		echo "height='54' ";
		echo "src='$BASEPATH/overlay." .
			strtolower($THISHOMEBASE) . ".gif' ";
	    }
	    echo "></a>\n";
	    echo "</td>\n";
	}
	else {
	    if ($FANCYBANNER) {
		echo "<a href='$TBDOCBASE/index.php3'>
908
909
910
911
912
913
                        <img height='100px' width='365px' border='0' ";
		echo "src='$BASEPATH/fancy-header-" .
			strtolower($THISHOMEBASE) . ".png' ";
		echo "></a>\n";
	    }
	    else {
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
		echo "<map name='overlaymap'>
                         <area shape=\"rect\" coords=\"100,60,339,100\"
                               href='http://www.emulab.net/index.php3'>
                         <area shape=\"rect\" coords=\"0,0,339,100\"
                               href='$TBDOCBASE/index.php3'>
                      </map>\n";
		echo "<img height='100' border='0' usemap=\"#overlaymap\" ";
		if ($ELABINELAB) {
		    echo "width='239' ";
		    echo "src='$BASEPATH/overlay.elabinelab.gif' ";
		}
		else {
		    echo "width='339' ";
		    echo "src='$BASEPATH/overlay." .
			strtolower($THISHOMEBASE) . ".gif' ";
		}
		echo "alt='$THISHOMEBASE - the network testbed'>\n";
931
            }
932
933
934
935
936
937
938
	}
        if (!$login_user) 
	    echo "</div>\n";
    }
    else {
	# Need this to force no top margin/padding. No idea why! 
	echo "<div id='nobannercell'></div>\n";
939
940
    }
    if (! $nocontent ) {
941
942
943
944
945
946
947
	if ($login_user) {
	    ;
	}
	else {
	    echo "<div class='leftcell'>\n";
	    echo "<!-- sidebar begins -->\n";
	}
Chad Barb's avatar
   
Chad Barb committed
948
    }
Chad Barb's avatar
   
Chad Barb committed
949
950
951
952
953
}

#
# finishes sidebar td
#
954
function FINISHSIDEBAR($nocontent = 0)
Chad Barb's avatar
   
Chad Barb committed
955
{
956
    global $TBMAINSITE, $TBBASE, $BASEPATH, $currentusage, $login_user;
957
958
959
960
961
962
963

    if (!$nocontent) {
	if (!$TBMAINSITE) {
	    #
	    # It is a violation of Emulab licensing restrictions to remove
	    # this logo!
	    #
964
965
966
967
	    if (!$login_user) {
		echo "       <a class='builtwith' href='http://www.emulab.net'>
                             <img src='$BASEPATH/builtwith.png'></a>";
	    }
968
	}
969
970
971
	if ($currentusage && $login_user) {
	    $class = "navbarusageframe";
	    echo "<td>\n";
972
	    if (0) {
973
		echo "<iframe src='$BASEPATH/currentusage.php3' class='$class'
974
                              scrolling='no' frameborder='0'></iframe>\n";
975
976
	    }
	    else {
977
978
979
980
		echo "<div onclick=\"ToggleUsageTable();\" ".
		     "onmouseover='return escape(\"Click to toggle mode\")' ".
		     "id=usagefreenodes>\n";
		echo "</div>\n";
981
	    }
982
	    echo "</td></tr></table>\n";
983
	}
984
985
	echo "<!-- sidebar ends -->
              </div>";
986
    }
Chad Barb's avatar
   
Chad Barb committed
987
988
}

989
990
991
#
# Spit out a vanilla page header.
#
992
993
function PAGEHEADER($title, $view = NULL, $extra_headers = NULL,
		    $notice = NULL) {
994
995
    global $login_status, $login_user;
    global $TBBASE, $TBDOCBASE, $THISHOMEBASE;
996
    global $BASEPATH, $SSL_PROTOCOL, $drewheader, $autorefresh;
997
    global $TBMAINSITE;
998
999

    $drewheader = 1;
1000
1001
1002
    if (isset($_GET['refreshrate']) && is_numeric($_GET['refreshrate'])) {
	$autorefresh = $_GET['refreshrate'];
    }
1003

1004
    #
1005
    # Figure out who is logged in, if anyone.
1006
1007
1008
1009
    #
    if (($login_user = CheckLogin($status)) != null) {
	$login_status = $status;
	$login_uid    = $login_user->uid();
1010
1011
    }

1012
1013
1014
1015
1016
1017
1018
    #
    # If no view options were specified, get the ones for the current user
    #
    if (!$view) {
	$view = GETUSERVIEW();
    }

1019
    #
1020
1021
    # Check for NOLOGINS. 
    # We want to allow admin types to continue using the web interface,
1022
1023
    # and logout anyone else that is currently logged in!
    #
1024
1025
    if (NOLOGINS() && $login_user && !ISADMIN()) {
	DOLOGOUT($login_user);
1026
	$login_status = CHECKLOGIN_NOTLOGGEDIN;
1027
	$login_user   = null;
1028
    }
1029
    
Kevin Atkinson's avatar
   
Kevin Atkinson committed
1030
    header('Content-type: text/html; charset=utf-8');
1031
1032
    header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
    
1033
    if (1) {
1034
1035
1036
1037
1038
1039
1040
	header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
	header("Cache-Control: no-cache, must-revalidate");
	header("Pragma: no-cache");
    }
    else {
	header("Expires: " . gmdate("D, d M Y H:i:s", time() + 300) . " GMT"); 
    }
Chad Barb's avatar
   
Chad Barb committed
1041

1042
    if (VIEWSET($view, 'hide_banner')) {
1043
1044
1045
1046
	$nobanner = 1;
    } else {
	$nobanner = 0;
    }
1047
    $contentname = ($login_user ? "content" : "rightcontent");
1048
    $nocontent = VIEWSET($view, 'hide_sidebar') && !VIEWSET($view, 'menu');
Timothy Stack's avatar
   
Timothy Stack committed
1049
    PAGEBEGINNING( $title, $nobanner,
1050
		   $nocontent,
Timothy Stack's avatar
   
Timothy Stack committed
1051
		   $extra_headers );
1052
    if (!VIEWSET($view, 'hide_sidebar')) {
1053
1054
	WRITESIDEBAR();
    }
1055
    elseif (VIEWSET($view, 'menu')) {
1056
1057
	WRITESIMPLESIDEBAR($view['menu']);
    }
Timothy Stack's avatar
   
Timothy Stack committed
1058
1059
1060
    else {
	$contentname = "fullcontent";
    }
1061
    FINISHSIDEBAR($nocontent);
Chad Barb's avatar
   
Chad Barb committed
1062

1063
1064
1065
1066
1067
1068
    if ($login_user) {
	# This is only going to happen when its an admin person
	# still logged in while web interface disabled. Want to make it
	# clear that the web interface is disabled.
	if (NOLOGINS() && ISADMIN()) {
	    echo "<div class=webmessage>";
1069
	    echo "Web Interface Temporarily Unavailable</div>\n";
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
	}
	else {
	    $message = TBGetSiteVar("web/message");
	    if ($message != "") {
		echo "<div class=webmessage>$message</div>\n";
	    }
	}
    }

    echo "<div class='$contentname'>\n";
    echo "<!-- content body -->\n";

    if ($login_user)
1083
1084
	echo "<div id='contentheader'>";
    else {
1085
	echo "<div class='contentbody'>";
1086
1087
	echo "<div id='rightcontentheader'>";
    }
Timothy Stack's avatar
   
Timothy Stack committed
1088
    echo "<div id='logintime'>";
1089
    echo "<span class='loggedin'>";
Timothy Stack's avatar
   
Timothy Stack committed
1090
    $now = date("D M d g:ia T");
1091
    if ($login_user) {
Timothy Stack's avatar
   
Timothy Stack committed
1092
	echo "<span class='uid'>$login_uid</span> Logged in.";
1093
    }
Timothy Stack's avatar
   
Timothy Stack committed
1094
1095
1096
1097
    echo "</span>";
    echo "<span class='timestamp'>$now</span>\n";
    echo "</div>";
    
1098
    if ($login_user || VIEWSET($view, 'hide_versioninfo'))
1099
	$versioninfo = "";
1100
1101
1102
1103
1104
1105
    else {
	$major = "";
	$minor = "";
	$build = "";
	TBGetVersionInfo($major, $minor, $build);
	
1106
	$versioninfo = "Vers: $major.$minor Build: $build";
1107
    }
Timothy Stack's avatar
   
Timothy Stack committed
1108
    echo "<div id='versioninfo'>$versioninfo</div>";
1109
1110
    if ($notice) {
	echo "<span class='headernotice'>$notice</span>";
Chad Barb's avatar
   
Chad Barb committed
1111
    }
Timothy Stack's avatar
   
Timothy Stack committed
1112

1113
1114
1115
1116
1117
    if ($login_user)
	echo "<h2 class='contenttitle'>\n";
    else
	echo "<h2 class='rightcontenttitle'>\n";
    echo "$title</h2>";
1118
1119
1120
1121
1122
    # Close off 'contentheader' (rightcontentheader);
    echo "</div>\n";
    if ($login_user) {
	# And start the contentbody.
	echo "<div id='fullcontentbody'>";
1123
    }
1124
    echo "<!-- begin content -->";
1125
    if (VIEWSET($view, 'show_topbar', "plab")) {
1126
1127
	WRITEPLABTOPBAR();
    }
1128
1129
1130
1131
1132
}

#
# Spit out a vanilla page footer.
#
1133
function PAGEFOOTER($view = NULL) {
1134
    global $TBDOCBASE, $TBMAILADDR, $THISHOMEBASE, $BASEPATH, $TBBASE;
Leigh B. Stoller's avatar
Leigh B. Stoller committed
1135
    global $TBMAINSITE, $SSL_PROTOCOL, $bodyclosestring, $currently_busy;
1136
    global $login_user, $javascript_debug, $sortedtables;
1137
1138
1139
1140
1141

    if ($currently_busy) {
	CLEARBUSY();
	$currently_busy = 0;
    }
1142

1143
1144
1145
1146
    if (!$view) {
	$view = GETUSERVIEW();
    }

1147
1148
    $today = getdate();
    $year  = $today["year"];
Chad Barb's avatar
   
Chad Barb committed
1149

1150
    if (VIEWSET($view, 'show_bottombar', "plab")) {
1151
1152
1153
1154
	WRITEPLABBOTTOMBAR();
    }

    echo "
1155
              <div class='contentfooter'>\n";
1156
    if (!VIEWSET($view, 'hide_copyright')) {
1157
	echo "
Timothy Stack's avatar
   
Timothy Stack committed
1158
                <ul class='navlist'>
1159
1160
1161
1162
1163
1164
		<li>[&nbsp;<a href=\"http://www.cs.utah.edu/flux/\"
                    >Flux&nbsp;Research&nbsp;Group</a>&nbsp;]</li>
	        <li>[&nbsp;<a href=\"http://www.cs.utah.edu/\"
                    >School&nbsp;of&nbsp;Computing</a>&nbsp;]</li>
		<li>[&nbsp;<a href=\"http://www.utah.edu/\"
                    >University&nbsp;of&nbsp;Utah</a>&nbsp;]</li>
Timothy Stack's avatar
   
Timothy Stack committed
1165
                </ul>
Chad Barb's avatar
   
Chad Barb committed
1166
                <!-- begin copyright -->
Timothy Stack's avatar
   
Timothy Stack committed
1167
                <span class='copyright'>
1168
1169
                <a href='$TBDOCBASE/docwrapper.php3?docname=copyright.html'>
                    Copyright &copy; 2000-$year The University of Utah</a>
Timothy Stack's avatar
   
Timothy Stack committed
1170
                </span>\n";
1171
    }
1172
1173
1174
1175
1176
    echo "      <br>\n";
    echo "      <table class=stealth width=100% ".
	               "border='0' cellspacing='0' cellpadding='0'>";
    echo "       <tr>\n";
    
1177
    if ($login_user) {
1178
1179
1180
	echo "    <td class=reportbug>";
	echo "      <a href='$TBBASE/gotobugdb.php3".
	                    "?do=newtask&project_title=Emulab'>";
1181
	echo "        Report Bug, Gripe, Request Feature</a>";
1182
1183
1184
1185
	echo "    </td>";
    }
    echo "        <td class=contact>Questions? Contact $TBMAILADDR</td>";
    echo "       </tr>\n";
1186
    echo "      </table>\n";
1187
    echo "      <!-- end copyright -->\n";
Timothy Stack's avatar
   
Timothy Stack committed
1188
1189
    echo "</div>";
    echo "</div>";
Chad Barb's avatar
   
Chad Barb committed
1190

1191
1192
1193
1194
    if ($javascript_debug) {
	echo "<div id='inline-console'></div>\n";
    }