]>
gitweb.michael.orlitzky.com - charm-bypass.git/blob - cgi-bin/code.cgi
3 # A posix sh CGI script (yeah, that's right) to update the daily
4 # code for CharmBypass. This is not useful to you unless you
5 # host CharmBypass on a public web server and are insane.
8 # Fail on the first error.
11 # The CGI spec says that the current working directory SHOULD be set
12 # to the directory containing the script. Well, that's not always what
13 # happens. It's true in apache...
14 INDEX_HTML
=$(pwd)/..
/index.html
16 # But not in python's server.http
17 [ -f "${INDEX_HTML}" ] || INDEX_HTML
=$(pwd)/index.html
20 # Die with an error. The first argument, an HTTP status code, is
21 # returned as the Status. The second argument, an error message, is
22 # printed after setting the Content-type to text/plain. Finally, we
26 echo "Content-type: text/plain"
32 # Redirect to the given URL; return a 302 status, and send the
33 # necessary location header.
41 # Parse and return the daily code from the index.html file.
42 # This relies on "implementation details" within the HTML;
43 # namely, the field name and its value must appear next
44 # to each other on the same line.
47 -e 's/.*name="code" value="\([A-Za-z0-9]\{2\}\)".*/\1/p' \
52 # Update (replace) the daily code in the index.html file. The first
53 # argument is the new code to use. This relies on "implementation
54 # details" within the HTML; namely, the field name and its value must
55 # appear next to each other on the same line.
58 _find
='name="code" value="[a-zA-Z0-9]\{0,2\}"'
59 _replace
="name=\"code\" value=\"${_new_code}\""
62 # The "-i" flag to sed isn't POSIX, and worse, it tries to use a
63 # temp file in CWD. We don't want to make the parent directory
64 # writable because then this script is writable.
65 sed -e "s/${_find}/${_replace}/g" "${INDEX_HTML}" > "${_tmp}"
67 # mv would also recreate the file here, so cp/rm instead.
68 cp "${_tmp}" "${INDEX_HTML}"
72 # Display the "update code" form and exit.
74 echo "Content-type: text/html"
81 <meta charset="utf-8">
83 content="width=device-width, initial-scale=1" />
86 CharmBypass: got that transit equity
92 <label for="code">Today's code:</label>
94 name="code" value="${1}"
99 pattern="[a-zA-Z0-9]*" />
101 <input type="submit" value="Update it" />
109 # If this isn't a POST request, it should be a "normal" page hit,
110 # i.e. a GET request with no querystring parameters. If there are
111 # parameters, we ignore them, and display the "update code" form
113 if [ "${REQUEST_METHOD}" != "POST" ]; then
114 # Parse the code before we start displaying the form
115 # so that we can throw a 500 error if it fails.
116 _old_code
=$(parse_code) || die
500 "failed to parse the existing code"
117 display_code_form
"${_old_code}"
120 # Since display_code_form() exits, the only way we can get
121 # here is if this is a POST request. And in that case, we
122 # should have some data... At least, CONTENT_LENGTH will
124 if [ -n "${CONTENT_LENGTH}" -a "${CONTENT_LENGTH}" -gt 0 ]; then
125 POST_DATA
=$(dd bs=1 count="${CONTENT_LENGTH}" 2>/dev/null)
127 # Sanity check the form data. To prevent mistakes, it's not possible
128 # to "erase" the code that somebody else entered. If it's wrong, who
129 # cares? Erasing it would make it random... i.e. still wrong.
130 case "${POST_DATA}" in
131 "code="[A
-Za-z0-9][A
-Za-z0-9])
132 CODE
=$(echo "${POST_DATA}" | cut -d= -f2)
133 update_code
"${CODE}" || die
500 "failed to update the code"
137 # If the form data isn't exactly what we expect,
139 die
400 "bad request"