summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--etc/apache2/sites-available/001-piny56
-rw-r--r--etc/cgitrc100
-rw-r--r--index.mdwn4
-rw-r--r--srv/templates/aggregatepost.tmpl15
-rw-r--r--srv/templates/archivepage.tmpl7
-rw-r--r--srv/templates/atomitem.tmpl48
-rw-r--r--srv/templates/atompage.tmpl39
-rw-r--r--srv/templates/autoindex.tmpl1
-rw-r--r--srv/templates/blogpost.tmpl16
-rw-r--r--srv/templates/change.tmpl46
-rw-r--r--srv/templates/comment.tmpl59
-rw-r--r--srv/templates/commentmoderation.tmpl29
-rw-r--r--srv/templates/editcomment.tmpl30
-rw-r--r--srv/templates/editconflict.tmpl7
-rw-r--r--srv/templates/editcreationconflict.tmpl9
-rw-r--r--srv/templates/editfailedsave.tmpl10
-rw-r--r--srv/templates/editpage.tmpl50
-rw-r--r--srv/templates/editpagegone.tmpl7
-rw-r--r--srv/templates/feedlink.tmpl8
-rw-r--r--srv/templates/googleform.tmpl6
-rw-r--r--srv/templates/inlinepage.tmpl74
-rw-r--r--srv/templates/misc.tmpl37
-rw-r--r--srv/templates/page.tmpl138
-rw-r--r--srv/templates/passwordmail.tmpl15
-rw-r--r--srv/templates/recentchanges.tmpl7
-rw-r--r--srv/templates/renamesummary.tmpl26
-rw-r--r--srv/templates/rssitem.tmpl29
-rw-r--r--srv/templates/rsspage.tmpl11
-rw-r--r--srv/templates/searchform.tmpl5
-rw-r--r--srv/templates/searchquery.tmpl112
-rw-r--r--srv/templates/titlepage.tmpl1
-rwxr-xr-xusr/local/bin/addaccess2
l---------usr/local/bin/createuser1
-rwxr-xr-xusr/local/bin/newrepo2
-rwxr-xr-xusr/local/bin/newuser2
-rwxr-xr-xusr/local/bin/pinyshell5
-rwxr-xr-xusr/local/bin/rmaccess2
-rwxr-xr-xusr/local/bin/rmrepo2
-rwxr-xr-xusr/local/sbin/addaccess39
-rwxr-xr-xusr/local/sbin/newrepo226
-rwxr-xr-xusr/local/sbin/newuser129
-rwxr-xr-xusr/local/sbin/rmaccess39
-rwxr-xr-xusr/local/sbin/rmrepo64
43 files changed, 1512 insertions, 3 deletions
diff --git a/etc/apache2/sites-available/001-piny b/etc/apache2/sites-available/001-piny
new file mode 100644
index 0000000..e283977
--- /dev/null
+++ b/etc/apache2/sites-available/001-piny
@@ -0,0 +1,56 @@
+<VirtualHost *:80>
+ ServerName piny.svcs.cs.pdx.edu
+
+ DocumentRoot /srv/www/piny.svcs.cs.pdx.edu
+
+ <Directory />
+ Options Indexes FollowSymLinks MultiViews
+ AllowOverride None
+ </Directory>
+
+ RedirectMatch 301 ^/$ http://piny.svcs.cs.pdx.edu/piny-web/
+</VirtualHost>
+
+<VirtualHost *:80>
+ ServerName secure.piny.svcs.cs.pdx.edu
+ RedirectMatch 301 (.*) https://secure.piny.svcs.cs.pdx.edu$1
+</VirtualHost>
+
+<VirtualHost *:443>
+ ServerName secure.piny.svcs.cs.pdx.edu
+ DocumentRoot /srv/www/secure.piny.svcs.cs.pdx.edu
+
+ <Directory />
+ Options Indexes FollowSymLinks MultiViews
+ AllowOverride None
+ </Directory>
+
+ RedirectMatch 301 ^/$ http://piny.svcs.cs.pdx.edu/piny-web/
+
+ SSLEngine On
+ SSLCertificateFile /etc/ssl/private/wildcard.piny.svcs.cs.pdx.edu.pem
+</VirtualHost>
+
+<VirtualHost *:80>
+ ServerName cgi.piny.svcs.cs.pdx.edu
+ RedirectMatch 301 (.*) https://cgi.piny.svcs.cs.pdx.edu$1
+</VirtualHost>
+
+<VirtualHost *:443>
+ ServerName cgi.piny.svcs.cs.pdx.edu
+ DocumentRoot /srv/www/cgi.piny.svcs.cs.pdx.edu
+
+ <Directory "/srv/www/cgi.piny.svcs.cs.pdx.edu">
+ SSLRequireSSL
+ SetHandler cgi-script
+ AllowOverride None
+ Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
+ </Directory>
+
+ ScriptAlias /cgi-bin/cgit.cgi /usr/lib/cgi-bin/cgit.cgi
+
+ Include /etc/apache2/piny-enabled
+
+ SSLEngine On
+ SSLCertificateFile /etc/ssl/private/wildcard.piny.svcs.cs.pdx.edu.pem
+</VirtualHost>
diff --git a/etc/cgitrc b/etc/cgitrc
new file mode 100644
index 0000000..5ff681c
--- /dev/null
+++ b/etc/cgitrc
@@ -0,0 +1,100 @@
+# Enable caching of up to 1000 output entriess
+cache-size=1000
+
+
+# Specify some default clone prefixes
+clone-prefix=git://piny.svcs.cs.pdx.edu git+ssh://piny.svcs.cs.pdx.edu/srv/git
+
+# Specify the css url
+css=http://piny.svcs.cs.pdx.edu/piny-shared/cgit/cgit.css
+
+
+# Show extra links for each repository on the index page
+enable-index-links=1
+
+
+# Show number of affected files per commit on the log pages
+enable-log-filecount=1
+
+
+# Show number of added/removed lines per commit on the log pages
+enable-log-linecount=1
+
+
+# Add a cgit favicon
+#favicon=/cgit/favicon.ico
+
+
+# Use a custom logo
+logo=http://piny.svcs.cs.pdx.edu/piny-shared/cgit/cgit.png
+
+
+# Set the title and heading of the repository index page
+root-title=Piny git repositories
+
+
+# Set a subheading for the repository index page
+root-desc=For all your informational needs.
+
+
+# Include some more info about foobar.com on the index page
+#root-readme=/var/www/htdocs/about.html
+
+
+# Allow download of tar.gz, tar.bz and zip-files
+snapshots=tar.gz zip
+
+
+##
+## List of repositories.
+## PS: Any repositories listed when repo.group is unset will not be
+## displayed under a group heading
+## PPS: This list could be kept in a different file (e.g. '/etc/cgitrepos')
+## and included like this:
+include=/etc/cgitrepos
+##
+
+
+#repo.url=piny-web
+#repo.path=/srv/git/piny-web.git
+#repo.desc=piny-web
+#repo.owner=jrayhawk+piny.svcs.cs.pdx.edu@omgwallhack.org
+#repo.readme=info/web/about.html
+
+
+#repo.url=piny-shared
+#repo.path=/srv/git/piny-shared.git
+#repo.desc=piny-shared
+#repo.owner=jrayhawk+piny.svcs.cs.pdx.edu@omgwallhack.org
+#repo.readme=info/web/about.html
+
+
+# The next repositories will be displayed under the 'extras' heading
+
+#repo.url=baz
+#repo.path=/pub/git/baz.git
+#repo.desc=a set of extensions for bar users
+
+#repo.url=wiz
+#repo.path=/pub/git/wiz.git
+#repo.desc=the wizard of foo
+
+
+# Add some mirrored repositories
+#repo.group=mirrors
+
+
+#repo.url=git
+#repo.path=/pub/git/git.git
+#repo.desc=the dscm
+
+
+#repo.url=linux
+#repo.path=/pub/git/linux.git
+#repo.desc=the kernel
+
+# Disable adhoc downloads of this repo
+repo.snapshots=0
+
+# Disable line-counts for this repo
+repo.enable-log-linecount=0
diff --git a/index.mdwn b/index.mdwn
index ed6a228..0a762a4 100644
--- a/index.mdwn
+++ b/index.mdwn
@@ -1,6 +1,4 @@
-Welcome to your repo!
-
-[Ikiwiki usage](http://piny.svcs.cs.pdx.edu/piny-shared/ikiwiki/)
+The code behind piny.
Files:
[[!map pages="* and ! */*"]]
diff --git a/srv/templates/aggregatepost.tmpl b/srv/templates/aggregatepost.tmpl
new file mode 100644
index 0000000..8b89367
--- /dev/null
+++ b/srv/templates/aggregatepost.tmpl
@@ -0,0 +1,15 @@
+<TMPL_VAR CONTENT>
+<TMPL_LOOP NAME="TAGS">
+[[!tag <TMPL_VAR TAG>]]
+</TMPL_LOOP>
+<TMPL_IF NAME="TITLE">
+[[!meta title="<TMPL_VAR NAME="TITLE" ESCAPE=HTML>"]]
+</TMPL_IF>
+<TMPL_IF NAME="PERMALINK">
+[[!meta permalink="<TMPL_VAR NAME="PERMALINK" ESCAPE=HTML>"]]
+</TMPL_IF>
+<TMPL_IF NAME="COPYRIGHT">
+[[!meta copyright="<TMPL_VAR NAME="COPYRIGHT" ESCAPE=HTML>"]]
+</TMPL_IF>
+[[!meta author="<TMPL_VAR NAME="NAME" ESCAPE=HTML>"]]
+[[!meta authorurl="<TMPL_VAR NAME="URL" ESCAPE=HTML>"]]
diff --git a/srv/templates/archivepage.tmpl b/srv/templates/archivepage.tmpl
new file mode 100644
index 0000000..6bc789d
--- /dev/null
+++ b/srv/templates/archivepage.tmpl
@@ -0,0 +1,7 @@
+<p>
+<a href="<TMPL_VAR PAGEURL>"><TMPL_VAR TITLE></a><br />
+<i>
+Posted <TMPL_VAR CTIME>
+</i>
+
+</p>
diff --git a/srv/templates/atomitem.tmpl b/srv/templates/atomitem.tmpl
new file mode 100644
index 0000000..768695a
--- /dev/null
+++ b/srv/templates/atomitem.tmpl
@@ -0,0 +1,48 @@
+<entry>
+ <title><TMPL_VAR TITLE></title>
+ <TMPL_IF NAME="GUID">
+ <id><TMPL_VAR GUID></id>
+ <TMPL_ELSE>
+ <id><TMPL_VAR URL></id>
+ </TMPL_IF>
+ <link href="<TMPL_VAR PERMALINK>"/>
+ <TMPL_IF NAME="AUTHOR">
+ <author><name><TMPL_VAR AUTHOR ESCAPE=HTML></name></author>
+ </TMPL_IF>
+ <TMPL_IF NAME="COPYRIGHT">
+ <rights type="html" xml:lang="en">
+ <TMPL_IF NAME="LICENSE">
+ <TMPL_VAR LICENSE ESCAPE=HTML>
+ <TMPL_VAR COPYRIGHT ESCAPE=HTML>
+ <TMPL_ELSE>
+ <TMPL_VAR COPYRIGHT ESCAPE=HTML>
+ </TMPL_IF>
+ </rights>
+ <TMPL_ELSE>
+ <TMPL_IF NAME="LICENSE">
+ <rights type="html" xml:lang="en">
+ <TMPL_VAR LICENSE ESCAPE=HTML>
+ </rights>
+ </TMPL_IF>
+ </TMPL_IF>
+ <TMPL_IF NAME="CATEGORIES">
+ <TMPL_LOOP NAME="CATEGORIES">
+ <category term="<TMPL_VAR CATEGORY>" />
+ </TMPL_LOOP>
+ </TMPL_IF>
+ <updated><TMPL_VAR MDATE_3339></updated>
+ <published><TMPL_VAR CDATE_3339></published>
+ <TMPL_IF NAME="ENCLOSURE">
+ <link rel="enclosure" type="<TMPL_VAR TYPE>" href="<TMPL_VAR ENCLOSURE>" length="<TMPL_VAR LENGTH>" />
+ <TMPL_ELSE>
+ <content type="html" xml:lang="en">
+ <TMPL_VAR CONTENT ESCAPE=HTML>
+ </content>
+ </TMPL_IF>
+ <TMPL_IF NAME="COMMENTSURL">
+ <link rel="comments" href="<TMPL_VAR NAME="COMMENTSURL">" type="text/html" />
+ </TMPL_IF>
+ <TMPL_IF NAME="ATOMCOMMENTSURL">
+ <link rel="comments" href="<TMPL_VAR NAME="ATOMCOMMENTSURL">" type="application/atom+xml" />
+ </TMPL_IF>
+</entry>
diff --git a/srv/templates/atompage.tmpl b/srv/templates/atompage.tmpl
new file mode 100644
index 0000000..dcb89ab
--- /dev/null
+++ b/srv/templates/atompage.tmpl
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+<title><TMPL_VAR TITLE></title>
+<link href="<TMPL_VAR PAGEURL>"/>
+<link href="<TMPL_VAR FEEDURL>" rel="self" type="application/atom+xml"/>
+<author>
+<TMPL_IF NAME="AUTHOR">
+ <name><TMPL_VAR AUTHOR></name>
+<TMPL_ELSE>
+ <name><TMPL_VAR WIKINAME></name>
+</TMPL_IF>
+</author>
+<TMPL_IF NAME="COPYRIGHT">
+ <rights type="html" xml:lang="en">
+ <TMPL_IF NAME="LICENSE">
+ <TMPL_VAR LICENSE>
+ <TMPL_VAR COPYRIGHT ESCAPE=HTML>
+ <TMPL_ELSE>
+ <TMPL_VAR COPYRIGHT ESCAPE=HTML>
+ </TMPL_IF>
+ </rights>
+<TMPL_ELSE>
+ <TMPL_IF NAME="LICENSE">
+ <rights type="html">
+ <TMPL_VAR LICENSE ESCAPE=HTML>
+ </rights>
+ </TMPL_IF>
+</TMPL_IF>
+<TMPL_IF NAME="GUID">
+ <id><TMPL_VAR GUID></id>
+<TMPL_ELSE>
+ <id><TMPL_VAR PAGEURL></id>
+</TMPL_IF>
+<subtitle type="html"><TMPL_VAR FEEDDESC ESCAPE=HTML></subtitle>
+<generator uri="http://ikiwiki.info/" version="<TMPL_VAR VERSION>">ikiwiki</generator>
+<updated><TMPL_VAR FEEDDATE></updated>
+<TMPL_VAR CONTENT>
+</feed>
diff --git a/srv/templates/autoindex.tmpl b/srv/templates/autoindex.tmpl
new file mode 100644
index 0000000..d5ec3b8
--- /dev/null
+++ b/srv/templates/autoindex.tmpl
@@ -0,0 +1 @@
+[[!map pages="<TMPL_VAR PAGE>/* and ! <TMPL_VAR PAGE>/*/*"]]
diff --git a/srv/templates/blogpost.tmpl b/srv/templates/blogpost.tmpl
new file mode 100644
index 0000000..7eeede6
--- /dev/null
+++ b/srv/templates/blogpost.tmpl
@@ -0,0 +1,16 @@
+<form action="<TMPL_VAR CGIURL>" method="get">
+<div id="blogform">
+<TMPL_IF NAME="RSSURL">
+<a class="feedbutton" type="application/rss+xml" href="<TMPL_VAR NAME=RSSURL>">RSS</a>
+</TMPL_IF>
+<TMPL_IF NAME="ATOMURL">
+<a class="feedbutton" type="application/atom+xml" href="<TMPL_VAR NAME=ATOMURL>">Atom</a>
+</TMPL_IF>
+<input type="hidden" name="do" value="blog" />
+<input type="hidden" name="from" value="<TMPL_VAR ROOTPAGE>" />
+<input type="hidden" name="subpage" value="1" />
+<TMPL_VAR POSTFORMTEXT>
+<input name="title" size="40" />
+<input type="submit" value="Edit" />
+</div>
+</form>
diff --git a/srv/templates/change.tmpl b/srv/templates/change.tmpl
new file mode 100644
index 0000000..0e61a80
--- /dev/null
+++ b/srv/templates/change.tmpl
@@ -0,0 +1,46 @@
+[[!meta author="""<TMPL_VAR AUTHOR>"""]]
+<TMPL_IF AUTHORURL>
+[[!meta authorurl="""<TMPL_VAR AUTHORURL>"""]]
+</TMPL_IF>
+[[!meta title="""change to<TMPL_LOOP NAME="PAGES"> <TMPL_VAR PAGE></TMPL_LOOP> on <TMPL_VAR WIKINAME>"""]]
+<TMPL_IF PERMALINK>
+[[!meta permalink="<TMPL_VAR PERMALINK>"]]
+</TMPL_IF>
+<div id="change-<TMPL_VAR REV>" class="metadata">
+<span class="desc"><br />Changed pages:</span>
+<span class="pagelinks">
+<TMPL_LOOP NAME="PAGES">
+<TMPL_IF NAME="DIFFURL"><a href="<TMPL_VAR DIFFURL>">[[diff|wikiicons/diff.png]]</a><TMPL_VAR LINK>
+<TMPL_ELSE>
+<TMPL_VAR LINK>
+</TMPL_IF>
+</TMPL_LOOP>
+</span>
+<span class="desc"><br />Changed by:</span>
+<span class="committer">
+<TMPL_IF NAME="AUTHORURL">
+<a href="<TMPL_VAR AUTHORURL>" rel="nofollow"><TMPL_VAR USER></a>
+<TMPL_ELSE>
+<TMPL_VAR USER>
+</TMPL_IF>
+</span>
+<span class="desc"><br />Commit type:</span>
+<span class="committype"><TMPL_VAR COMMITTYPE></span>
+<span class="desc"><br />Date:</span>
+<span class="changedate"><TMPL_VAR COMMITDATE>
+</div>
+<div class=changelog>
+<TMPL_LOOP NAME="MESSAGE">
+<TMPL_IF NAME="LINE">
+<TMPL_VAR NAME="LINE"><br />
+</TMPL_IF>
+</TMPL_LOOP>
+</div>
+<TMPL_IF NAME="DIFF">
+<div class=diff>
+<pre>
+<TMPL_VAR NAME="DIFF">
+</pre>
+</div>
+</TMPL_IF>
+<!-- <TMPL_VAR REV> -->
diff --git a/srv/templates/comment.tmpl b/srv/templates/comment.tmpl
new file mode 100644
index 0000000..fb76ea0
--- /dev/null
+++ b/srv/templates/comment.tmpl
@@ -0,0 +1,59 @@
+<div class="comment" id="<TMPL_VAR NAME=COMMENTID>">
+
+<div class="comment-subject">
+<TMPL_IF PERMALINK>
+<a href="<TMPL_VAR PERMALINK>"><TMPL_VAR TITLE></a>
+<TMPL_ELSE>
+<TMPL_VAR TITLE>
+</TMPL_IF>
+</div>
+
+<div class="inlinecontent">
+<TMPL_VAR CONTENT>
+</div>
+
+<div class="comment-header">
+Comment by
+
+<TMPL_IF NAME="COMMENTUSER">
+<TMPL_IF NAME="COMMENTOPENID">
+<span class="author" title="OpenID">
+<a href="<TMPL_VAR NAME=COMMENTOPENID>"><TMPL_VAR NAME=COMMENTAUTHOR></a>
+</span>
+<TMPL_ELSE>
+<span class="author" title="Signed in">
+<TMPL_IF NAME="COMMENTAUTHORURL">
+<a href="<TMPL_VAR NAME=COMMENTAUTHORURL>"><TMPL_VAR NAME=COMMENTAUTHOR></a>
+<TMPL_ELSE>
+<TMPL_VAR NAME=COMMENTAUTHOR>
+</TMPL_IF>
+</span>
+</TMPL_IF>
+<TMPL_ELSE><!-- !COMMENTUSER -->
+<TMPL_IF NAME=COMMENTIP>
+<span class="author" title="Unauthenticated, from <TMPL_VAR NAME=COMMENTIP>">
+<TMPL_ELSE><!-- !COMMENTIP -->
+<span class="author" title="Unauthenticated, from unknown IP address">
+</TMPL_IF>
+<TMPL_IF NAME="AUTHORURL">
+<a href="<TMPL_VAR NAME=AUTHORURL>"><TMPL_VAR NAME=AUTHOR></a>
+<TMPL_ELSE>
+<TMPL_VAR NAME=AUTHOR>
+</TMPL_IF>
+</span>
+</TMPL_IF><!-- !COMMENTUSER -->
+
+&mdash; <TMPL_VAR CTIME>
+</div>
+
+<TMPL_IF NAME="HAVE_ACTIONS">
+<div class="actions">
+<ul>
+<TMPL_IF NAME="REMOVEURL">
+<li><a href="<TMPL_VAR REMOVEURL>" rel="nofollow">Remove comment</a></li>
+</TMPL_IF>
+</ul>
+</div><!--.actions-->
+</TMPL_IF>
+
+</div><!--.comment-->
diff --git a/srv/templates/commentmoderation.tmpl b/srv/templates/commentmoderation.tmpl
new file mode 100644
index 0000000..e91d314
--- /dev/null
+++ b/srv/templates/commentmoderation.tmpl
@@ -0,0 +1,29 @@
+<TMPL_IF NAME="COMMENTS">
+<br />
+<form action="<TMPL_VAR CGIURL>" method="post">
+<input type="hidden" name="do" value="commentmoderation" />
+<input type="hidden" name="sid" value="<TMPL_VAR SID>" />
+<input type="submit" value="Submit" />
+<input type="checkbox" name="rejectalldefer" value="1" />Reject
+all comments marked <em>Defer</em>
+<br />
+<TMPL_LOOP NAME="COMMENTS">
+<div>
+<div>
+<TMPL_VAR VIEW>
+</div>
+<input type="radio" value="Defer" name="<TMPL_VAR ID>" checked />Defer
+<input type="radio" value="Accept" name="<TMPL_VAR ID>" />Accept
+<input type="radio" value="Reject" name="<TMPL_VAR ID>" />Reject
+</div>
+<br />
+</TMPL_LOOP>
+<input type="submit" value="Submit" />
+<input type="checkbox" name="rejectalldefer" value="1" />Reject
+all comments marked <em>Defer</em>
+</form>
+<TMPL_ELSE>
+<p>
+No comments need moderation at this time.
+</p>
+</TMPL_IF>
diff --git a/srv/templates/editcomment.tmpl b/srv/templates/editcomment.tmpl
new file mode 100644
index 0000000..7590cdf
--- /dev/null
+++ b/srv/templates/editcomment.tmpl
@@ -0,0 +1,30 @@
+<div class="editcomment">
+<TMPL_VAR MESSAGE>
+<TMPL_VAR FORM-START>
+<TMPL_VAR FIELD-DO>
+<TMPL_VAR FIELD-SID>
+<TMPL_VAR FIELD-PAGE>
+<TMPL_UNLESS NAME=USERNAME>
+<TMPL_IF NAME=ALLOWAUTHOR>
+Name: <TMPL_VAR NAME=FIELD-AUTHOR> (optional)<br />
+Website: <TMPL_VAR NAME=FIELD-URL> (optional)<br />
+</TMPL_IF>
+</TMPL_UNLESS>
+Subject: <TMPL_VAR FIELD-SUBJECT><br />
+<TMPL_VAR FIELD-EDITCONTENT><br />
+<TMPL_VAR FORM-SUBMIT> <TMPL_VAR FIELD-TYPE> <TMPL_VAR HELPONFORMATTINGLINK><br />
+IkiWiki directives ([[!directive]]) are <TMPL_UNLESS NAME="ALLOWDIRECTIVES">not </TMPL_UNLESS>allowed in comments on this wiki.<br />
+<TMPL_VAR NAME="FORM-END">
+<TMPL_VAR WMD_PREVIEW>
+
+<TMPL_IF NAME="PAGE_PREVIEW">
+<hr />
+<div class="header">
+<span>Comment preview:</span>
+</div><!-- .header -->
+<div id="preview">
+<TMPL_VAR PAGE_PREVIEW>
+</div><!-- #preview -->
+</TMPL_IF>
+
+</div><!-- .editcomment -->
diff --git a/srv/templates/editconflict.tmpl b/srv/templates/editconflict.tmpl
new file mode 100644
index 0000000..1252033
--- /dev/null
+++ b/srv/templates/editconflict.tmpl
@@ -0,0 +1,7 @@
+<p class="error">
+<b>Your changes conflict with other changes made to the page.</b>
+</p>
+<p>
+Conflict markers have been inserted into the page content. Reconcile the
+conflict and commit again to save your changes.
+</p>
diff --git a/srv/templates/editcreationconflict.tmpl b/srv/templates/editcreationconflict.tmpl
new file mode 100644
index 0000000..c99102f
--- /dev/null
+++ b/srv/templates/editcreationconflict.tmpl
@@ -0,0 +1,9 @@
+<p class="error">
+<b>While you were creating this page, someone else independently created a page
+with the same name.</b>
+</p>
+<p>
+The edit box below contains the page's current content, followed by the
+content you entered previously, to allow you to merge the two
+together before saving.
+</p>
diff --git a/srv/templates/editfailedsave.tmpl b/srv/templates/editfailedsave.tmpl
new file mode 100644
index 0000000..5184f7d
--- /dev/null
+++ b/srv/templates/editfailedsave.tmpl
@@ -0,0 +1,10 @@
+<p class="error">
+<b>Failed to save your changes.</b>
+</p>
+<p>
+Your changes were not able to be saved to disk. The system gave the error:
+<blockquote>
+<TMPL_VAR ERROR_MESSAGE>
+</blockquote>
+Your changes are preserved below, and you can try again to save them.
+</p>
diff --git a/srv/templates/editpage.tmpl b/srv/templates/editpage.tmpl
new file mode 100644
index 0000000..b1cf015
--- /dev/null
+++ b/srv/templates/editpage.tmpl
@@ -0,0 +1,50 @@
+<br />
+<TMPL_VAR JAVASCRIPT>
+<TMPL_VAR MESSAGE>
+<TMPL_VAR FORM-START>
+<TMPL_VAR FIELD-DO>
+<TMPL_VAR FIELD-SID>
+<TMPL_VAR FIELD-FROM>
+<TMPL_VAR FIELD-RCSINFO>
+<TMPL_VAR FIELD-NEWFILE>
+<TMPL_IF NAME="PAGE_SELECT">
+Page location: <TMPL_VAR FIELD-PAGE>
+Page type: <TMPL_VAR FIELD-TYPE>
+<TMPL_ELSE>
+<br />
+<TMPL_VAR FIELD-PAGE>
+<TMPL_VAR FIELD-TYPE>
+</TMPL_IF>
+<TMPL_VAR FIELD-EDITCONTENT><br />
+<TMPL_IF NAME="CAN_COMMIT">
+Optional comment about this change:<br />
+<TMPL_VAR FIELD-COMMENTS><br />
+</TMPL_IF>
+<TMPL_VAR FORM-SUBMIT>
+<TMPL_VAR HELPONFORMATTINGLINK>
+<TMPL_IF NAME="FIELD-ATTACHMENT">
+<a class="toggle" href="#attachments">Attachments</a>
+<div class="<TMPL_VAR ATTACHMENTS-CLASS>" id="attachments">
+<table>
+<tr><td colspan="5"><TMPL_VAR FIELD-ATTACHMENT><TMPL_VAR FIELD-UPLOAD></td></tr>
+<TMPL_LOOP NAME="ATTACHMENT_LIST">
+<tr><td><TMPL_VAR FIELD-SELECT><TMPL_VAR LINK></td><td><TMPL_VAR SIZE></td><td><TMPL_VAR MTIME></td></tr>
+</TMPL_LOOP>
+<TMPL_IF NAME="ATTACHMENT_LIST">
+<tr><td colspan="2"><TMPL_VAR FIELD-LINK><TMPL_VAR FIELD-RENAME><TMPL_VAR FIELD-REMOVE></td></tr>
+</TMPL_IF>
+</table>
+</div>
+</TMPL_IF>
+<TMPL_VAR FORM-END>
+<TMPL_VAR WMD_PREVIEW>
+
+<TMPL_IF NAME="PAGE_PREVIEW">
+<hr />
+<div class="header">
+<span>Page preview:</span>
+</div>
+<div id="preview">
+<TMPL_VAR PAGE_PREVIEW>
+</div>
+</TMPL_IF>
diff --git a/srv/templates/editpagegone.tmpl b/srv/templates/editpagegone.tmpl
new file mode 100644
index 0000000..2eed03a
--- /dev/null
+++ b/srv/templates/editpagegone.tmpl
@@ -0,0 +1,7 @@
+<p class="error">
+<b>The page you were editing has disappeared.</b>
+</p>
+<p>
+Perhaps someone else has deleted it or moved it. If you want to recreate
+this page with your text, click "Save Page" again.
+</p>
diff --git a/srv/templates/feedlink.tmpl b/srv/templates/feedlink.tmpl
new file mode 100644
index 0000000..2963156
--- /dev/null
+++ b/srv/templates/feedlink.tmpl
@@ -0,0 +1,8 @@
+<div id="feedlink">
+<TMPL_IF NAME="RSSURL">
+<a class="feedbutton" type="application/rss+xml" href="<TMPL_VAR NAME=RSSURL>">RSS</a>
+</TMPL_IF>
+<TMPL_IF NAME="ATOMURL">
+<a class="feedbutton" type="application/atom+xml" href="<TMPL_VAR NAME=ATOMURL>">Atom</a>
+</TMPL_IF>
+</div>
diff --git a/srv/templates/googleform.tmpl b/srv/templates/googleform.tmpl
new file mode 100644
index 0000000..e2d4a1f
--- /dev/null
+++ b/srv/templates/googleform.tmpl
@@ -0,0 +1,6 @@
+<form method="get" action="http://www.google.com/search" id="searchform">
+ <div>
+ <input name="sitesearch" value="<TMPL_VAR SITEFQDN>" type="hidden" />
+ <input name="q" value="" id="searchbox" size="16" maxlength="255" type="text" />
+ </div>
+</form>
diff --git a/srv/templates/inlinepage.tmpl b/srv/templates/inlinepage.tmpl
new file mode 100644
index 0000000..3c0b933
--- /dev/null
+++ b/srv/templates/inlinepage.tmpl
@@ -0,0 +1,74 @@
+<div class="inlinepage">
+
+<div class="inlineheader">
+
+<TMPL_IF NAME="AUTHOR">
+<span class="author">
+<TMPL_IF NAME="AUTHORURL">
+<a href="<TMPL_VAR AUTHORURL>"><TMPL_VAR AUTHOR></a>
+<TMPL_ELSE>
+<TMPL_VAR AUTHOR>
+</TMPL_IF>
+</span>
+</TMPL_IF>
+<span class="header">
+<TMPL_IF NAME="PERMALINK">
+<a href="<TMPL_VAR PERMALINK>"><TMPL_VAR TITLE></a>
+<TMPL_ELSE>
+<a href="<TMPL_VAR PAGEURL>"><TMPL_VAR TITLE></a>
+</TMPL_IF>
+</span>
+
+</div><!--.inlineheader-->
+
+<div class="inlinecontent">
+<TMPL_VAR CONTENT>
+</div><!--.inlinecontent-->
+
+<div class="inlinefooter">
+
+<span class="pagedate">
+Posted <TMPL_VAR CTIME>
+</span>
+
+<TMPL_IF NAME="TAGS">
+<span class="tags">
+Tags:
+<TMPL_LOOP NAME="TAGS">
+<TMPL_VAR LINK>
+</TMPL_LOOP>
+</span>
+</TMPL_IF>
+
+<TMPL_IF COPYRIGHT>
+<div class="pagecopyright">
+<TMPL_VAR COPYRIGHT>
+</div>
+</TMPL_IF>
+
+<TMPL_IF LICENSE>
+<div class="pagelicense">
+License: <TMPL_VAR LICENSE>
+</div>
+</TMPL_IF>
+
+<TMPL_IF NAME="HAVE_ACTIONS">
+<div class="actions">
+<ul>
+<TMPL_IF NAME="EDITURL">
+<li><a href="<TMPL_VAR EDITURL>" rel="nofollow">Edit</a></li>
+</TMPL_IF>
+<TMPL_IF NAME="COMMENTSLINK">
+<li><TMPL_VAR COMMENTSLINK></li>
+<TMPL_ELSE>
+<TMPL_IF NAME="DISCUSSIONLINK">
+<li><TMPL_VAR DISCUSSIONLINK></li>
+</TMPL_IF>
+</TMPL_IF>
+</ul>
+</div><!--.actions-->
+</TMPL_IF>
+
+</div><!--.inlinefooter-->
+
+</div><!--.inlinepage-->
diff --git a/srv/templates/misc.tmpl b/srv/templates/misc.tmpl
new file mode 100644
index 0000000..0de56ed
--- /dev/null
+++ b/srv/templates/misc.tmpl
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<TMPL_IF NAME="FORCEBASEURL">
+<base href="<TMPL_VAR FORCEBASEURL>" />
+<TMPL_ELSE>
+<base href="<TMPL_VAR BASEURL>" />
+</TMPL_IF>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title><TMPL_VAR TITLE></title>
+<link rel="stylesheet" href="<TMPL_VAR BASEURL>style.css" type="text/css" />
+<link rel="stylesheet" href="<TMPL_VAR BASEURL>local.css" type="text/css" />
+<TMPL_IF NAME="FAVICON">
+<link rel="icon" href="<TMPL_VAR BASEURL><TMPL_VAR FAVICON>" type="image/x-icon" />
+</TMPL_IF>
+</head>
+<body>
+
+<div class="pageheader">
+<div class="header">
+<span>
+<TMPL_VAR INDEXLINK>/ <TMPL_VAR TITLE>
+</span>
+</div>
+</div> <!-- .pageheader -->
+
+<div id="content">
+<TMPL_VAR PAGEBODY>
+</div>
+
+<div id="footer">
+<!-- from <TMPL_VAR NAME=WIKINAME> -->
+</div>
+
+</body>
+</html>
diff --git a/srv/templates/page.tmpl b/srv/templates/page.tmpl
new file mode 100644
index 0000000..cda5c71
--- /dev/null
+++ b/srv/templates/page.tmpl
@@ -0,0 +1,138 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title><TMPL_VAR TITLE></title>
+<TMPL_IF NAME="FAVICON">
+<link rel="icon" href="<TMPL_VAR BASEURL><TMPL_VAR FAVICON>" type="image/x-icon" />
+</TMPL_IF>
+<link rel="stylesheet" href="/piny-shared/style.css" type="text/css" />
+<link rel="stylesheet" href="<TMPL_VAR BASEURL>local.css" type="text/css" /> <!-- Optional per-repo custom CSS. -->
+<TMPL_IF NAME="EDITURL">
+<link rel="alternate" type="application/x-wiki" title="Edit this page" href="<TMPL_VAR EDITURL>" />
+</TMPL_IF>
+<TMPL_IF NAME="FEEDLINKS"><TMPL_VAR FEEDLINKS></TMPL_IF>
+<TMPL_IF NAME="RELVCS"><TMPL_VAR RELVCS></TMPL_IF>
+<TMPL_IF NAME="META"><TMPL_VAR META></TMPL_IF>
+</head>
+<body>
+
+<div class="pageheader">
+<div class="header">
+<span>
+<span class="parentlinks">
+<TMPL_LOOP NAME="PARENTLINKS">
+<a href="<TMPL_VAR URL>"><TMPL_VAR PAGE></a>/
+</TMPL_LOOP>
+</span>
+<span class="title">
+<TMPL_VAR TITLE>
+</span>
+</span><!--.header-->
+<TMPL_IF NAME="SEARCHFORM">
+<TMPL_VAR SEARCHFORM>
+</TMPL_IF>
+</div>
+
+<TMPL_IF NAME="HAVE_ACTIONS">
+<div class="actions">
+<ul>
+<TMPL_IF NAME="EDITURL">
+<li><a href="<TMPL_VAR EDITURL>" rel="nofollow">Edit</a></li>
+</TMPL_IF>
+<TMPL_IF NAME="RECENTCHANGESURL">
+<li><a href="<TMPL_VAR RECENTCHANGESURL>">RecentChanges</a></li>
+</TMPL_IF>
+<TMPL_IF NAME="HISTORYURL">
+<li><a href="<TMPL_VAR HISTORYURL>">History</a></li>
+</TMPL_IF>
+<TMPL_IF NAME="PREFSURL">
+<li><a href="<TMPL_VAR PREFSURL>">Preferences</a></li>
+</TMPL_IF>
+<TMPL_IF NAME="COMMENTSLINK">
+<li><TMPL_VAR COMMENTSLINK><br /></li>
+<TMPL_ELSE>
+<TMPL_IF NAME="DISCUSSIONLINK">
+<li><TMPL_VAR DISCUSSIONLINK><br /></li>
+</TMPL_IF>
+</TMPL_IF>
+</ul>
+</div>
+</TMPL_IF>
+</div> <!-- .pageheader -->
+
+<TMPL_IF SIDEBAR>
+<div id="sidebar">
+<TMPL_VAR SIDEBAR>
+</div>
+</TMPL_IF>
+
+<div id="content">
+<TMPL_VAR CONTENT>
+</div>
+
+<TMPL_IF COMMENTS>
+<div id="comments">
+<TMPL_VAR COMMENTS>
+<TMPL_IF ADDCOMMENTURL>
+<div class="addcomment">
+<a href="<TMPL_VAR ADDCOMMENTURL>">Add a comment</a>
+</div>
+<TMPL_ELSE>
+<div class="addcomment">Comments on this page are closed.</div>
+</TMPL_IF>
+</div>
+</TMPL_IF>
+
+<div id="footer" class="pagefooter">
+<div id="pageinfo">
+
+<TMPL_IF NAME="TAGS">
+<div class="tags">
+Tags:
+<TMPL_LOOP NAME="TAGS">
+<TMPL_VAR LINK>
+</TMPL_LOOP>
+</div>
+</TMPL_IF>
+
+<TMPL_IF NAME="BACKLINKS">
+<div id="backlinks">
+Links:
+<TMPL_LOOP NAME="BACKLINKS">
+<a href="<TMPL_VAR URL>"><TMPL_VAR PAGE></a>
+</TMPL_LOOP>
+<TMPL_IF NAME="MORE_BACKLINKS">
+<span class="popup">...
+<span class="balloon">
+<TMPL_LOOP NAME="MORE_BACKLINKS">
+<a href="<TMPL_VAR URL>"><TMPL_VAR PAGE></a>
+</TMPL_LOOP>
+</span>
+</span>
+</TMPL_IF>
+</div><!-- #backlinks -->
+</TMPL_IF>
+
+<TMPL_IF COPYRIGHT>
+<div class="pagecopyright">
+<a name="pagecopyright"></a>
+<TMPL_VAR COPYRIGHT>
+</div>
+</TMPL_IF>
+
+<TMPL_IF LICENSE>
+<div class="pagelicense">
+<a name="pagelicense"></a>
+License: <TMPL_VAR LICENSE>
+</div>
+</TMPL_IF>
+
+</div><!-- #pageinfo -->
+<TMPL_IF EXTRAFOOTER><TMPL_VAR EXTRAFOOTER></TMPL_IF>
+<a href="https://cgi.piny.svcs.cs.pdx.edu/cgi-bin/cgit.cgi/<TMPL_VAR WIKINAME>/">Repository information</a>
+</div><!-- .pagefooter #footer -->
+
+</body>
+</html>
diff --git a/srv/templates/passwordmail.tmpl b/srv/templates/passwordmail.tmpl
new file mode 100644
index 0000000..aa8a68c
--- /dev/null
+++ b/srv/templates/passwordmail.tmpl
@@ -0,0 +1,15 @@
+Someone[1], possibly you, requested that the password for
+<TMPL_VAR USER_NAME> on <TMPL_VAR WIKINAME>[2] be reset.
+
+To change your password, visit the following url, and enter a new password:
+
+<TMPL_VAR PASSWORDURL>
+
+This url can only be used once to change your password, and it will also
+stop working the next time you successfully log in.
+
+--
+ikiwiki
+
+[1] Their IP address was <TMPL_VAR REMOTE_ADDR>
+[2] Located at <TMPL_VAR WIKIURL>
diff --git a/srv/templates/recentchanges.tmpl b/srv/templates/recentchanges.tmpl
new file mode 100644
index 0000000..340a157
--- /dev/null
+++ b/srv/templates/recentchanges.tmpl
@@ -0,0 +1,7 @@
+<TMPL_IF FIRST>
+<div class="recentchanges">
+</TMPL_IF>
+<TMPL_VAR CONTENT>
+<TMPL_IF LAST>
+</div>
+</TMPL_IF>
diff --git a/srv/templates/renamesummary.tmpl b/srv/templates/renamesummary.tmpl
new file mode 100644
index 0000000..60f81b3
--- /dev/null
+++ b/srv/templates/renamesummary.tmpl
@@ -0,0 +1,26 @@
+<TMPL_IF ERROR>
+<p>
+<b>Failed to rename <TMPL_VAR SRC> to <TMPL_VAR DEST>: </b>
+<TMPL_VAR ERROR>
+</p>
+<TMPL_ELSE>
+<p>
+<b>Successfully renamed <TMPL_VAR SRC> to <TMPL_VAR DEST>.</b>
+</p>
+<p>
+<TMPL_IF FIXEDLINKS>
+The following pages have been automatically modified to update their links to <TMPL_VAR DEST>:
+<ul>
+<TMPL_LOOP NAME=FIXEDLINKS><li><TMPL_VAR PAGE></li></TMPL_LOOP>
+</ul>
+</TMPL_IF>
+<TMPL_IF BROKENLINKS_CHECKED>
+<TMPL_IF BROKENLINKS>
+The following pages still link to <TMPL_VAR SRC>:
+<ul>
+<TMPL_LOOP NAME=BROKENLINKS><li><TMPL_VAR PAGE></li></TMPL_LOOP>
+</ul>
+</TMPL_IF>
+</TMPL_IF>
+</p>
+</TMPL_IF>
diff --git a/srv/templates/rssitem.tmpl b/srv/templates/rssitem.tmpl
new file mode 100644
index 0000000..a61b92b
--- /dev/null
+++ b/srv/templates/rssitem.tmpl
@@ -0,0 +1,29 @@
+<item>
+ <TMPL_IF NAME="AUTHOR">
+ <title><TMPL_VAR AUTHOR ESCAPE=HTML>: <TMPL_VAR TITLE></title>
+ <dcterms:creator><TMPL_VAR AUTHOR ESCAPE=HTML></dcterms:creator>
+ <TMPL_ELSE>
+ <title><TMPL_VAR TITLE></title>
+ </TMPL_IF>
+ <TMPL_IF NAME="GUID">
+ <guid isPermaLink="no"><TMPL_VAR GUID></guid>
+ <TMPL_ELSE>
+ <guid><TMPL_VAR URL></guid>
+ </TMPL_IF>
+ <link><TMPL_VAR PERMALINK></link>
+ <TMPL_IF NAME="CATEGORIES">
+ <TMPL_LOOP NAME="CATEGORIES">
+ <category><TMPL_VAR CATEGORY></category>
+ </TMPL_LOOP>
+ </TMPL_IF>
+ <pubDate><TMPL_VAR CDATE_822></pubDate>
+ <dcterms:modified><TMPL_VAR MDATE_3339></dcterms:modified>
+ <TMPL_IF NAME="ENCLOSURE">
+ <enclosure url="<TMPL_VAR ENCLOSURE>" type="<TMPL_VAR TYPE>" length="<TMPL_VAR LENGTH>" />
+ <TMPL_ELSE>
+ <description><TMPL_VAR CONTENT ESCAPE=HTML></description>
+ </TMPL_IF>
+ <TMPL_IF NAME="COMMENTSURL">
+ <comments><TMPL_VAR NAME="COMMENTSURL"></comments>
+ </TMPL_IF>
+</item>
diff --git a/srv/templates/rsspage.tmpl b/srv/templates/rsspage.tmpl
new file mode 100644
index 0000000..e54094a
--- /dev/null
+++ b/srv/templates/rsspage.tmpl
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<rss version="2.0"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:dcterms="http://purl.org/dc/terms/" >
+<channel>
+<title><TMPL_VAR TITLE></title>
+<link><TMPL_VAR PAGEURL></link>
+<description><TMPL_VAR FEEDDESC ESCAPE=HTML></description>
+<TMPL_VAR CONTENT>
+</channel>
+</rss>
diff --git a/srv/templates/searchform.tmpl b/srv/templates/searchform.tmpl
new file mode 100644
index 0000000..afae2eb
--- /dev/null
+++ b/srv/templates/searchform.tmpl
@@ -0,0 +1,5 @@
+<form method="get" action="<TMPL_VAR SEARCHACTION>" id="searchform">
+<div>
+<input type="text" id="searchbox" name="P" value="" size="16" />
+</div>
+</form>
diff --git a/srv/templates/searchquery.tmpl b/srv/templates/searchquery.tmpl
new file mode 100644
index 0000000..782b12c
--- /dev/null
+++ b/srv/templates/searchquery.tmpl
@@ -0,0 +1,112 @@
+$setmap{prefix,title,S}
+$setmap{prefix,link,XLINK}
+$set{thousand,$.}$set{decimal,.}$setmap{BN,,Any Country,uk,England,fr,France}
+${
+$def{PREV,
+$if{$ne{$topdoc,0},<INPUT TYPE=image NAME="&lt;" ALT="&lt;"
+SRC="/images/xapian-omega/prev.png" BORDER=0 HEIGHT=30 WIDTH=30>,
+<IMG ALT="" SRC="/images/xapian-omega/prevoff.png" HEIGHT=30 WIDTH=30>}
+}
+
+$def{NEXT,
+$if{$ne{$last,$msize},<INPUT TYPE=image NAME="&gt;" ALT="&gt;"
+SRC="/images/xapian-omega/next.png" BORDER=0 HEIGHT=30 WIDTH=30>,
+<IMG ALT="" SRC="/images/xapian-omega/nextoff.png" HEIGHT=30 WIDTH=30>}
+}
+
+$def{P,<INPUT TYPE=image NAME="$1" VALUE="$1" SRC="/images/xapian-omega/page-$2.png" BORDER=0$opt{a} ALT="$1">}
+$def{PAGE,$if{$gt{$1,9},$if{$gt{$1,99},$P{$1,$div{$1,100}}}$P{$1,$mod{$div{$1,10},10}}}$P{$1,$mod{$1,10}}}
+
+$def{S,<IMG SRC="/images/xapian-omega/page-$2s.png"$opt{a} ALT=$1>}
+$def{SPAGE,$if{$gt{$1,9},$if{$gt{$1,99},$S{$1,$div{$1,100}}}$S{$1,$mod{$div{$1,10},10}}}$S{$1,$mod{$1,10}}}
+}
+
+$def{PREV,$if{$ne{$topdoc,0},<INPUT TYPE=submit NAME="&lt;" VALUE="Previous">}}
+
+$def{PAGE,<INPUT TYPE=submit NAME="[" VALUE="$1">}
+
+$def{SPAGE,<INPUT TYPE=submit NAME="[" VALUE="$1" DISABLED=disabled>}
+
+$def{NEXT,$if{$ne{$last,$msize},<INPUT TYPE=submit NAME="&gt;" VALUE="Next">}}
+
+<p>
+
+<FORM NAME=P METHOD=GET
+ACTION="$html{$env{CGIURL}}" TARGET="_top">
+<center>
+<INPUT NAME=P VALUE="$html{$query}" SIZE=65>
+<INPUT TYPE=SUBMIT VALUE="Search">
+$env{HELPLINK}
+<hr>
+<SELECT NAME=DEFAULTOP>
+<OPTION VALUE=or $if{$eq{$defaultop,or},SELECTED}>Matching any words
+<OPTION VALUE=and $if{$eq{$defaultop,and},SELECTED}>Matching all words
+</SELECT>
+$or{$html{$error},
+$if{$eq{$msize,0},
+$if{$query,No documents match your query,
+<hr>Searching $nice{$dbsize} documents
+},
+$if{$not{$msizeexact},
+ $nice{$add{$topdoc,1}}-$nice{$last} of about $nice{$msize} matches,
+ $if{$and{$eq{$last,$msize},$eq{$topdoc,0}},
+ All $nice{$msize} matches,
+ $nice{$add{$topdoc,1}}$if{$ne{$add{$topdoc,1},$last},-$nice{$last}} of exactly $nice{$msize} matches}
+}
+<hr>
+</center>
+$list{$map{$queryterms,$list{$html{$uniq{$unstem{$_}}},<b>,</b>/<b>,</b>}:&nbsp;$nice{$freq{$_}}},Term frequencies: ,$. ,}
+<br><small>Search took $time seconds</small>
+<table>
+$hitlist{<tr><td valign=top>
+${<IMG SRC="/images/xapian-omega/score-$div{$percentage,10}.png" ALT="$percentage%" HEIGHT=16 WIDTH=32>}
+<div title="$percentage%" style='float:left;width:60px;height:10px;border:1px solid black;margin-top:4px;'>
+<div style='width:$div{$mul{$percentage,6},10}px; height:10px; background-color: red;'>
+</div></div>
+<div style='float:left;margin-top:2px;font-size:x-small;'>
+<span title="$html{$date{$field{modtime},%Y-%m-%d %H:%M:%S}}">
+Modified:<br><b>$html{$date{$field{modtime},%Y-%m-%d}}</b></span><br>
+$if{$field{language},Language: <b>$html{$field{language}}</b><br>}
+$if{$field{size},<span title="$html{$field{size}} bytes">Size: <b>$html{$filesize{$field{size}}}</b></span><br>}
+</div>
+</td>
+<td><B><A HREF="$field{url}">$html{$or{$field{caption},$field{title},$field{url},Untitled}}</A></B><BR>
+<small>$highlight{$field{sample},$terms}$if{$field{sample},...}</small><br>
+<small>
+$percentage% relevant$. matching:
+<i>$list{$map{$terms,$html{$prettyterm{$_}}},$. ,</i> and <i>}</i></small>${for lynx:}<p></td></tr>}
+</table>
+
+<br><center>
+
+${suppress next, prev, and page links if there's only one page}
+$if{$ne{$lastpage,1},
+$set{a,$if{$opt{pagelink_height}, HEIGHT=$opt{pagelink_height}}$if{$opt{pagelink_width}, WIDTH=$opt{pagelink_width}}}
+
+${1-W ... X-(this)-Y ...}
+$set{w,$min{3,$add{$thispage,-1}}}
+$set{x,$max{$add{$opt{w},1},$add{$thispage,-3}}}
+$set{y,$min{$lastpage,$add{$thispage,8}}}
+$PREV
+$map{$range{1,$opt{w}},$PAGE{$_}}
+$if{$ne{$add{$opt{w},1},$opt{x}},...}
+$map{$range{$opt{x},$add{$thispage,-1}},$PAGE{$_}}
+$SPAGE{$thispage}
+$map{$range{$add{$thispage,1},$opt{y}},$PAGE{$_}}
+$if{$ne{$opt{y},$lastpage},...}
+$NEXT
+}
+}}
+</center><br>
+$if{$dbname,<INPUT TYPE=hidden NAME=DB VALUE="$html{$dbname}">}
+$if{$ne{$topdoc,0},<INPUT TYPE=hidden NAME=TOPDOC VALUE=$topdoc>}
+$if{$ne{$hitsperpage,10},<INPUT TYPE=hidden NAME=HITSPERPAGE VALUE=$hitsperpage>}
+$if{$fmt,<INPUT TYPE=hidden NAME=FMT VALUE="$html{$fmt}">}
+$if{$cgi{COLLAPSE},<INPUT TYPE=hidden NAME=COLLAPSE VALUE="$html{$cgi{COLLAPSE}}">}
+$if{$queryterms,<INPUT TYPE=hidden NAME=xP VALUE="$html{$queryterms}">}
+<INPUT TYPE=hidden NAME=xDB VALUE="$html{$dbname}">
+<INPUT TYPE=hidden NAME=xFILTERS VALUE="$html{$filters}">
+$list{$relevants,<INPUT TYPE=hidden NAME=R VALUE=",.,">}
+$if{$cgi{THRESHOLD},<INPUT TYPE=hidden NAME=THRESHOLD VALUE="$html{$cgi{THRESHOLD}}">}
+</FORM>
+<hr><div align=right><i><small><a href="http://www.xapian.org/">$html{$version}</a></small></i></div>
diff --git a/srv/templates/titlepage.tmpl b/srv/templates/titlepage.tmpl
new file mode 100644
index 0000000..f5cd5bc
--- /dev/null
+++ b/srv/templates/titlepage.tmpl
@@ -0,0 +1 @@
+<p><a href="<TMPL_VAR PAGEURL>"><TMPL_VAR TITLE></a></p>
diff --git a/usr/local/bin/addaccess b/usr/local/bin/addaccess
new file mode 100755
index 0000000..6f734f6
--- /dev/null
+++ b/usr/local/bin/addaccess
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec /usr/bin/sudo /usr/local/sbin/addaccess "$@"
diff --git a/usr/local/bin/createuser b/usr/local/bin/createuser
new file mode 120000
index 0000000..e9d7937
--- /dev/null
+++ b/usr/local/bin/createuser
@@ -0,0 +1 @@
+newuser \ No newline at end of file
diff --git a/usr/local/bin/newrepo b/usr/local/bin/newrepo
new file mode 100755
index 0000000..05ce120
--- /dev/null
+++ b/usr/local/bin/newrepo
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec /usr/bin/sudo /usr/local/sbin/newrepo "$@"
diff --git a/usr/local/bin/newuser b/usr/local/bin/newuser
new file mode 100755
index 0000000..841b47d
--- /dev/null
+++ b/usr/local/bin/newuser
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec /usr/bin/sudo /usr/local/sbin/newuser
diff --git a/usr/local/bin/pinyshell b/usr/local/bin/pinyshell
new file mode 100755
index 0000000..0db88a8
--- /dev/null
+++ b/usr/local/bin/pinyshell
@@ -0,0 +1,5 @@
+#!/bin/sh
+cd /srv/rbin
+export PATH=/srv/rbin
+
+exec /bin/rbash "$@"
diff --git a/usr/local/bin/rmaccess b/usr/local/bin/rmaccess
new file mode 100755
index 0000000..6c40690
--- /dev/null
+++ b/usr/local/bin/rmaccess
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec /usr/bin/sudo /usr/local/sbin/rmaccess "$@"
diff --git a/usr/local/bin/rmrepo b/usr/local/bin/rmrepo
new file mode 100755
index 0000000..53bf029
--- /dev/null
+++ b/usr/local/bin/rmrepo
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec /usr/bin/sudo /usr/local/sbin/rmrepo "$@"
diff --git a/usr/local/sbin/addaccess b/usr/local/sbin/addaccess
new file mode 100755
index 0000000..07cc893
--- /dev/null
+++ b/usr/local/sbin/addaccess
@@ -0,0 +1,39 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+my( $reponame, $uid, $gitowner);
+
+if ( ( ! scalar $ARGV[1] ) or ( scalar $ARGV[2] ) ) { # must have exactly two arguments
+ print( "Usage: addaccess USER REPONAME\n" );
+ exit( 1 );
+} elsif ( ( $ARGV[0] !~ /^[a-zA-Z0-9_.][a-zA-Z0-9_.-]+$/ ) or ( $ARGV[1] !~ /^[a-z0-9][a-z0-9+.-]+$/ ) ) { # Extra paranoid sanity checking
+ print( "Usage: addaccess USER REPONAME\n" );
+ print( " USER must consist only of letters, digits, underscores, periods, and dashes, and not start with a dash.\n" );
+ print( " REPONAME must consist only of lower case letters (a-z), digits (0-9), plus (+) and minus (-) signs, and periods (.).\n" );
+ print( " REPONAME must be at least two characters long and must start with an alphanumeric character.\n" );
+ exit( 1 );
+} else {
+ $reponame = $ARGV[1];
+};
+
+open (PASSWD, '/etc/passwd');
+while(<PASSWD>) {
+ if( $_ =~ /^$ENV{SUDO_USER}:.+?:(.+?):/ ) { $uid = $1; }; # grabbing uid.
+};
+close(PASSWD);
+
+unless( -d "/srv/git/$reponame.git" ) {
+ print( "/srv/git/$reponame.git doesn't exist!\n" );
+ exit( 2 );
+};
+
+$gitowner = (stat( "/srv/git/$reponame.git" ))[4]; # grab owner uid of repository
+
+if( ( $gitowner != $uid ) and ( $gitowner != 65534 ) ) {
+ print( "$reponame is not owned by you!\n" );
+ exit( 3 );
+};
+
+system( "/usr/sbin/adduser $ARGV[0] git-$reponame" );
diff --git a/usr/local/sbin/newrepo b/usr/local/sbin/newrepo
new file mode 100755
index 0000000..7988117
--- /dev/null
+++ b/usr/local/sbin/newrepo
@@ -0,0 +1,226 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+my( $errorto ) = 'jrayhawk+piny.svcs.cs.pdx.edu@omgwallhack.org'; # Email address to send horrible errors to.
+my( $reponame, $email, @errors, $wikilisttempfile, $cgitrctempfile);
+
+if ( ( ! scalar $ARGV[0] ) or ( scalar $ARGV[1] ) or ( $ARGV[0] !~ /^[a-z0-9][a-z0-9+.-]+$/ ) ) {
+ print( "Usage: newrepo REPONAME\n" );
+ print( " REPONAME must consist only of lower case letters (a-z), digits (0-9), plus (+) and minus (-) signs, and periods (.).\n" );
+ print( " REPONAME must be at least two characters long and must start with an alphanumeric character.\n" );
+ exit( 1 );
+} else {
+ $reponame = $ARGV[0];
+};
+
+# We want to check to see if
+# 1) $reponame already exists in some form so we don't try to create it, and
+# 2) $reponame is only partially created, in which case we want to email someone who can sanity check and fix it.
+open (PASSWD, '/etc/passwd');
+while(<PASSWD>) {
+ if( $_ =~ /^$ENV{SUDO_USER}:.+?:.+?:.+?:(.+?):/ ) { $email = $1; }; # While we're here, may as well grab the email address.
+ if( $_ =~ /^ikiwiki-$reponame:/ ) { push( @errors, "user ikiwiki-$reponame already exists!\n"); };
+};
+close(PASSWD);
+open (GROUP, '/etc/group');
+while(<GROUP>) {
+ if( $_ =~ /^git-$reponame:/ ) { push( @errors, "group git-$reponame already exists!\n"); };
+};
+close(GROUP);
+if( -d "/srv/git/$reponame.git" ) { push( @errors, "/srv/git/$reponame.git already exists!\n"); };
+if( -d "/srv/ikiwiki/$reponame" ) { push( @errors, "/srv/ikiwiki/$reponame already exists!\n"); };
+if( -d "/srv/www/piny.svcs.cs.pdx.edu/$reponame" ) { push( @errors, "/srv/www/piny.svcs.cs.pdx.edu/$reponame already exists!\n"); };
+if( -d "/srv/www/cgi.piny.svcs.cs.pdx.edu/repos/$reponame" ) { push( @errors, "/srv/www/cgi.piny.svcs.cs.pdx.edu/repos/$reponame already exists!\n"); };
+if( -f "/etc/ikiwiki/piny/$reponame.setup" ) { push( @errors, "/etc/ikiwiki/piny/$reponame.setup already exists!\n"); };
+if( -f "/etc/ikiwiki/wikilist.d/$reponame" ) { push( @errors, "/etc/ikiwiki/wikilist.d/$reponame already exists!\n"); };
+if( -f "/etc/apache2/piny-available/$reponame" ) { push( @errors, "/etc/apache2/piny-available/$reponame already exists!\n"); };
+if( -f "/etc/cgitrc.d/$reponame" ) { push( @errors, "/etc/cgitrc.d/$reponame already exists!\n"); };
+
+if( @errors ) {
+ if( @errors == 10 ) { # Everything's fine, nothing is broken
+ print( "$reponame already exists!\n" );
+ } else { # IT'S ARMAGEDDON
+ open ( MAIL, "|/usr/lib/sendmail -t" );
+ print( MAIL "To: $errorto\n" );
+ print( MAIL "From: newrepo\@piny.svcs.cs.pdx.edu\n" );
+ print( MAIL "Subject: Piny error: $ENV{SUDO_USER} found inconsistent $reponame in the creation process!\n" );
+ print( MAIL "MIME-Version: 1.0\n" );
+ print( MAIL "Content-Type: text/plain; charset=us-ascii\n" );
+ print( MAIL "\n" );
+ print( MAIL "@errors\n" );
+ close( MAIL );
+ print( "$reponame already exists but is in an inconsistent state! The Piny admins probably screwed up; they have been notified and will take a look at it.\n" );
+ };
+ exit( 2 );
+};
+
+
+# CREATE USER/GROUPS
+unless( system( "mkdir /srv/git/$reponame.git" ) == 0 ) { # We need a locking or atomic operation as our first to check against simultaneous execution.
+ print( "I suspect that you are attempting to create the same repo multiple times simultaneously.\n" );
+ exit( 3 );
+};
+system( "/usr/sbin/addgroup --quiet git-$reponame" );
+system( "/usr/sbin/adduser --quiet --system --group --gecos $reponame ikiwiki-$reponame" );
+system( "/usr/sbin/adduser --quiet ikiwiki-$reponame git-$reponame | grep -v 'Adding user'" );
+system( "/usr/sbin/adduser --quiet $ENV{SUDO_USER} git-$reponame | grep -v 'Adding user '" );
+
+# CREATE REPO
+system( "GIT_DIR=/srv/git/$reponame.git /usr/bin/git init --template=/srv/git-template.git --quiet --shared" );
+open ( DESC, ">/srv/git/$reponame.git/description" );
+print( DESC "$reponame owned by $email" );
+close( DESC );
+# ln -f post-receive /srv/git/$reponame.git/hooks/ # turn on e-mail commit notices
+system( "/bin/chown -R $ENV{SUDO_USER}.git-$reponame /srv/git/$reponame.git/" );
+system( "/bin/chown -R ikiwiki-$reponame.ikiwiki-$reponame /srv/git/$reponame.git/hooks/" );
+system( "/bin/touch /srv/git/$reponame.git/git-daemon-export-ok" );
+
+# WRITE IKIWIKI SETUP FILE
+open ( SETUP, ">/etc/ikiwiki/piny/$reponame.setup" );
+print( SETUP
+'#!/usr/bin/perl
+# Configuration file for ikiwiki.
+# Passing this to ikiwiki --setup will make ikiwiki generate wrappers and
+# build the wiki.
+#
+# Remember to re-run ikiwiki --setup any time you edit this file.
+
+use IkiWiki::Setup::Standard {
+ wikiname => \'' . $reponame . '\', # PINY
+ adminemail => \'' . $email . '\', # PINY
+ srcdir => \'/srv/ikiwiki/' . $reponame . '\', # PINY
+ destdir => \'/srv/www/piny.svcs.cs.pdx.edu/' . $reponame . '\', # PINY
+ url => \'http://piny.svcs.cs.pdx.edu/' . $reponame . '\', # PINY
+ cgiurl => \'https://cgi.piny.svcs.cs.pdx.edu/repos/' . $reponame . '/ikiwiki.cgi\', # PINY
+ historyurl => \'https://cgi.piny.svcs.cs.pdx.edu/gitweb.cgi?p=' . $reponame . '.git;a=history;f=[[file]]\', # PINY
+ diffurl => \'https://cgi.piny.svcs.cs.pdx.edu/gitweb.cgi?p=' . $reponame . ';a=blobdiff;f=doc/[[file]];h=[[sha1_to]];hp=[[sha1_from]];hb=[[sha1_commit]];hpb=[[sha1_parent]]\', # PINY
+
+ templatedir => "/srv/templates",
+ underlaydir => "/etc/ikiwiki/share/underlay",
+
+ rcs => "git",
+ gitorigin_branch => "origin",
+ gitmaster_branch => "master",
+
+ wrappers => [
+ {
+ cgi => 1,
+ wrapper => \'/srv/www/cgi.piny.svcs.cs.pdx.edu/repos/' . $reponame . '/ikiwiki.cgi\', # PINY
+ wrappermode => "06755",
+ wrappergroup => \'git-' . $reponame . '\', # PINY
+ },
+ {
+ wrapper => \'/srv/git/' . $reponame . '.git/hooks/post-update\', # PINY
+ wrappermode => "06755",
+ wrappergroup => \'git-' . $reponame . '\', # PINY
+
+ notify => 0,
+ },
+ ],
+
+ # Generate rss feeds for blogs?
+ rss => 1,
+ # Generate atom feeds for blogs?
+ atom => 0,
+ # Include discussion links on all pages?
+ discussion => 0,
+ # To exclude files matching a regexp from processing. This adds to
+ # the default exclude list.
+ #exclude => qr/*\.wav/,
+ # To change the extension used for generated html files.
+ #htmlext => "htm",
+ # Time format (for strftime)
+ #timeformat => "%c",
+ # Locale to use. Must be a UTF-8 locale.
+ #locale => "en_US.UTF-8",
+ # Only send cookies over SSL connections.
+ sslcookie => 1,
+ # Logging settings:
+ verbose => 0,
+ syslog => 1,
+ # To link to user pages in a subdirectory of the wiki.
+ #userdir => "users",
+ # To create output files named page.html rather than page/index.html.
+ usedirs => 1,
+ # Simple spam prevention: require an account-creation password.
+ #account_creation_password => "example",
+ # Use new "!"-prefixed preprocessor directive syntax
+ prefix_directives => 1,
+ httpauth => 1,
+ # To add plugins, list them here.
+ add_plugins => [qw{sidebar toc meta table tag httpauth attachment rename remove autoindex map teximg version edittemplate}],
+ disable_plugins => [qw{openid passwordauth}],
+ teximg_prefix => \'\\documentclass{scrartcl}
+\\usepackage[version=3]{mhchem}
+\\usepackage{amsmath}
+\\usepackage{amsfonts}
+\\usepackage{amssymb}
+\\pagestyle{empty}
+\\newcommand{\unit}[1]{\\ensuremath{\\, \\mathrm{#1}}}
+\\begin{document}\',
+
+ teximg_dvipng => 1,
+
+ # For use with the tag plugin, make all tags be located under a
+ # base page.
+ tagbase => "tag",
+
+ # For use with the search plugin if your estseek.cgi is located
+ # somewhere else.
+ #estseek => "/usr/lib/estraier/estseek.cgi",
+}');
+close( SETUP );
+open ( WIKILIST, '>>/etc/ikiwiki/wikilist' );
+print( WIKILIST "ikiwiki-$reponame /etc/ikiwiki/piny/$reponame.setup\n" );
+close( WIKILIST );
+
+# WRITE APACHE CONFIG
+open ( APACHE, ">/etc/apache2/piny-available/$reponame" );
+print( APACHE '<Directory /srv/www/cgi.piny.svcs.cs.pdx.edu/repos/' . $reponame . '>
+ AuthPAM_Enabled on
+ AuthGROUP_Enabled on
+ AuthPAM_FallThrough off
+ AuthBasicAuthoritative off
+ AuthType Basic
+ AuthName "User access to ' . $reponame . ' repository needed."
+ Require group git-' . $reponame . '
+</Directory>' );
+close( APACHE );
+link( "/etc/apache2/piny-available/$reponame", "/etc/apache2/piny-enabled/$reponame");
+system( '/etc/init.d/apache2 reload | grep -v "Reloading web server config: apache2."' );
+
+
+# CREATE IKIWIKI WORKING DIR
+system( "/usr/bin/git clone --quiet /srv/git/$reponame /srv/ikiwiki/$reponame" );
+mkdir( "/srv/www/piny.svcs.cs.pdx.edu/$reponame" );
+mkdir( "/srv/www/cgi.piny.svcs.cs.pdx.edu/repos/$reponame" );
+system( "/bin/chown -R ikiwiki-$reponame /srv/ikiwiki/$reponame /srv/www/piny.svcs.cs.pdx.edu/$reponame /srv/www/cgi.piny.svcs.cs.pdx.edu/repos/$reponame" );
+
+open ( WIKILIST, ">/etc/ikiwiki/wikilist.d/$reponame" ); # Maybe someday ikiwiki will support wikilist.d.
+print( WIKILIST "ikiwiki-$reponame /etc/ikiwiki/piny/$reponame.setup\n" ); # In the meantime, we fake it.
+close( WIKILIST );
+$wikilisttempfile = `/bin/mktemp`;
+chomp( $wikilisttempfile );
+system( "/bin/cat /etc/ikiwiki/wikilist.d/* > $wikilisttempfile" );
+chmod ( 0644, $wikilisttempfile );
+system( "/bin/mv $wikilisttempfile /etc/ikiwiki/wikilist" ); # This is marginally racy, but the consequences are probably ignorable.
+
+open ( CGITRC, ">/etc/cgitrc.d/$reponame" ); # Maybe someday cgit will support cgitrc.d.
+print( CGITRC
+"repo.url=$reponame
+repo.path=/srv/git/$reponame.git
+repo.desc=$reponame
+repo.owner=$email
+
+" ); # In the meantime, we fake it.
+close( CGITRC );
+$cgitrctempfile = `/bin/mktemp`;
+chomp( $cgitrctempfile );
+system( "/bin/cat /etc/cgitrc.d/* > $cgitrctempfile" );
+chmod ( 0644, $cgitrctempfile );
+system( "/bin/mv $cgitrctempfile /etc/cgitrepos" ); # This is marginally racy, but the consequences are minor.
+
+# COMPILE
+system( "/usr/bin/sudo -u ikiwiki-$reponame /usr/bin/ikiwiki --setup /etc/ikiwiki/piny/$reponame.setup | grep -v 'successfully generated'" );
diff --git a/usr/local/sbin/newuser b/usr/local/sbin/newuser
new file mode 100755
index 0000000..e0b175b
--- /dev/null
+++ b/usr/local/sbin/newuser
@@ -0,0 +1,129 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Email::Valid::Loose qw( );
+
+# If they passed any arguments, complain and exit.
+if ( scalar @ARGV ) {
+ print "You can't pass any arguments to this script!\n";
+ exit 2;
+};
+
+# If they didn't provide a terminal definition, then assume xterm.
+# Everybody emulates xterm to at least a basic extent.
+if ( not exists $ENV{"TERM"} ) {
+ $ENV{"TERM"} = "xterm";
+ print "I don't know what terminal you're using; guessing xterm...\n";
+};
+
+# Disable buffering.
+$|++;
+
+# Configure the strictness of our email checks.
+my $checker = Email::Valid::Loose->new
+ ( "-fqdn" => 1
+ , "-fudge" => 0
+ , "-local_rules" => 0
+ , "-mxcheck" => 1
+ , "-tldcheck" => 0
+ );
+
+my ( $email, $username, $password1, $password2 );
+
+while ( 1 ) {
+
+ print "Your email address: ";
+ chomp ( $email = <STDIN> );
+
+ if ( $email eq "" ) {
+ print "You must provide an email address!\n";
+ next;
+ };
+
+ $email = $checker->address( $email );
+ if ( not defined $email ) {
+ print "Please, at least pretend to provide a valid email address.\n";
+ next;
+ };
+
+ last;
+
+};
+
+while ( 1 ) {
+
+ print "Desired username: ";
+ chomp ( $username = <STDIN> );
+
+ if ( $username eq "" ) {
+ print "You have to enter a username!\n";
+ next;
+ };
+
+ if ( $username =~ /^git-|^ikiwiki-/ ) {
+ print "Your username cannot start with git- or ikiwiki-!\n";
+ next
+ };
+
+ if ( $username !~ /^[a-zA-Z0-9_.][a-zA-Z0-9_.-]+$/ ) {
+ print( "Usernames must consist only of letters, digits, underscores, periods, and dashes, and not start with a dash. Usernames are case sensitive.\n" );
+ next
+ };
+
+ last;
+
+};
+
+while ( 1 ) {
+
+ system( "stty", "-echo" );
+ print "Desired password: ";
+ chomp ( $password1 = <STDIN> );
+ print "\nRetype password: ";
+ chomp ( $password2 = <STDIN> );
+ print "\n";
+ system( "stty", "echo" );
+
+ if ( $password1 ne $password2 ) {
+ print "Provided passwords do not match; try again.\n";
+ next;
+ };
+
+ if ( $password1 eq "" ) {
+ print "You have to enter a password!\n";
+ next;
+ };
+
+ last;
+
+};
+
+my @saltchars =
+ ( 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
+ , 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
+ , '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
+ , '.', '/'
+ );
+
+my $salt = "\$6\$";
+
+foreach my $n ( 1 .. 16 ) {
+ $salt .= $saltchars[int ( rand ( scalar @saltchars ) )];
+};
+
+$salt .= "\$";
+
+my $crypt = crypt( $password1, $salt );
+
+my $ret = system( "/usr/sbin/useradd", "-c", "$email", "-k", "/var/empty", "-g", "users", "-m", "-p", $crypt, "-s", "/usr/local/bin/pinyshell", $username );
+
+if ( $ret ) {
+ print "An error occured creating the user; most likely, that username is already taken.\n";
+ exit 1;
+};
+
+print "Your user has been created. Try logging in!\n";
+
+exit 0;
diff --git a/usr/local/sbin/rmaccess b/usr/local/sbin/rmaccess
new file mode 100755
index 0000000..2f7e06e
--- /dev/null
+++ b/usr/local/sbin/rmaccess
@@ -0,0 +1,39 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+my( $reponame, $uid, $gitowner);
+
+if ( ( ! scalar $ARGV[1] ) or ( scalar $ARGV[2] ) ) { # must have exactly two arguments
+ print( "Usage: rmaccess USER REPONAME\n" );
+ exit( 1 );
+} elsif ( ( $ARGV[0] !~ /^[a-zA-Z0-9_.][a-zA-Z0-9_.-]+$/ ) or ( $ARGV[1] !~ /^[a-z0-9][a-z0-9+.-]+$/ ) ) { # Extra paranoid sanity checking
+ print( "Usage: rmaccess USER REPONAME\n" );
+ print( " USER must consist only of letters, digits, underscores, periods, and dashes, and not start with a dash.\n");
+ print( " REPONAME must consist only of lower case letters (a-z), digits (0-9), plus (+) and minus (-) signs, and periods (.).\n" );
+ print( " REPONAME must be at least two characters long and must start with an alphanumeric character.\n" );
+ exit( 1 );
+} else {
+ $reponame = $ARGV[1];
+};
+
+open (PASSWD, '/etc/passwd');
+while(<PASSWD>) {
+ if( $_ =~ /^$ENV{SUDO_USER}:.+?:(.+?):/ ) { $uid = $1; }; # grabbing uid.
+};
+close(PASSWD);
+
+unless( -d "/srv/git/$reponame.git" ) {
+ print( "/srv/git/$reponame.git doesn't exist!\n" );
+ exit( 2 );
+};
+
+$gitowner = (stat( "/srv/git/$reponame.git" ))[4]; # grab owner uid of repository
+
+if( ( $gitowner != $uid ) and ( $gitowner != 65534 ) ) {
+ print( "$reponame is not owned by you!\n" );
+ exit( 3 );
+};
+
+system( "/usr/sbin/deluser $ARGV[0] git-$reponame" );
diff --git a/usr/local/sbin/rmrepo b/usr/local/sbin/rmrepo
new file mode 100755
index 0000000..3905412
--- /dev/null
+++ b/usr/local/sbin/rmrepo
@@ -0,0 +1,64 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+my( $reponame, $uid, $gitowner, $wikilisttempfile, $cgitrctempfile);
+
+if ( ( ! scalar $ARGV[0] ) or ( scalar $ARGV[1] ) or ( $ARGV[0] !~ /^[a-z0-9][a-z0-9+.-]+$/ ) ) {
+ print( "Usage: rmrepo REPONAME\n" );
+ exit( 1 );
+} else {
+ $reponame = $ARGV[0];
+};
+
+open (PASSWD, '/etc/passwd');
+while(<PASSWD>) {
+ if( $_ =~ /^$ENV{SUDO_USER}:.+?:(.+?):/ ) { $uid = $1; }; # grabbing uid.
+};
+close(PASSWD);
+
+unless( -d "/srv/git/$reponame.git" ) {
+ print( "/srv/git/$reponame.git doesn't exist!\n" );
+ exit( 2 );
+};
+
+$gitowner = (stat "/srv/git/$reponame.git")[4];
+
+if( ( $gitowner != $uid ) and ( $gitowner != 65534 ) ) {
+ print( "$reponame is not owned by you!\n" );
+ exit( 3 );
+};
+
+# We have to be careful about how we delete things; we don't want have post-update or ikiwiki.cgi thrashing, and we REALLY don't want to leave remappable owner UIDs around, but we're also keying security on /srv/git/$reponame
+system( "/bin/chown -R nobody.nogroup /srv/git/$reponame.git" );
+
+unlink( "/etc/ikiwiki/wikilist.d/$reponame" );
+$wikilisttempfile = `/bin/mktemp`;
+chomp ( $wikilisttempfile );
+system( "/bin/cat /etc/ikiwiki/wikilist.d/* > $wikilisttempfile" );
+chmod ( 0644, $wikilisttempfile );
+system( "/bin/mv $wikilisttempfile /etc/ikiwiki/wikilist" ); # This is marginally racy, but the consequences are probably ignorable.
+
+unlink( "/etc/cgitrc.d/$reponame" );
+$cgitrctempfile = `/bin/mktemp`;
+chomp ( $cgitrctempfile );
+system( "/bin/cat /etc/cgitrc.d/* > $cgitrctempfile" );
+chmod ( 0644, $cgitrctempfile );
+system( "/bin/mv $cgitrctempfile /etc/cgitrepos" ); # This is marginally racy, but the consequences are probably ignorable.
+
+system( "/bin/rm -r /srv/www/piny.svcs.cs.pdx.edu/$reponame" );
+system( "/bin/rm -r /srv/www/cgi.piny.svcs.cs.pdx.edu/repos/$reponame" );
+
+unlink( "/etc/ikiwiki/piny/$reponame.setup" );
+system( "/bin/rm -r /srv/ikiwiki/$reponame" );
+
+unlink( "/etc/apache2/piny-available/$reponame" );
+unlink( "/etc/apache2/piny-enabled/$reponame" );
+system( '/etc/init.d/apache2 reload | grep -v "Reloading web server config: apache2."' );
+
+system( "/usr/sbin/delgroup --quiet git-$reponame" );
+system( "/usr/sbin/deluser --quiet --remove-home ikiwiki-$reponame" );
+system( "/usr/sbin/delgroup --quiet ikiwiki-$reponame" );
+
+system( "/bin/rm -rf /srv/git/$reponame.git" );