gmqcc/doc/html/download.c

284 lines
7.7 KiB
C

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
/*
* protect some information, not that I care, but this is just to stay
* safer.
*/
#define SECURITY_BASE "\
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
#define SECURITY_TOKEN "\
P29hdXRoX2NvbnN1bWVyX2tleT03NnZoM3E0Mmhudm16bTMmb2F1dGhfdG9rZW49\
dzBieHpmMGRmdDhlZGZxJm9hdXRoX3NpZ25hdHVyZV9tZXRob2Q9UExBSU5URVhU\
Jm9hdXRoX3NpZ25hdHVyZT10bWVlY2h0MmNtaDcyeGElMjY5dm9zeDd4OGd5NGtn\
amsmb2F1dGhfdGltZXN0YW1wPSZvYXV0aF9ub25jZT0xMjE2NQo="
int isbase64(char c) {
return !!(c && strchr(SECURITY_BASE, c) != NULL);
}
char value(char c) {
const char *load = SECURITY_BASE;
const char *find = strchr(load, c);
return (find) ? find - load : 0;
}
int security_decode(unsigned char *dest, const unsigned char *src, int srclen) {
unsigned char *p;
if(!*src)
return 0;
*dest = 0;
p = dest;
do {
*p++ = (value(src[0]) << 2) | (value(src[1]) >> 4);
*p++ = (value(src[1]) << 4) | (value(src[2]) >> 2);
*p++ = (value(src[2]) << 6) | (value(src[3]) >> 0);
if(!isbase64(src[1])) {
p -= 2;
break;
}
else if(!isbase64(src[2])) {
p -= 2;
break;
}
else if(!isbase64(src[3])) {
p--;
break;
}
src += 4;
while(*src && (*src == 13 || *src == 10))
src++;
} while(srclen-= 4);
*p = 0;
return p-dest;
}
#define BASEURL " https://api-content.dropbox.com/1/files/sandbox/"
/*
* If more platforms are supported add the entries between the start
* tag here, and the end tag below. Nothing else needs to be done
* <tag> (the table needs to match the HTML too)
*/
#define ARCHLINUX_32_REF "%sgmqcc-%c.%c.%c-1-i686.pkg.tar.xz%s"
#define ARCHLINUX_64_REF "%sgmqcc-%c.%c.%c-1-x86_64.pkg.tar.xz%s"
#define DEBIAN_32_REF "%sgmqcc-%c.%c.%c-i686.deb%s"
#define DEBIAN_64_REF "%sgmqcc-%c.%c.%c-x86_64.deb%s"
#define WINDOWS_32_REF "%sgmqcc-%c.%c.%c-win32.zip%s"
#define WINDOWS_64_REF "%sgmqcc-%c.%c.%c-win64.zip%s"
#define HTML "\
<!doctype html>\
<html>\
<head>\
<meta charset=\"utf-8\">\
<meta http-equiv=\"X-UA-Compatible\" content=\"chrome=1\">\
<title>GMQCC</title>\
<link rel=\"stylesheet\" href=\"stylesheets/styles.css\">\
<link rel=\"stylesheet\" href=\"stylesheets/pygment_trac.css\">\
<script src=\"javascripts/scale.fix.js\"></script>\
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">\
<!--[if lt IE 9]>\
<script src=\"//html5shiv.googlecode.com/svn/trunk/html5.js\"></script>\
<![endif]-->\
</head>\
<body>\
<a href=\"https://github.com/graphitemaster/gmqcc\"><div class=\"fork\"></div></a>\
<div class=\"wrapper\">\
<header>\
<h1 class=\"header\">GMQCC</h1>\
<p class=\"header\">An Improved Quake C Compiler</p>\
<ul>\
<li class=\"buttons\"><a href=index.html>Index</a></li>\
<li class=\"download\"><a href=\"download.html\">Download</a></li>\
<li class=\"buttons\"><a href=\"https://github.com/graphitemaster/gmqcc/issues\">Issues</a></li>\
<li class=\"buttons\"><a href=\"doc.html\">Documentation</a></li>\
<li class=\"buttons\"><a href=\"https://github.com/graphitemaster/gmqcc\">View On GitHub</a></li>\
</ul>\
</header>\
<section>\
<table>\
<tr>\
<th>Operating System / Distribution</th>\
<th>x86 Architecture</th>\
<th>x86_64 Architecture</th>\
</tr>\
<tr>\
<td>Archlinux</td>\
<td><a href=\"%s\">Download</a></td>\
<td><a href=\"%s\">Download</a></td>\
</tr>\
<tr>\
<td>Debian</td>\
<td><a href=\"%s\">Download</a></td>\
<td><a href=\"%s\">Download</a></td>\
</tr>\
<tr>\
<td>Windows</td>\
<td><a href=\"%s\">Download</a></td>\
<td><a href=\"%s\">Download</a></td>\
</tr>\
</table>\
</section>\
<footer>\
<script type=\"text/javascript\" src=\"http://www.ohloh.net/p/602517/widgets/project_partner_badge.js\"></script>\
</footer>\
</div>\
<!--[if !IE]><script>fixScale(document);</script><![endif]-->\
</body>\
</html>\
"
static char build_table[][4096] = {
ARCHLINUX_32_REF, ARCHLINUX_64_REF,
DEBIAN_32_REF, DEBIAN_64_REF,
WINDOWS_32_REF, WINDOWS_64_REF
};
/* </tag> */
#define ISXDIGIT(c) ((c >= 48 && c <= 57) || ((c & ~0x20) >= 65 && (c & ~0x20) <= 70))
typedef struct {
char *data;
unsigned int len;
unsigned int size;
} url_t;
void escape(url_t *str) {
char *p, *ptr;
char hexstr[3];
unsigned int i=0;
unsigned long l=0;
p = str->data;
for(i=0; i < str->len; i++) {
if((p - str->data) >= str->len)
break;
if(*p == '%' &&
((p - str->data)+2) < str->len &&
ISXDIGIT(*(p+1)) &&
ISXDIGIT(*(p+2))
) {
p++;
hexstr[0] = *p++;
hexstr[1] = *p++;
hexstr[2] = 0;
l = strtoul(hexstr, &ptr, 16);
str->data[i] = (char)(l & 0x7f);
continue;
}
if(*p == '+') {
*p = ' ';
}
str->data[i] = *p++;
}
str->data[i] = 0;
str->len = i;
}
void version(const char *directory, char *major, char *minor, char *patch) {
FILE *handle;
char file[4096];
size_t size = 0;
char *data = NULL;
snprintf(file, sizeof(file), "%s/gmqcc.h", directory);
handle = fopen(file, "r");
if (!handle) {
fprintf(stderr, "failed to open %s for reading version (%s)\n",
file, strerror(errno)
);
abort();
}
while (getline(&data, &size, handle) != EOF) {
#define TEST(TYPE, STORE) \
if (strstr(data, "#define GMQCC_VERSION_" TYPE )) { \
char *get = data; \
while (!isdigit(*get)) \
get++; \
*STORE = *get; \
}
TEST("MAJOR", major)
TEST("MINOR", minor)
TEST("PATCH", patch)
#undef TEST
}
free(data);
}
void genhtml() {
FILE *fp = fopen("download.html", "w");
if (!fp) {
fprintf(stderr, "failed to generate HTML: %s\n", strerror(errno));
abort();
}
fprintf(fp, HTML,
build_table[0], build_table[1],
build_table[2], build_table[3],
build_table[4], build_table[5]
);
fclose (fp);
}
/*
* Builds a list of download links with the right version and handles the
* rest of the magic.
*/
void build(const char *directory) {
/* Figure out version number */
char find[3];
char decode[4096];
size_t size;
version(directory, &find[0], &find[1], &find[2]);
/*
* decode the secuity stuff for preparing the URLs which will be used
* as links.
*/
memset(decode, 0, sizeof(decode));
security_decode(decode, SECURITY_TOKEN, strlen(SECURITY_TOKEN));
for (size = 0; size < sizeof(build_table) / sizeof(*build_table); size++) {
char *load = strdup(build_table[size]);
url_t esc = { NULL, 0 };
snprintf(build_table[size], 4096, load, BASEURL, find[0], find[1], find[2], decode);
esc.data = strdup(build_table[size]);
esc.size = strlen(build_table[size]);
esc.len = esc.size;
/* Yes we also need to escape URLs just incase */
escape(&esc);
free(load);
}
/*
* Now generate the HTML file for those download links by asking tinyurl to
*/
genhtml();
}
int main(int argc, char **argv) {
size_t itr;
argc--;
argv++;
if (!argc) {
printf("usage: %s [gmqcc.h location]\n", argv[-1]);
return 0;
}
build(*argv);
}