mirror of https://github.com/xvxx/phd
Compare commits
No commits in common. 'master' and 'v0.1.10' have entirely different histories.
@ -1,74 +1,74 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "alphanumeric-sort"
|
name = "alphanumeric-sort"
|
||||||
version = "1.4.4"
|
version = "1.0.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "77e9c9abb82613923ec78d7a461595d52491ba7240f3c64c0bbe0e6d98e0fce0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "content_inspector"
|
name = "content_inspector"
|
||||||
version = "0.2.4"
|
version = "0.2.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b7bda66e858c683005a53a9a60c69a4aca7eeaa45d124526e389f7aec8e62f38"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f629dc602392d3ec14bfc8a09b5e644d7ffd725102b48b81e59f90f2633621d7"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.66"
|
version = "0.2.66"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.2.1"
|
version = "2.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num_cpus"
|
name = "num_cpus"
|
||||||
version = "1.11.1"
|
version = "1.11.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "76dac5ed2a876980778b8b85f75a71b6cbf0db0b1232ee12f826bccb00d09d72"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hermit-abi",
|
"hermit-abi 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc",
|
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "phd"
|
name = "phd"
|
||||||
version = "0.1.15"
|
version = "0.1.10"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"alphanumeric-sort",
|
"alphanumeric-sort 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"content_inspector",
|
"content_inspector 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"shell-escape",
|
"shell-escape 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"threadpool",
|
"threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shell-escape"
|
name = "shell-escape"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "170a13e64f2a51b77a45702ba77287f5c6829375b04a69cf2222acd17d0cfab9"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "threadpool"
|
name = "threadpool"
|
||||||
version = "1.7.1"
|
version = "1.7.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num_cpus",
|
"num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
"checksum alphanumeric-sort 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "f37ce94154d73f6961f87571a3ab7814e1608f373bd55a933e3e771b6dd59fc4"
|
||||||
|
"checksum content_inspector 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b7bda66e858c683005a53a9a60c69a4aca7eeaa45d124526e389f7aec8e62f38"
|
||||||
|
"checksum hermit-abi 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f629dc602392d3ec14bfc8a09b5e644d7ffd725102b48b81e59f90f2633621d7"
|
||||||
|
"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
|
||||||
|
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
|
||||||
|
"checksum num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76dac5ed2a876980778b8b85f75a71b6cbf0db0b1232ee12f826bccb00d09d72"
|
||||||
|
"checksum shell-escape 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "170a13e64f2a51b77a45702ba77287f5c6829375b04a69cf2222acd17d0cfab9"
|
||||||
|
"checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865"
|
||||||
|
@ -1,206 +0,0 @@
|
|||||||
.\" Generated by scdoc 1.11.0
|
|
||||||
.\" Complete documentation for this program is not available as a GNU info page
|
|
||||||
.ie \n(.g .ds Aq \(aq
|
|
||||||
.el .ds Aq '
|
|
||||||
.nh
|
|
||||||
.ad l
|
|
||||||
.\" Begin generated content:
|
|
||||||
.TH "PHD" "1" "2020-06-27"
|
|
||||||
.P
|
|
||||||
.SH NAME
|
|
||||||
.P
|
|
||||||
phd - an estoeric gopher server
|
|
||||||
.P
|
|
||||||
.SH SYNOPSIS
|
|
||||||
.P
|
|
||||||
\fBphd\fR [\fIOPTIONS\fR] [\fISITE ROOT\fR]
|
|
||||||
.P
|
|
||||||
.SH DESCRIPTION
|
|
||||||
.P
|
|
||||||
\fBphd\fR is a small, easy-to-use gopher server.
|
|
||||||
.P
|
|
||||||
Point it at a directory and it'll serve up all the text files,
|
|
||||||
sub-directories, and binary files over Gopher. Any \fB.gph\fR files will
|
|
||||||
be served up as Gophermaps and executable \fB.gph\fR files will be
|
|
||||||
run as a program with their output served to the client, like the
|
|
||||||
glorious cgi-bin days of yore!
|
|
||||||
.P
|
|
||||||
Usually \fBphd\fR is started with a path to your Gopher site:
|
|
||||||
.P
|
|
||||||
.RS 4
|
|
||||||
phd /srv/gopher
|
|
||||||
.P
|
|
||||||
.RE
|
|
||||||
If no path is given, \fBphd\fR will use the current directory as the root
|
|
||||||
of your Gopher site.
|
|
||||||
.P
|
|
||||||
.SH OPTIONS
|
|
||||||
.P
|
|
||||||
\fB-r\fR \fISELECTOR\fR, \fB--render\fR \fISELECTOR\fR
|
|
||||||
.P
|
|
||||||
.RS 4
|
|
||||||
Rather than start as a server, render the \fISELECTOR\fR of the site using the options provided and print the raw response to \fBSTDOUT\fR.
|
|
||||||
.P
|
|
||||||
.RE
|
|
||||||
\fB-b\fR \fIADDRESS\fR, \fB--bind\fR \fIADDRESS\fR
|
|
||||||
.RS 4
|
|
||||||
Set the socket address to bind to, e.g. \fB127.0.0.1:7070\fR
|
|
||||||
.P
|
|
||||||
.RE
|
|
||||||
\fB-p\fR \fIPORT\fR, \fB--port\fR \fIPORT\fR
|
|
||||||
.RS 4
|
|
||||||
Set the \fIPORT\fR to use when generating Gopher links.
|
|
||||||
.P
|
|
||||||
.RE
|
|
||||||
\fB-h\fR \fIHOST\fR, \fB--host\fR \fIHOST\fR
|
|
||||||
.RS 4
|
|
||||||
Set the \fIHOST\fR to use when generating Gopher links.
|
|
||||||
.P
|
|
||||||
.RE
|
|
||||||
\fB-h\fR, \fB--help\fR
|
|
||||||
.RS 4
|
|
||||||
Print a help summary and exit.
|
|
||||||
.P
|
|
||||||
.RE
|
|
||||||
\fB-v\fR, \fB--version\fR
|
|
||||||
.RS 4
|
|
||||||
Print version information and exit.
|
|
||||||
.P
|
|
||||||
.RE
|
|
||||||
.SH SPECIAL FILES
|
|
||||||
.P
|
|
||||||
The following files have special behavior when present in a directory
|
|
||||||
that \fBphd\fR is tasked with serving:
|
|
||||||
.P
|
|
||||||
\fBheader.gph\fR
|
|
||||||
.RS 4
|
|
||||||
If it exists in a directory, its content will be shown above the directory's content. Put ASCII art in it.
|
|
||||||
.P
|
|
||||||
.RE
|
|
||||||
\fBfooter.gph\fR
|
|
||||||
.RS 4
|
|
||||||
Same, but will be shown below a directory's content.
|
|
||||||
.P
|
|
||||||
.RE
|
|
||||||
\fBindex.gph\fR
|
|
||||||
.RS 4
|
|
||||||
Completely replaces a directory's content with what's in this file.
|
|
||||||
.P
|
|
||||||
.RE
|
|
||||||
\fB??.gph\fR
|
|
||||||
.RS 4
|
|
||||||
Visiting \fBgopher://yoursite/1/dog/\fR will try to render \fBdog.gph\fR from disk. Visiting \fB/1/dog.gph\fR will render the raw content of the .gph file.
|
|
||||||
.P
|
|
||||||
.RE
|
|
||||||
\fB.reverse\fR
|
|
||||||
.RS 4
|
|
||||||
If this exists, the directory contents will be listed in reverse alphanumeric order. Useful for phloggin', if you date your posts.
|
|
||||||
.P
|
|
||||||
.RE
|
|
||||||
.SH GOPHERMAP SYNTAX
|
|
||||||
.P
|
|
||||||
Any line in a \fB.gph\fR file that doesn't contain tabs (\fBt\fR) will get an
|
|
||||||
\fBi\fR automatically prefixed, turning it into a Gopher information item.
|
|
||||||
.P
|
|
||||||
For your convenience, phd supports \fBgeomyidae\fR syntax for
|
|
||||||
creating links:
|
|
||||||
.P
|
|
||||||
.nf
|
|
||||||
.RS 4
|
|
||||||
This is an info line\&.
|
|
||||||
[1|This is a link|/help|server|port]
|
|
||||||
[h|URL Link|URL:https://noogle\&.com]
|
|
||||||
.fi
|
|
||||||
.RE
|
|
||||||
.P
|
|
||||||
\fBserver\fR and \fBport\fR will get translated into the server and port of
|
|
||||||
the actively running server, eg \fBlocalhost\fR and \fB7070\fR.
|
|
||||||
.P
|
|
||||||
Any line containing a tab character (\fBt\fR) will be sent as-is to the
|
|
||||||
client, meaning you can write and serve up raw Gophermap files too.
|
|
||||||
.P
|
|
||||||
.SH DYNAMIC CONTENT
|
|
||||||
.P
|
|
||||||
Any \fB.gph\fR file that is marked \fBexecutable\fR with be run as if it
|
|
||||||
were a standalone program and its output will be sent to the client.
|
|
||||||
It will be passed three arguments: the query string (if any), the
|
|
||||||
server's hostname, and the current port. Do with them what you will.
|
|
||||||
.P
|
|
||||||
For example:
|
|
||||||
.P
|
|
||||||
.nf
|
|
||||||
.RS 4
|
|
||||||
$ cat echo\&.gph
|
|
||||||
#!/bin/sh
|
|
||||||
echo "Hi, world! You said:" $1
|
|
||||||
echo "1Visit Gopherpedia / gopherpedia\&.com 70"
|
|
||||||
.fi
|
|
||||||
.RE
|
|
||||||
.P
|
|
||||||
Then:
|
|
||||||
.P
|
|
||||||
.nf
|
|
||||||
.RS 4
|
|
||||||
$ gopher-client gopher://localhost/1/echo?something
|
|
||||||
[INFO] Hi, world! You said: something
|
|
||||||
[LINK] Visit Gopherpedia
|
|
||||||
.fi
|
|
||||||
.RE
|
|
||||||
.P
|
|
||||||
Or more seriously:
|
|
||||||
.P
|
|
||||||
.nf
|
|
||||||
.RS 4
|
|
||||||
$ cat figlet\&.gph
|
|
||||||
#!/bin/sh
|
|
||||||
figlet $1
|
|
||||||
.fi
|
|
||||||
.RE
|
|
||||||
.P
|
|
||||||
then:
|
|
||||||
.P
|
|
||||||
.nf
|
|
||||||
.RS 4
|
|
||||||
$ gopher-client gopher://localhost/1/figlet?hi gopher
|
|
||||||
[INFO] _ _ _
|
|
||||||
[INFO] | |__ (_) __ _ ___ _ __ | |__ ___ _ __
|
|
||||||
[INFO] | '_ | | / _` |/ _ | '_ | '_ / _ '__|
|
|
||||||
[INFO] | | | | | | (_| | (_) | |_) | | | | __/ |
|
|
||||||
[INFO] |_| |_|_| __, |___/| \&.__/|_| |_|___|_|
|
|
||||||
[INFO] |___/ |_|
|
|
||||||
.fi
|
|
||||||
.RE
|
|
||||||
.P
|
|
||||||
.SS RESOURCES
|
|
||||||
.P
|
|
||||||
geomyidae source code
|
|
||||||
.RS 4
|
|
||||||
gopher://bitreich.org/1/scm/geomyidae/files.gph
|
|
||||||
.P
|
|
||||||
.RE
|
|
||||||
Example Gophermap
|
|
||||||
.RS 4
|
|
||||||
https://github.com/gophernicus/gophernicus/blob/master/README.Gophermap
|
|
||||||
.P
|
|
||||||
.RE
|
|
||||||
Gophermaps
|
|
||||||
.RS 4
|
|
||||||
https://gopher.zone/posts/how-to-gophermap/
|
|
||||||
.P
|
|
||||||
.RE
|
|
||||||
RFC 1436:
|
|
||||||
.RS 4
|
|
||||||
https://tools.ietf.org/html/rfc1436
|
|
||||||
.P
|
|
||||||
.RE
|
|
||||||
.SH ABOUT
|
|
||||||
.P
|
|
||||||
\fBphd\fR is maintained by chris west and released under the MIT license.
|
|
||||||
.P
|
|
||||||
phd's Gopher hole:
|
|
||||||
.RS 4
|
|
||||||
\fIgopher://phkt.io/1/phd\fR
|
|
||||||
.RE
|
|
||||||
phd's webpage:
|
|
||||||
.RS 4
|
|
||||||
\fIhttps://github.com/xvxx/phd\fR
|
|
@ -1,154 +0,0 @@
|
|||||||
PHD(1)
|
|
||||||
|
|
||||||
# NAME
|
|
||||||
|
|
||||||
phd - an estoeric gopher server
|
|
||||||
|
|
||||||
# SYNOPSIS
|
|
||||||
|
|
||||||
*phd* [_OPTIONS_] [_SITE ROOT_]
|
|
||||||
|
|
||||||
# DESCRIPTION
|
|
||||||
|
|
||||||
*phd* is a small, easy-to-use gopher server.
|
|
||||||
|
|
||||||
Point it at a directory and it'll serve up all the text files,
|
|
||||||
sub-directories, and binary files over Gopher. Any *.gph* files will
|
|
||||||
be served up as Gophermaps and executable *.gph* files will be
|
|
||||||
run as a program with their output served to the client, like the
|
|
||||||
glorious cgi-bin days of yore!
|
|
||||||
|
|
||||||
Usually *phd* is started with a path to your Gopher site:
|
|
||||||
|
|
||||||
phd /srv/gopher
|
|
||||||
|
|
||||||
If no path is given, *phd* will use the current directory as the root
|
|
||||||
of your Gopher site.
|
|
||||||
|
|
||||||
# OPTIONS
|
|
||||||
|
|
||||||
*-r* _SELECTOR_, *--render* _SELECTOR_
|
|
||||||
|
|
||||||
Rather than start as a server, render the _SELECTOR_ of the site using the options provided and print the raw response to *STDOUT*.
|
|
||||||
|
|
||||||
*-b* _ADDRESS_, *--bind* _ADDRESS_
|
|
||||||
Set the socket address to bind to, e.g. *127.0.0.1:7070*
|
|
||||||
|
|
||||||
*-p* _PORT_, *--port* _PORT_
|
|
||||||
Set the _PORT_ to use when generating Gopher links.
|
|
||||||
|
|
||||||
*-h* _HOST_, *--host* _HOST_
|
|
||||||
Set the _HOST_ to use when generating Gopher links.
|
|
||||||
|
|
||||||
*-h*, *--help*
|
|
||||||
Print a help summary and exit.
|
|
||||||
|
|
||||||
*-v*, *--version*
|
|
||||||
Print version information and exit.
|
|
||||||
|
|
||||||
# SPECIAL FILES
|
|
||||||
|
|
||||||
The following files have special behavior when present in a directory
|
|
||||||
that *phd* is tasked with serving:
|
|
||||||
|
|
||||||
*header.gph*
|
|
||||||
If it exists in a directory, its content will be shown above the directory's content. Put ASCII art in it.
|
|
||||||
|
|
||||||
*footer.gph*
|
|
||||||
Same, but will be shown below a directory's content.
|
|
||||||
|
|
||||||
*index.gph*
|
|
||||||
Completely replaces a directory's content with what's in this file.
|
|
||||||
|
|
||||||
*??.gph*
|
|
||||||
Visiting *gopher://yoursite/1/dog/* will try to render *dog.gph* from disk. Visiting */1/dog.gph* will render the raw content of the .gph file.
|
|
||||||
|
|
||||||
*.reverse*
|
|
||||||
If this exists, the directory contents will be listed in reverse alphanumeric order. Useful for phloggin', if you date your posts.
|
|
||||||
|
|
||||||
# GOPHERMAP SYNTAX
|
|
||||||
|
|
||||||
Any line in a *.gph* file that doesn't contain tabs (*\t*) will get an
|
|
||||||
*i* automatically prefixed, turning it into a Gopher information item.
|
|
||||||
|
|
||||||
For your convenience, phd supports *geomyidae* syntax for
|
|
||||||
creating links:
|
|
||||||
|
|
||||||
```
|
|
||||||
This is an info line.
|
|
||||||
[1|This is a link|/help|server|port]
|
|
||||||
[h|URL Link|URL:https://noogle.com]
|
|
||||||
```
|
|
||||||
|
|
||||||
*server* and *port* will get translated into the server and port of
|
|
||||||
the actively running server, eg *localhost* and *7070*.
|
|
||||||
|
|
||||||
Any line containing a tab character (*\t*) will be sent as-is to the
|
|
||||||
client, meaning you can write and serve up raw Gophermap files too.
|
|
||||||
|
|
||||||
# DYNAMIC CONTENT
|
|
||||||
|
|
||||||
Any *.gph* file that is marked *executable* with be run as if it
|
|
||||||
were a standalone program and its output will be sent to the client.
|
|
||||||
It will be passed three arguments: the query string (if any), the
|
|
||||||
server's hostname, and the current port. Do with them what you will.
|
|
||||||
|
|
||||||
For example:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ cat echo.gph
|
|
||||||
#!/bin/sh
|
|
||||||
echo "Hi, world! You said:" $1
|
|
||||||
echo "1Visit Gopherpedia / gopherpedia.com 70"
|
|
||||||
```
|
|
||||||
|
|
||||||
Then:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ gopher-client gopher://localhost/1/echo?something
|
|
||||||
[INFO] Hi, world! You said: something
|
|
||||||
[LINK] Visit Gopherpedia
|
|
||||||
```
|
|
||||||
|
|
||||||
Or more seriously:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ cat figlet.gph
|
|
||||||
#!/bin/sh
|
|
||||||
figlet $1
|
|
||||||
```
|
|
||||||
|
|
||||||
then:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ gopher-client gopher://localhost/1/figlet?hi gopher
|
|
||||||
[INFO] _ _ _
|
|
||||||
[INFO] | |__ (_) __ _ ___ _ __ | |__ ___ _ __
|
|
||||||
[INFO] | '_ \| | / _` |/ _ \| '_ \| '_ \ / _ \ '__|
|
|
||||||
[INFO] | | | | | | (_| | (_) | |_) | | | | __/ |
|
|
||||||
[INFO] |_| |_|_| \__, |\___/| .__/|_| |_|\___|_|
|
|
||||||
[INFO] |___/ |_|
|
|
||||||
```
|
|
||||||
|
|
||||||
## RESOURCES
|
|
||||||
|
|
||||||
geomyidae source code
|
|
||||||
gopher://bitreich.org/1/scm/geomyidae/files.gph
|
|
||||||
|
|
||||||
Example Gophermap
|
|
||||||
https://github.com/gophernicus/gophernicus/blob/master/README.Gophermap
|
|
||||||
|
|
||||||
Gophermaps
|
|
||||||
https://gopher.zone/posts/how-to-gophermap/
|
|
||||||
|
|
||||||
RFC 1436:
|
|
||||||
https://tools.ietf.org/html/rfc1436
|
|
||||||
|
|
||||||
# ABOUT
|
|
||||||
|
|
||||||
*phd* is maintained by chris west and released under the MIT license.
|
|
||||||
|
|
||||||
phd's Gopher hole:
|
|
||||||
_gopher://phkt.io/1/phd_
|
|
||||||
phd's webpage:
|
|
||||||
_https://github.com/xvxx/phd_
|
|
Loading…
Reference in New Issue