diff --git a/2005/mynx/.gitignore b/2005/mynx/.gitignore index 760b192f2..11a543853 100644 --- a/2005/mynx/.gitignore +++ b/2005/mynx/.gitignore @@ -1 +1,4 @@ mynx +mynx.alt +source/config.* +source/makefile diff --git a/2005/mynx/Makefile b/2005/mynx/Makefile index 8531dc060..72f898a29 100644 --- a/2005/mynx/Makefile +++ b/2005/mynx/Makefile @@ -114,8 +114,8 @@ OBJ= ${PROG}.o DATA= source/configure source/configure.in entities.txt source/makefile.in TARGET= ${PROG} # -ALT_OBJ= -ALT_TARGET= +ALT_OBJ= ${PROG}.alt.o +ALT_TARGET= ${PROG}.alt ################# diff --git a/2005/mynx/README.md b/2005/mynx/README.md index f85715c43..9aa574b8a 100644 --- a/2005/mynx/README.md +++ b/2005/mynx/README.md @@ -13,6 +13,11 @@ make ``` +[Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) fixed this so that the +[configure](source/configure) script (which is not needed but part of the entry) +would work with compilers that have by default `-Werror` like clang in macOS. +Thank you Cody! + ## To run: ```sh @@ -22,6 +27,8 @@ make You can specify a port by appending to the domain `:port`. See notes below on the issue of https. + + ## Try: ```sh @@ -30,28 +37,52 @@ the issue of https. [Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) pointed out that this -will not work for https initially for two reasons. First it scanned for http://. -Cody changed it to scan for both http:// and https:// but the problem is a -secure connection needs to be set up before http commands can be sent. One would -also have to specify a port in the URL. Fortunately or unfortunately many more -websites use https nowadays so this entry will not work as well as it used to. -If one were to try and connect to `http://www.ioccc.org` with this entry they'll -just get a 301 error. Perhaps someone can come up with a pipeline that will make -this work with the change made. Otherwise just enjoy it for what it was. +will not work for https initially for two reasons. For a starting point see the +alternate code section below. + +### Alternate code: + +As noted this will not work for https. This is because it does not scan for +https but also a secure connection needs to be set up before http commands can +be sent. One would also have to specify a port in the URL. Fortunately or +unfortunately many more websites use https nowadays so this entry will not work +as well as it used to. If one were to try and connect to `http://www.ioccc.org` +with this entry they'll just get a 301 error. + +In case someone can come up with a clever pipeline or some other hack or +workaround (perhaps [stunnel](https://www.stunnel.org)), Cody added the alt code +which does scan for https. Futile, maybe, in which case just enjoy it for what +it was. To compile: -## Judges' remarks +```sh +make alt +``` -This little mynx will give any Fiery Fox a run for its money. A nice complement -to last years winning hibachi. The judges double dare any eager -Obfuscationalists to submit the missing pieces to get a functioning LAMP stack. +Use `mynx.alt` as you would `mynx`. You'd have to specify a port at the end of +the URL like: + +```sh +./mynx.alt https://www.ioccc.org:443 +``` + +but again unless you have a clever workaround or hack to the problem, this sadly +won't work. + +## Judges' remarks: + +This little `mynx` will give any [Fiery +Fox](https://en.wikipedia.org/wiki/Firefox) a run for its money. A nice +complement to last years winning [hibachi](/2004/hibachi/src/hibachi.c). The +judges double dare any eager Obfuscationalists to submit the missing pieces to +get a functioning LAMP stack. ## Author's remarks: -I was rather impressed by last year's mini web server. So much so that +I was rather impressed by last year's mini webserver. So much so that it inspired me to try my hand at writing the client side complement. -A typical build would be command would be: +A typical build command would be: ```sh cc -omynx mynx.c @@ -69,26 +100,27 @@ all the network functions in a variety of places. So a simpler build command sequence would be: ```sh -./configure -make +cd source ; ./configure ; make ``` After which, the rest of the documentation can be read by saying: ```sh -./mynx manual.html +./mynx ../manual.html ``` Manifest: - mynx.c - makefile pre-built generic Un*x - README.TXT - manual.html - makefile.in makefile template - entities.txt ISO 8859-1 entites - configure.in configure script description - configure pre-built configure script +``` + mynx.c + makefile pre-built generic Un*x + README.TXT + manual.html + makefile.in makefile template + entities.txt ISO 8859-1 entites + configure.in configure script description + configure pre-built configure script +``` ## Copyright and CC BY-SA 4.0 License: diff --git a/2005/mynx/mynx.alt.c b/2005/mynx/mynx.alt.c new file mode 100644 index 000000000..6476d1eb0 --- /dev/null +++ b/2005/mynx/mynx.alt.c @@ -0,0 +1,224 @@ +#define I int +#define c char * +#define G fscanf(f, +#define W while( +#define k return +#define Q if( +#define Z 512 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +FILE *f; +short w[4] = { 24, 80 }; +I L, B, r, H; +c l[Z], b[Z], s[Z], S[Z][10], T[Z], h[Z]; +I +e(c s) +{ + I n = 0; + Q *s == '#') + k (I) strtol(s+1, 0, 0); + W n < Z) { + Q *S[n] && !strcmp(s, S[n]+1)) + k *S[n]; + n++; + } + k '?'; +} +void +P(I x) +{ + Q x == '\n' || w[1] - 3 < B) { + b[B] = 0; + b[B+1] = 0; + B = printf("%s", b); + B = snprintf( + b, Z, + "\n %s", + b + B + 1 + ); + r++; + } + Q b[B-1] != ' ' || !isspace(x)) { + b[B++] = isspace(x) ? ' ' : x; + Q w[1] - 3 < B) + *strrchr(b, ' ') = 0; + } +} +void +p(c t, ...) +{ + va_list x; + va_start(x, t); + vsnprintf(s, Z, t, x); + t = s; + W *t) + P(*t++); + va_end(x); +} +I +X(c s) +{ + I x; + c t = s; + long m = ftell(f); + W *t && (x = fgetc(f)) != EOF) { + Q *t == '*') + s = t++; + Q tolower(x) != *t) { + Q *s != '*') + break; + t = s; + } + t++; + } + Q *t) + fseek(f, m, SEEK_SET); + k !*t; +} +void +d(c s) +{ + Q 4 < B) + P('\n'); + P('\n'); + Q *s == 'h') + B = 1; +} +void +a(c s) +{ + *T = 0; + G + ungetc(fgetc(f), f) == '"' + ? "\"%511[^\"]" + : "'%511[^']", + T + ); + Q *s == 'a' || *s == 'f' || s[1] == 'f') { + free(l[++L]); + l[L] = strdup(T); + p(" [%d] ", L); + } + Q *s != 'a') + p("%s%s\n", T, *s == 'b' || s[1] == 'h' ? "" : "\n"); + X("*>"); +} +void *Y[] = { + "!--*-->" , 0 , + "a *href=" , a , + "ifr*src=" , a , + "fra*src=" , a , + "img*src=" , a , + "p*>" , d , + "bl*>" , d , + "br" , a , + "hr" , a , + "h*>" , d , + "/h" , a , + "/tr" , a , + "/dt" , a , + "/dd" , a , + "li*>" , d , + "*>" , 0 , + 0 , 0 +}; +I +main(I V, c *v) +{ + I x, n = 0; + c t = v[1]; + ioctl(0, TIOCGWINSZ, w); + f = fopen("entities.txt", "r"); + Q f) { + W G "%s %d", S[n]+1, &x) == 2) + *S[n++] = x; + fclose(f); + n = 0; + } + W t) { + I m = 0; + struct hostent *y; + struct sockaddr_in A; + L = 0; + B = 1; + Q (!sscanf(t, "http://%255[^/]%n", h, &n)&&!sscanf(t,"https://%255[^/]%n",h, &n) && !*h)) { + Q !(f = fopen(t, "rb"))) + k 1; + goto e; + } + Q 0 < sscanf(h, "%*[^:]%n:%d", &x, &H)) + h[x] = 0; + else + H = 80; + y = gethostbyname(h); + Q !y) + k 1; + memcpy(&A.sin_addr.s_addr, y->h_addr, y->h_length); + A.sin_port = htons( (short) H); + A.sin_family = y->h_addrtype; + f = tmpfile(); + Q !f) + k 1; + W + connect( + m = socket( + A.sin_family, SOCK_STREAM, 0 + ), (void *) &A, sizeof A + ) + || errno == EINTR + ) + ; + n = snprintf( + b, Z, + "GET %s%s HTTP/1.0\r\nHost: %s:%d\r\n\r\n", + t[n] == '/' ? "" : "/", t+n, h, H + ); + Q send(m, b, n, 0) == n) { + W 0 < (n = recv(m, b, Z, 0))) + fwrite(b, 1, n, f); + } + close(m); + rewind(f); + X("*\r\n\r\n"); +e: + r = 3; + *b = ' '; + W r < *w && (x = fgetc(f)) != EOF) { + Q x == '<') { + void **p = Y; + W *p) { + Q X(*p)) { + Q p[1]) + (* (void (*)(c )) + p[1])(*p); + break; + } + p += 2; + } + } else { + Q x == '&') { + G "%9[^;];", T); + x = e(T); + } + P(isspace(x) ? ' ' : x); + } + } + printf("\n? "); + fflush(stdout); + fgets(T, Z, stdin); + Q *T == '\n') + goto e; + t = l[strtol(T, 0, 0)]; + fclose(f); + } + k 0; +} diff --git a/2005/mynx/mynx.c b/2005/mynx/mynx.c index b3d21e644..d0d1f4270 100644 --- a/2005/mynx/mynx.c +++ b/2005/mynx/mynx.c @@ -6,6 +6,9 @@ #define Q if( #define Z 512 #include +#include +#include +#include #include #include #include @@ -147,7 +150,7 @@ main(I V, c *v) struct sockaddr_in A; L = 0; B = 1; - Q (!sscanf(t, "http://%255[^/]%n", h, &n)&&!sscanf(t,"https://%255[^/]%n",h, &n) && !*h)) { + Q !sscanf(t, "http://%255[^/]%n", h, &n) && !*h) { Q !(f = fopen(t, "rb"))) k 1; goto e; diff --git a/2005/mynx/source/mynx.c b/2005/mynx/source/mynx.c new file mode 100644 index 000000000..d0d1f4270 --- /dev/null +++ b/2005/mynx/source/mynx.c @@ -0,0 +1,224 @@ +#define I int +#define c char * +#define G fscanf(f, +#define W while( +#define k return +#define Q if( +#define Z 512 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +FILE *f; +short w[4] = { 24, 80 }; +I L, B, r, H; +c l[Z], b[Z], s[Z], S[Z][10], T[Z], h[Z]; +I +e(c s) +{ + I n = 0; + Q *s == '#') + k (I) strtol(s+1, 0, 0); + W n < Z) { + Q *S[n] && !strcmp(s, S[n]+1)) + k *S[n]; + n++; + } + k '?'; +} +void +P(I x) +{ + Q x == '\n' || w[1] - 3 < B) { + b[B] = 0; + b[B+1] = 0; + B = printf("%s", b); + B = snprintf( + b, Z, + "\n %s", + b + B + 1 + ); + r++; + } + Q b[B-1] != ' ' || !isspace(x)) { + b[B++] = isspace(x) ? ' ' : x; + Q w[1] - 3 < B) + *strrchr(b, ' ') = 0; + } +} +void +p(c t, ...) +{ + va_list x; + va_start(x, t); + vsnprintf(s, Z, t, x); + t = s; + W *t) + P(*t++); + va_end(x); +} +I +X(c s) +{ + I x; + c t = s; + long m = ftell(f); + W *t && (x = fgetc(f)) != EOF) { + Q *t == '*') + s = t++; + Q tolower(x) != *t) { + Q *s != '*') + break; + t = s; + } + t++; + } + Q *t) + fseek(f, m, SEEK_SET); + k !*t; +} +void +d(c s) +{ + Q 4 < B) + P('\n'); + P('\n'); + Q *s == 'h') + B = 1; +} +void +a(c s) +{ + *T = 0; + G + ungetc(fgetc(f), f) == '"' + ? "\"%511[^\"]" + : "'%511[^']", + T + ); + Q *s == 'a' || *s == 'f' || s[1] == 'f') { + free(l[++L]); + l[L] = strdup(T); + p(" [%d] ", L); + } + Q *s != 'a') + p("%s%s\n", T, *s == 'b' || s[1] == 'h' ? "" : "\n"); + X("*>"); +} +void *Y[] = { + "!--*-->" , 0 , + "a *href=" , a , + "ifr*src=" , a , + "fra*src=" , a , + "img*src=" , a , + "p*>" , d , + "bl*>" , d , + "br" , a , + "hr" , a , + "h*>" , d , + "/h" , a , + "/tr" , a , + "/dt" , a , + "/dd" , a , + "li*>" , d , + "*>" , 0 , + 0 , 0 +}; +I +main(I V, c *v) +{ + I x, n = 0; + c t = v[1]; + ioctl(0, TIOCGWINSZ, w); + f = fopen("entities.txt", "r"); + Q f) { + W G "%s %d", S[n]+1, &x) == 2) + *S[n++] = x; + fclose(f); + n = 0; + } + W t) { + I m = 0; + struct hostent *y; + struct sockaddr_in A; + L = 0; + B = 1; + Q !sscanf(t, "http://%255[^/]%n", h, &n) && !*h) { + Q !(f = fopen(t, "rb"))) + k 1; + goto e; + } + Q 0 < sscanf(h, "%*[^:]%n:%d", &x, &H)) + h[x] = 0; + else + H = 80; + y = gethostbyname(h); + Q !y) + k 1; + memcpy(&A.sin_addr.s_addr, y->h_addr, y->h_length); + A.sin_port = htons( (short) H); + A.sin_family = y->h_addrtype; + f = tmpfile(); + Q !f) + k 1; + W + connect( + m = socket( + A.sin_family, SOCK_STREAM, 0 + ), (void *) &A, sizeof A + ) + || errno == EINTR + ) + ; + n = snprintf( + b, Z, + "GET %s%s HTTP/1.0\r\nHost: %s:%d\r\n\r\n", + t[n] == '/' ? "" : "/", t+n, h, H + ); + Q send(m, b, n, 0) == n) { + W 0 < (n = recv(m, b, Z, 0))) + fwrite(b, 1, n, f); + } + close(m); + rewind(f); + X("*\r\n\r\n"); +e: + r = 3; + *b = ' '; + W r < *w && (x = fgetc(f)) != EOF) { + Q x == '<') { + void **p = Y; + W *p) { + Q X(*p)) { + Q p[1]) + (* (void (*)(c )) + p[1])(*p); + break; + } + p += 2; + } + } else { + Q x == '&') { + G "%9[^;];", T); + x = e(T); + } + P(isspace(x) ? ' ' : x); + } + } + printf("\n? "); + fflush(stdout); + fgets(T, Z, stdin); + Q *T == '\n') + goto e; + t = l[strtol(T, 0, 0)]; + fclose(f); + } + k 0; +} diff --git a/bugs.md b/bugs.md index 12d902b96..12dc6db02 100644 --- a/bugs.md +++ b/bugs.md @@ -1751,12 +1751,12 @@ does not exist. ## STATUS: INABIAF - please **DO NOT** fix [Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) notes that, though -probably obvious, this entry will not work with https. He changed the code to -scan for https too (it exited before) in case someone comes up with a clever -command line to make it work but the problem is a secure connection has to first -be set up in order to give http commands. This is not a bug but it's worth -pointing out as it won't work on as many websites as it used to including the -[IOCCC website](https://www.ioccc.org) itself. +probably obvious, this entry will not work with https. He added an alt version +that scans for https in case someone wants to set up a pipeline or other +workaround (perhaps with stunnel) but the problem otherwise is a secure +connection has to first be set up in order to give http commands. This is not a +bug but it's worth pointing out as it won't work on as many websites as it used +to including the [IOCCC website](https://www.ioccc.org) itself. # 2006