<!doctype html><htmllang=en><head><metacharset=utf-8><metaname=viewportcontent="width=device-width,initial-scale=1"><linkrel="shortcut icon"href=/img/icon.pngtype=image/png><metaname=generatorcontent="Hugo 0.105.0"><metaproperty="og:title"content="Esoteric uses of CGI"><metaproperty="og:description"content="Or how to program the back-end of your website using Commodore BASIC."><metaproperty="og:type"content="article"><metaproperty="og:url"content="http://toasters.rocks/esoteric-uses-of-cgi/"><metaproperty="og:image"content="http://toasters.rocks/images/2019/12/photo-1461749280684-dccba630e2f6.jpg"><metaproperty="article:section"content><metaproperty="article:published_time"content="2019-12-21T04:41:19+00:00"><metaproperty="article:modified_time"content="2019-12-21T05:34:28+00:00"><metaname=twitter:cardcontent="summary_large_image"><metaname=twitter:imagecontent="http://toasters.rocks/images/2019/12/photo-1461749280684-dccba630e2f6.jpg"><metaname=twitter:titlecontent="Esoteric uses of CGI"><metaname=twitter:descriptioncontent="Or how to program the back-end of your website using Commodore BASIC."><metaname=theme-colorcontent="#660066"><title>Esoteric uses of CGI - toasters rocks</title><linkrel=stylesheethref=http://toasters.rocks/css/toastersrocks.min.css></head><body><header><imgsrc=/img/icon.png><h1>toasters rocks</h1></header><main><aside><nav><ahref=/><iclass="fas fa-home"></i>
<spanstyle=color:#fe3801>SoundCloud</span></a><br></nav></aside><articlestyle=background-image:url(/images/2019/12/photo-1461749280684-dccba630e2f6.jpg)><divclass=metadatastyle="height:calc((var(--height) - 2em) * .6675 - 3.5em)"><h2name=top>Esoteric uses of CGI</h2><p>Or how to program the back-end of your website using Commodore BASIC.</p><iclass="far fa-calendar-alt"></i>
#<aclass="btn btn-sm btn-outline-dark tag-btn"href=http://toasters.rocks/tags/tech>Tech</a><br><iclass="fas fa-hourglass"></i> ~6 minutes</div><p>Well, you probably all heard of <ahref=https://esolangs.org/>esoteric programming languages</a> before, but the question today is, programming languages used outside its intended use, would that be esoteric?</p><p>If I tell you back-end web languages, you’d immediately think PHP, Node.js, Ruby, C maybe, but what if I tell you… Commodore BASIC? Sure, just get a Commodore 64 with a TCP/IP stack and write a web server for it you’d say, but I mean, actually using it on an actual, everyday web server on some Linux box? It’s clearly not made for that.</p><p>Enter <ahref=https://en.wikipedia.org/wiki/Common_Gateway_Interface>CGI</a>, which is a protocol that was basically made so your web server can run a Perl script that could do more than directly serving some static HTML file so your user could actually interact with your website. A standard setup would be PHP running as a FastCGI server on top of Nginx, that or running as a plugin on Apache. In the first case, PHP communicates with Nginx via a UNIX socket, the web server forwards a request, PHP processes it and sends it back, so it would be more efficient and not spawn a process every request, which might slow your site down if it’s popular enough.</p><h2id=installation>Installation</h2><p>We’re going to use <ahref=https://github.com/gnosek/fcgiwrap>fcgiwrap</a>, a little piece of software that plugs into Nginx just like PHP does, but it runs just about any software you can run on command line, be it a shell script, a program, or a script written using your favourite language interpreter. You just install it using your Linux distro’s package manager, activate the socket with a <code>sudo systemctl start fcgiwrap.socket</code>, install it in your <code>nginx.conf</code> just like you did with PHP, that’s it, just like in the good ol’ days.</p><divclass=highlight><divclass=chroma><tableclass=lntable><tr><tdclass=lntd><pretabindex=0class=chroma><code><spanclass=lnt>1
</span></span></code></pre></td></tr></table></div></div><p>Example nginx config block.</p><p>So, as long as you have an interpreter, you can turn it into a web back-end server language, right? Theorically, yes. We’ll take our good ol’ Commodore 64 BASIC <ahref=https://github.com/mist64/cbmbasic>that has been ported to C</a> so it could work on your modern computer as a case study.</p><p>So basically, you need a console program that opens a file and interprets it:</p><divclass=highlight><divclass=chroma><tableclass=lntable><tr><tdclass=lntd><pretabindex=0class=chroma><code><spanclass=lnt>1
</span></span></code></pre></td></tr></table></div></div><p>Example console session.</p><p>Mind the shebang (the <code>#!/usr/bin/cbmbasic</code> line), it basically turns <code>./program.bas</code> into the proper <code>cbmbasic program.bas</code>. You’ll need to run <code>chmod +x</code> on it for it to work. It’s going to be useful later as you have no way otherwise to tell your web server which interpreter you want to run that file with.</p><p>So now you can dump in your web directory a file like this:</p><divclass=highlight><divclass=chroma><tableclass=lntable><tr><tdclass=lntd><pretabindex=0class=chroma><code><spanclass=lnt>1
</span></span><spanclass=line><spanclass=cl><spanclass=nl>60</span><spanclass=w></span><spanclass=kr>PRINT</span><spanclass=s2>"<br/>Time is: "</span><spanclass=p>;</span>
</span></span></code></pre></td></tr></table></div></div><p>index.cgi</p><p>Navigate to it with your browser and sure enough, you have a nice “Hello, world!” with the current time. So it’s really easy to code something to show up in your browser. But of course, this ain’t PHP, you have to send the HTTP headers yourself (lines 10-30, anything followed by two newlines should be sufficient, but for best results you should send the HTTP code and the content type), but still, quite easy. But the question here is, how is it useful?</p><h2id=_post>$_POST</h2><p>Obviously, you’d need some kind of input, right? The HTTP protocol allows for GET and POST. POST allows you to send data in the body of the request, otherwise you can also get some data from the URL. In PHP that would be respectively the <code>$_POST</code> and <code>$_GET</code> arrays. But of course it won’t automatically parse these, so let’s do that.</p><p>For POST data, it’s just as easy as reading keyboard input, or STDIN, depending of how it works. If it’s a GET request, then you should get nothing (or a 0xFF byte in case of BASIC), otherwise you’d get the data your user sent in your POST form.</p><divclass=highlight><divclass=chroma><tableclass=lntable><tr><tdclass=lntd><pretabindex=0class=chroma><code><spanclass=lnt> 1
</span></span></code></pre></td></tr></table></div></div><p>Add this code to get and print POST variables. Good thing there’s line numbers so I don’t have to tell you where to add them.
It’s safe to assume anything over 127 is the end of input, as anything above that will be percent-encoded. In particular, in BASIC, you get 199 if you’re past the end (EOF) and 255 if there’s nothing. Parsing the resulting string is left as an exercise to the reader. And now if you send some data in the form you’ll get:</p><pretabindex=0><code> input=Something
</code></pre><p>You can even use brainfuck or something similar:</p><pre><code>100 PRINT"<form method=POST action='bf.cgi'>
</code></pre><p>Replace line 100 from above…</p><divclass=highlight><divclass=chroma><tableclass=lntable><tr><tdclass=lntd><pretabindex=0class=chroma><code><spanclass=lnt>1
</span></span></span></code></pre></td></tr></table></div></div><p>…and create bf.cgi</p><h2id=_server-_get-_cookies-etc>$_SERVER, $_GET, $_COOKIES, etc.</h2><p>Now you’ll want some of the sweet variables the server sends you that tells where the request came from and similar stuff, which is <code>$_SERVER</code> in PHP. If your language doesn’t support environment variables from the OS, unfortunately (for brainfuck), you’ll need to open files here. On Linux, it’s <code>/proc/self/environ</code>, your mileage may vary on other OSes. It’s mostly the same code, except the lines are separated by null bytes.</p><divclass=highlight><divclass=chroma><tableclass=lntable><tr><tdclass=lntd><pretabindex=0class=chroma><code><spanclass=lnt> 1