Add unobfuscated code from @SirWumpus

The entries 2004/hibachi and 2005/mynx have unobfuscated code now.

2004/hibachi has a configure script that is used along the lines of the
original entry (with some adjustments and fixes) and the hibachi.alt.c
had to have ctype.h included too. The directory src/localhost was copied
to src-alt/localhost but the rest of src/ was from Anthony. The Makefile
had to be updated to build this version.

2005/mynx does have a configure script but it is, just like the original
entry, unused and so the unobfuscated (in source-alt/) is also unused.
The mynx.alt.c was changed to mynx.alt2.c and the unobfuscated code was
made mynx.alt.c.

Updated manifest, rebuilt .entry.json and index.html files.

After a question is answered and taken care of (in one of 199[1-3]/ant -
not sure which one) issue #2513 can possibly be closed as complete
(though the manifest updates will have to be looked at more when 2004
and 2005 are reviewed).
This commit is contained in:
Cody Boone Ferguson committed 2024-07-08 13:11:00 -07:00
1 parent 60ce3d9155
commit 0d65af1b2b
65 files changed
+15579 -218

No files matched your search

+40
View File
@@ -31,6 +31,14 @@
"OK_to_edit" : true,
"display_as" : "c",
"display_via_github" : true,
"entry_text" : "author provided unobfuscated code"
},
{
"file_path" : "mynx.alt2.c",
"inventory_order" : 40,
"OK_to_edit" : true,
"display_as" : "c",
"display_via_github" : true,
"entry_text" : "alternate source code"
},
{
@@ -57,6 +65,38 @@
"display_via_github" : false,
"entry_text" : "ISO 8859-1 entitles"
},
{
"file_path" : "source-alt/transform.sed",
"inventory_order" : 130,
"OK_to_edit" : true,
"display_as" : "sed",
"display_via_github" : true,
"entry_text" : "sed(1) script for building unobfuscated code"
},
{
"file_path" : "source-alt/configure",
"inventory_order" : 150,
"OK_to_edit" : true,
"display_as" : "shellscript",
"display_via_github" : true,
"entry_text" : "pre-built configure script for unobfuscated code"
},
{
"file_path" : "source-alt/configure.in",
"inventory_order" : 150,
"OK_to_edit" : true,
"display_as" : "shellscript",
"display_via_github" : true,
"entry_text" : "GNU Autoconf script for unobfuscated code"
},
{
"file_path" : "source-alt/makefile.in",
"inventory_order" : 150,
"OK_to_edit" : true,
"display_as" : "shellscript",
"display_via_github" : true,
"entry_text" : "GNU Automake script for unobfuscated code"
},
{
"file_path" : "source/configure",
"inventory_order" : 150,
+3
View File
@@ -6,7 +6,10 @@ indent.c
indent.o
mynx
mynx.alt
mynx.alt2
mynx.orig
prog.orig
source/config.*
source/makefile
source-alt/config.*
source-alt/makefile
+2 -2
View File
@@ -116,8 +116,8 @@ OBJ= ${PROG}.o
DATA= source/configure source/configure.in entities.txt source/makefile.in
TARGET= ${PROG}
#
ALT_OBJ= ${PROG}.alt.o
ALT_TARGET= ${PROG}.alt
ALT_OBJ= ${PROG}.alt.o ${PROG}.alt
ALT_TARGET= ${PROG}.alt ${PROG}.alt2
#################
+28 -16
View File
@@ -4,10 +4,11 @@
make
```
There is an alternate version that scans for (_ONLY_ scans) the string `https`
as a starting point in case anyone wishes to add support or come up with a
pipeline to let it work, as many websites no longer work with `http`.
See [alternate code](#alternate-code) below.
The author provided us with an unobfuscated version. There is also a version
that scans (**ONLY** scans) the string `https` as a starting point in case
anyone wishes to add support or come up with a pipeline to make it work, as many
websites no longer work with `http`. See [alternate code](#alternate-code)
below.
### Bugs and (Mis)features:
@@ -42,20 +43,28 @@ the issue of https.
## Alternate code:
Obviously this will not work with `https` as it only scans for `http` in the URL
(if not specified it tries to open it as a local file). But even if it scanned
The author's provided unobfuscated code,
[mynx.alt.c](%%REPO_URL%%/2005/mynx/mynx.alt.c) can be compiled and evaluated if
you wish to not try and decipher the original entry.
The other version, [mynx.alt2.c](%%REPO_URL%%/2005/mynx/mynx.alt2.c) is a
starting point for anyone who wishes to come up with a version (or pipeline)
that works with `https`.
Obviously this will not work with `https` without so easily as it only scans for `http` in the URL
(if not specified it tries to open it as a local file). But even though it scans
for `https` one would need to do more work as it would have to set up a secure
connection before http commands could be sent. Fortunately or unfortunately
many more websites use https so this entry will not work as well as it used to.
many more websites use https so this entry will not work as well as it used to.
If one were to try and connect to <https://ioccc.org> with this entry they'll
just get a 301 error.
The alternate code is a starting point that scans for `https` too (note you have
to specify the port in this case) but that is all it does. It will not work with
https websites as it does not set up a secure connection. But should anyone wish
to either come up with a pipeline (or some other command line) that allows it to
work with https or to update the code to support https they may. Otherwise you
must just appreciate the entry for what it once was.
This alternate code is a starting point that scans for `https` too (note you
have to specify the port in this case) but that is all it does. It will not work
with https websites as it stands as it does not set up a secure connection. But
should anyone wish to either come up with a pipeline (or some other command
line) that allows it to work with https or to update the code to support https
they may. Otherwise you must just appreciate the entry for what it once was.
### Alternate build:
@@ -67,11 +76,14 @@ must just appreciate the entry for what it once was.
### Alternate use:
Use `mynx.alt` as you would `mynx`. You'd have to specify a port at the end of
the URL like:
Use `mynx.alt` as you would `mynx`.
For the version that also scans for `https` you'll have to specify a port at the
end of the URL like:
``` <!---sh-->
./mynx.alt https://www.ioccc.org:443
./mynx.alt2 https://www.ioccc.org:443
```
but again unless you have a clever workaround or hack to the problem, this sadly
+29 -16
View File
@@ -403,10 +403,11 @@ Location: <a href="../../location.html#CA">CA</a> - <em>Canada</em></li>
<!-- BEFORE: 1st line of markdown file: 2005/mynx/README.md -->
<h2 id="to-build">To build:</h2>
<pre><code> make</code></pre>
<p>There is an alternate version that scans for (<em>ONLY</em> scans) the string <code>https</code>
as a starting point in case anyone wishes to add support or come up with a
pipeline to let it work, as many websites no longer work with <code>http</code>.
See <a href="#alternate-code">alternate code</a> below.</p>
<p>The author provided us with an unobfuscated version. There is also a version
that scans (<strong>ONLY</strong> scans) the string <code>https</code> as a starting point in case
anyone wishes to add support or come up with a pipeline to make it work, as many
websites no longer work with <code>http</code>. See <a href="#alternate-code">alternate code</a>
below.</p>
<h3 id="bugs-and-misfeatures">Bugs and (Mis)features:</h3>
<p>The current status of this entry is:</p>
<pre><code> STATUS: INABIAF - please DO NOT fix</code></pre>
@@ -420,25 +421,32 @@ the issue of https.</p>
./mynx manual.html</code></pre>
<h2 id="alternate-code">Alternate code:</h2>
<p>Obviously this will not work with <code>https</code> as it only scans for <code>http</code> in the URL
(if not specified it tries to open it as a local file). But even if it scanned
<p>The author’s provided unobfuscated code,
<a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2005/mynx/mynx.alt.c">mynx.alt.c</a> can be compiled and evaluated if
you wish to not try and decipher the original entry.</p>
<p>The other version, <a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2005/mynx/mynx.alt2.c">mynx.alt2.c</a> is a
starting point for anyone who wishes to come up with a version (or pipeline)
that works with <code>https</code>.</p>
<p>Obviously this will not work with <code>https</code> without so easily as it only scans for <code>http</code> in the URL
(if not specified it tries to open it as a local file). But even though it scans
for <code>https</code> one would need to do more work as it would have to set up a secure
connection before http commands could be sent. Fortunately or unfortunately
many more websites use https so this entry will not work as well as it used to.
If one were to try and connect to <a href="https://ioccc.org" class="uri">https://ioccc.org</a> with this entry they’ll
just get a 301 error.</p>
<p>The alternate code is a starting point that scans for <code>https</code> too (note you have
to specify the port in this case) but that is all it does. It will not work with
https websites as it does not set up a secure connection. But should anyone wish
to either come up with a pipeline (or some other command line) that allows it to
work with https or to update the code to support https they may. Otherwise you
must just appreciate the entry for what it once was.</p>
<p>This alternate code is a starting point that scans for <code>https</code> too (note you
have to specify the port in this case) but that is all it does. It will not work
with https websites as it stands as it does not set up a secure connection. But
should anyone wish to either come up with a pipeline (or some other command
line) that allows it to work with https or to update the code to support https
they may. Otherwise you must just appreciate the entry for what it once was.</p>
<h3 id="alternate-build">Alternate build:</h3>
<pre><code> make alt</code></pre>
<h3 id="alternate-use">Alternate use:</h3>
<p>Use <code>mynx.alt</code> as you would <code>mynx</code>. You’d have to specify a port at the end of
the URL like:</p>
<pre><code> ./mynx.alt https://www.ioccc.org:443</code></pre>
<p>Use <code>mynx.alt</code> as you would <code>mynx</code>.</p>
<p>For the version that also scans for <code>https</code> you’ll have to specify a port at the
end of the URL like:</p>
<pre><code> ./mynx.alt2 https://www.ioccc.org:443</code></pre>
<p>but again unless you have a clever workaround or hack to the problem, this sadly
won’t work.</p>
<h2 id="judges-remarks">Judges’ remarks:</h2>
@@ -488,10 +496,15 @@ command sequence would be:</p>
<ul>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2005/mynx/mynx.c">mynx.c</a> - entry source code</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2005/mynx/Makefile">Makefile</a> - entry Makefile</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2005/mynx/mynx.alt.c">mynx.alt.c</a> - alternate source code</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2005/mynx/mynx.alt2.c">mynx.alt2.c</a> - alternate source code</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2005/mynx/mynx.alt.c">mynx.alt.c</a> - author provided unobfuscated code</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2005/mynx/mynx.orig.c">mynx.orig.c</a> - original source code</li>
<li><a href="manual.html">manual.html</a> - manual for the Mynx web browser</li>
<li><a href="entities.txt">entities.txt</a> - ISO 8859-1 entitles</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2005/mynx/source-alt/transform.sed">source-alt/transform.sed</a> - sed(1) script for building unobfuscated code</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2005/mynx/source-alt/configure">source-alt/configure</a> - pre-built configure script for unobfuscated code</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2005/mynx/source-alt/configure.in">source-alt/configure.in</a> - GNU Autoconf script for unobfuscated code</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2005/mynx/source-alt/makefile.in">source-alt/makefile.in</a> - GNU Automake script for unobfuscated code</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2005/mynx/source/configure">source/configure</a> - pre-built configure script</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2005/mynx/source/configure.in">source/configure.in</a> - GNU Autoconf script</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2005/mynx/source/makefile.in">source/makefile.in</a> - GNU Automake script</li>
+341 -165
View File
@@ -1,224 +1,400 @@
#define I int
#define c char *
#define G fscanf(f,
#define W while(
#define k return
#define Q if(
#define Z 512
/*
* mynx.c
*
* Copyright 2005 by Anthony Howe. All rights reserved.
*/
#define LENGTH 512
/***********************************************************************
*** No configuration below this point.
***********************************************************************/
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#if defined(__WIN32__) || defined(__CYGWIN__)
#include <windows.h>
#include <winsock2.h>
#ifdef ORIGINAL_VERSION
#define EISCONN WSAEISCONN
#define EINPROGRESS WSAEINPROGRESS
#define UPDATE_ERRNO if (errno == 0) errno = WSAGetLastError()
#endif
#else
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define UPDATE_ERRNO
#define SOCKET int
#define closesocket close
/* The ioctl() TIOCGWINSZ call return the same information in the same
* order for Linux, System V, abd *BSD, but for some stupid reason they
* can't agree on a standard structure name. Fuck'em.
*
* Linux, System V:
*
* struct winsize {
* unsigned short ws_row;
* unsigned short ws_col;
* unsigned short ws_xpixel;
* unsigned short ws_ypixel;
* };
*
*
* OpenBSD
*
* struct ttysize {
* unsigned short ts_lines;
* unsigned short ts_cols;
* unsigned short ts_xxx;
* unsigned short ts_yyy;
* };
*/
#include <sys/ioctl.h>
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)
#endif
#define peek(f) ungetc(fgetc(f), f)
FILE *fp;
short winsz[4] = { 24, 80 };
int linksLength, bufferLength, row, port;
char *links[LENGTH], buffer[BUFSIZ], fmtbuf[BUFSIZ], entities[LENGTH][10], text[LENGTH], host[LENGTH];
int
entity(char *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];
int n = 0;
if (*s == '#')
return (int) strtol(s+1, NULL, 0);
while (n < LENGTH) {
if (*entities[n] != '\0' && strcmp(s, entities[n]+1) == 0)
return *entities[n];
n++;
}
k '?';
return '?';
}
/*
* Line wrap print controller.
*/
void
P(I x)
printc(int ch)
{
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
/* Flush current line buffer. */
if (ch == '\n' || winsz[1] - 3 < bufferLength) {
buffer[bufferLength] = '\0';
buffer[bufferLength+1] = '\0';
bufferLength = printf("%s", buffer);
bufferLength = snprintf(
buffer, BUFSIZ,
"\n %s",
buffer + bufferLength + 1
);
r++;
row++;
}
Q b[B-1] != ' ' || !isspace(x)) {
b[B++] = isspace(x) ? ' ' : x;
Q w[1] - 3 < B)
*strrchr(b, ' ') = 0;
/* Compact whitespace. */
if (buffer[bufferLength-1] != ' ' || !isspace(ch)) {
/* Append character to line wrap buffer. */
buffer[bufferLength++] = isspace(ch) ? ' ' : ch;
/* If we've exceed the screen width, wrap just before previous word. */
if (winsz[1] - 3 < bufferLength)
*strrchr(buffer, ' ') = '\0';
}
}
void
p(c t, ...)
prints(char *fmt, ...)
{
va_list x;
va_start(x, t);
vsnprintf(s, Z, t, x);
t = s;
W *t)
P(*t++);
va_end(x);
va_list args;
va_start(args, fmt);
vsnprintf(fmtbuf, LENGTH, fmt, args);
fmt = fmtbuf;
while (*fmt != '\0')
printc(*fmt++);
va_end(args);
}
I
X(c s)
/*
* Find the next occurence of string. If the string is not found.
* rewind to the file pointer to its starting point.
*
* @param fp
* File pointer to scan through.
*
* @param s
* The string to match. An astrisk '*' acts as wildcard,
* scanning over zero or more bytes:
*
* "abc" match "abc" at the current offset
*
* "*abc" find "abc" from the current offset.
*
* "abc*def" match "abc", then find "def".
*
* "*abc*def" find "abc", then find "def"
*
* @return
* True on a successful match.
*/
int
fnext(char *s)
{
I x;
c t = s;
long m = ftell(f);
W *t && (x = fgetc(f)) != EOF) {
Q *t == '*')
int ch;
char *t = s;
long mark = ftell(fp);
while (*t != '\0' && (ch = fgetc(fp)) != EOF) {
if (*t == '*')
s = t++;
Q tolower(x) != *t) {
Q *s != '*')
if (tolower(ch) != *t) {
if (*s != '*')
break;
t = s;
}
t++;
}
Q *t)
fseek(f, m, SEEK_SET);
k !*t;
if (*t != '\0')
fseek(fp, mark, SEEK_SET);
return *t == '\0';
}
/*
* Flush the line wrap buffer and outdent the heading that
* is to follow.
*/
void
d(c s)
head(char *s)
{
Q 4 < B)
P('\n');
P('\n');
Q *s == 'h')
B = 1;
if (4 < bufferLength)
printc('\n');
printc('\n');
if (*s == 'h')
bufferLength = 1;
}
/*
* This used to be two functions. It handles the parsing of
* <a href="URL">, <img alt="text", and <frame src="URL"> to
* add links to the link table. It also handles line separation
* for text formatting tags like </p>, <hr/>, <br/>, and some
* some others (see tablep[] below).
*/
void
a(c s)
link(char *s)
{
*T = 0;
G
ungetc(fgetc(f), f) == '"'
? "\"%511[^\"]"
: "'%511[^']",
T
text[0] = '\0';
fscanf(fp,
peek(fp) == '"'
? "\"%511[^\"]"
: "'%511[^']",
text
);
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("*>");
if (*s == 'a' || *s == 'f' || s[1] == 'f') {
free(links[++linksLength]);
links[linksLength] = strdup(text);
prints(" [%d] ", linksLength);
}
if (*s != 'a')
prints("%s%s\n", text, *s == 'b' || s[1] == 'h' ? "" : "\n");
fnext("*>");
}
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
void *table[] = {
"!--*-->" , NULL ,
"a *href=" , link , /* Assumes space after tag name */
"ifr*src=" , link ,
"fra*src=" , link ,
/* If we search for "img*alt=" and the current tag has no alt
* attribute, then we could end up scanning over lots of text
* and tags until we find one. An <img> can only be assured to
* have a src attribute.
*/
"img*src=" , link ,
"p*>" , head , /* Closing tag not certain. */
"bl*>" , head ,
"br" , link ,
"hr" , link ,
"h*>" , head ,
"/h" , link ,
"/tr" , link ,
"/dt" , link ,
"/dd" , link ,
"li*>" , head , /* Closing tag not certain. */
"*>" , NULL , /* Skip other tags. */
NULL , NULL
};
I
main(I V, c *v)
int
main(int argc, char **argv)
{
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);
int ch, n = 0;
char *url = argv[1];
#if defined(__WIN32__) || defined(__CYGWIN__)
WORD version;
WSADATA wsaData;
version = MAKEWORD(2, 2);
if (WSAStartup(version, &wsaData) != 0)
return 1;
#else
# ifdef TIOCGWINSZ
ioctl(0, TIOCGWINSZ, winsz);
# endif
#endif
fp = fopen("entities.txt", "r");
if (fp != NULL) {
while (fscanf(fp, "%s %d", entities[n]+1, &ch) == 2)
*entities[n++] = ch;
fclose(fp);
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;
}
while (url != NULL) {
SOCKET fd = 0;
struct hostent *he;
struct sockaddr_in addr;
linksLength = 0;
bufferLength = 1;
if (sscanf(url, "http://%255[^/]%n", host, &n) == 0 && *host == '\0') {
/* Assume local file. */
if ((fp = fopen(url, "rb")) == NULL)
return 1;
goto nextpage;
}
Q 0 < sscanf(h, "%*[^:]%n:%d", &x, &H))
h[x] = 0;
/* Parse the URL into host, port, URI. */
if (0 < sscanf(host, "%*[^:]%n:%d", &ch, &port))
host[ch] = '\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
port = 80;
/* Build the web site address. */
he = gethostbyname(host);
if (he == NULL)
/* NOTE that Win32 does not handle IP address for the
* host name and so must be handled separately, before
* considering this a true error.
*/
return 1;
memcpy(&addr.sin_addr.s_addr, he->h_addr, he->h_length);
addr.sin_port = htons(/* (unsigned short) */ (short) port);
addr.sin_family = he->h_addrtype;
/* Create a really short lived cache file. */
fp = tmpfile();
if (fp == NULL)
return 1;
#ifdef ORIGINAL_VERSION
while (connect(fd = socket(addr.sin_family, SOCK_STREAM, 0),/* (struct sockaddr *) */ (void *) &addr, sizeof addr) != 0) {
UPDATE_ERRNO;
if (errno == EISCONN)
break;
if (errno != EINTR)
goto error1;
}
#else
while (
connect(
m = socket(
A.sin_family, SOCK_STREAM, 0
), (void *) &A, sizeof A
)
fd = socket(
addr.sin_family, SOCK_STREAM, 0
),/* (struct sockaddr *) */ (void *) &addr, sizeof addr
) != 0
|| errno == EINTR
)
;
/* This should work, because for EISCONN we break the loop
* and proceed to send the request. For other errors, we
* break the loop and generate another error for the send(),
* which by passes the response and closes the socket.
*/
#endif
n = snprintf(
b, Z,
"GET %s%s HTTP/1.0\r\nHost: %s:%d\r\n\r\n",
t[n] == '/' ? "" : "/", t+n, h, H
buffer, BUFSIZ,
"GET %s%s HTTP/1.0\r\nHost: %s:%d\r\n\r\n",
url[n] == '/' ? "" : "/", url+n, host, port
);
Q send(m, b, n, 0) == n) {
W 0 < (n = recv(m, b, Z, 0)))
fwrite(b, 1, n, f);
if (send(fd, buffer, n, 0) == n) {
/* Cache the response. */
while (0 < (n = recv(fd, buffer, BUFSIZ, 0)))
fwrite(buffer, 1, n, fp);
}
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 ))
#ifdef ORIGINAL_VERSION
error1:
#else
#endif
closesocket(fd);
rewind(fp);
/* We don't parse the response status or handle redirection,
* since RFC 2616 stipulates for most error responses SHOULD
* provide content explaining the error or a hypertext link
* for the user to follow for pre HTTP/1.1 software.
*/
(void) fnext("*\r\n\r\n");
nextpage:
row = 3;
/* The start of the buffer must contain a sentinel space,
* else the printc() line wrapping can seg.fault.
*/
buffer[0] = ' ';
while (row < winsz[0] && (ch = fgetc(fp)) != EOF) {
if (ch == '<') {
void **p = table;
while (*p != NULL) {
if (fnext(*p)) {
if (p[1] != NULL)
(* (void (*)(char *))
p[1])(*p);
break;
}
p += 2;
}
} else {
Q x == '&') {
G "%9[^;];", T);
x = e(T);
}
P(isspace(x) ? ' ' : x);
} else {
if (ch == '&') {
fscanf(fp, "%9[^;];", text);
ch = entity(text);
}
printc(isspace(ch) ? ' ' : ch);
}
}
printf("\n? ");
fflush(stdout);
fgets(T, Z, stdin);
Q *T == '\n')
goto e;
t = l[strtol(T, 0, 0)];
fclose(f);
fgets(text, LENGTH, stdin);
if (*text == '\n')
goto nextpage;
url = links[strtol(text, NULL, 0)];
fclose(fp);
}
k 0;
return 0;
}
+400
View File
@@ -0,0 +1,400 @@
/*
* mynx.c
*
* Copyright 2005 by Anthony Howe. All rights reserved.
*/
#define LENGTH 512
/***********************************************************************
*** No configuration below this point.
***********************************************************************/
#include <errno.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#if defined(__WIN32__) || defined(__CYGWIN__)
#include <windows.h>
#include <winsock2.h>
#ifdef ORIGINAL_VERSION
#define EISCONN WSAEISCONN
#define EINPROGRESS WSAEINPROGRESS
#define UPDATE_ERRNO if (errno == 0) errno = WSAGetLastError()
#endif
#else
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define UPDATE_ERRNO
#define SOCKET int
#define closesocket close
/* The ioctl() TIOCGWINSZ call return the same information in the same
* order for Linux, System V, abd *BSD, but for some stupid reason they
* can't agree on a standard structure name. Fuck'em.
*
* Linux, System V:
*
* struct winsize {
* unsigned short ws_row;
* unsigned short ws_col;
* unsigned short ws_xpixel;
* unsigned short ws_ypixel;
* };
*
*
* OpenBSD
*
* struct ttysize {
* unsigned short ts_lines;
* unsigned short ts_cols;
* unsigned short ts_xxx;
* unsigned short ts_yyy;
* };
*/
#include <sys/ioctl.h>
#endif
#define peek(f) ungetc(fgetc(f), f)
FILE *fp;
short winsz[4] = { 24, 80 };
int linksLength, bufferLength, row, port;
char *links[LENGTH], buffer[BUFSIZ], fmtbuf[BUFSIZ], entities[LENGTH][10], text[LENGTH], host[LENGTH];
int
entity(char *s)
{
int n = 0;
if (*s == '#')
return (int) strtol(s+1, NULL, 0);
while (n < LENGTH) {
if (*entities[n] != '\0' && strcmp(s, entities[n]+1) == 0)
return *entities[n];
n++;
}
return '?';
}
/*
* Line wrap print controller.
*/
void
printc(int ch)
{
/* Flush current line buffer. */
if (ch == '\n' || winsz[1] - 3 < bufferLength) {
buffer[bufferLength] = '\0';
buffer[bufferLength+1] = '\0';
bufferLength = printf("%s", buffer);
bufferLength = snprintf(
buffer, BUFSIZ,
"\n %s",
buffer + bufferLength + 1
);
row++;
}
/* Compact whitespace. */
if (buffer[bufferLength-1] != ' ' || !isspace(ch)) {
/* Append character to line wrap buffer. */
buffer[bufferLength++] = isspace(ch) ? ' ' : ch;
/* If we've exceed the screen width, wrap just before previous word. */
if (winsz[1] - 3 < bufferLength)
*strrchr(buffer, ' ') = '\0';
}
}
void
prints(char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vsnprintf(fmtbuf, LENGTH, fmt, args);
fmt = fmtbuf;
while (*fmt != '\0')
printc(*fmt++);
va_end(args);
}
/*
* Find the next occurence of string. If the string is not found.
* rewind to the file pointer to its starting point.
*
* @param fp
* File pointer to scan through.
*
* @param s
* The string to match. An astrisk '*' acts as wildcard,
* scanning over zero or more bytes:
*
* "abc" match "abc" at the current offset
*
* "*abc" find "abc" from the current offset.
*
* "abc*def" match "abc", then find "def".
*
* "*abc*def" find "abc", then find "def"
*
* @return
* True on a successful match.
*/
int
fnext(char *s)
{
int ch;
char *t = s;
long mark = ftell(fp);
while (*t != '\0' && (ch = fgetc(fp)) != EOF) {
if (*t == '*')
s = t++;
if (tolower(ch) != *t) {
if (*s != '*')
break;
t = s;
}
t++;
}
if (*t != '\0')
fseek(fp, mark, SEEK_SET);
return *t == '\0';
}
/*
* Flush the line wrap buffer and outdent the heading that
* is to follow.
*/
void
head(char *s)
{
if (4 < bufferLength)
printc('\n');
printc('\n');
if (*s == 'h')
bufferLength = 1;
}
/*
* This used to be two functions. It handles the parsing of
* <a href="URL">, <img alt="text", and <frame src="URL"> to
* add links to the link table. It also handles line separation
* for text formatting tags like </p>, <hr/>, <br/>, and some
* some others (see tablep[] below).
*/
void
link(char *s)
{
text[0] = '\0';
fscanf(fp,
peek(fp) == '"'
? "\"%511[^\"]"
: "'%511[^']",
text
);
if (*s == 'a' || *s == 'f' || s[1] == 'f') {
free(links[++linksLength]);
links[linksLength] = strdup(text);
prints(" [%d] ", linksLength);
}
if (*s != 'a')
prints("%s%s\n", text, *s == 'b' || s[1] == 'h' ? "" : "\n");
fnext("*>");
}
void *table[] = {
"!--*-->" , NULL ,
"a *href=" , link , /* Assumes space after tag name */
"ifr*src=" , link ,
"fra*src=" , link ,
/* If we search for "img*alt=" and the current tag has no alt
* attribute, then we could end up scanning over lots of text
* and tags until we find one. An <img> can only be assured to
* have a src attribute.
*/
"img*src=" , link ,
"p*>" , head , /* Closing tag not certain. */
"bl*>" , head ,
"br" , link ,
"hr" , link ,
"h*>" , head ,
"/h" , link ,
"/tr" , link ,
"/dt" , link ,
"/dd" , link ,
"li*>" , head , /* Closing tag not certain. */
"*>" , NULL , /* Skip other tags. */
NULL , NULL
};
int
main(int argc, char **argv)
{
int ch, n = 0;
char *url = argv[1];
#if defined(__WIN32__) || defined(__CYGWIN__)
WORD version;
WSADATA wsaData;
version = MAKEWORD(2, 2);
if (WSAStartup(version, &wsaData) != 0)
return 1;
#else
# ifdef TIOCGWINSZ
ioctl(0, TIOCGWINSZ, winsz);
# endif
#endif
fp = fopen("entities.txt", "r");
if (fp != NULL) {
while (fscanf(fp, "%s %d", entities[n]+1, &ch) == 2)
*entities[n++] = ch;
fclose(fp);
n = 0;
}
while (url != NULL) {
SOCKET fd = 0;
struct hostent *he;
struct sockaddr_in addr;
linksLength = 0;
bufferLength = 1;
if (sscanf(url, "http://%255[^/]%n", host, &n) == 0 && *host == '\0') {
/* Assume local file. */
if ((fp = fopen(url, "rb")) == NULL)
return 1;
goto nextpage;
}
/* Parse the URL into host, port, URI. */
if (0 < sscanf(host, "%*[^:]%n:%d", &ch, &port))
host[ch] = '\0';
else
port = 80;
/* Build the web site address. */
he = gethostbyname(host);
if (he == NULL)
/* NOTE that Win32 does not handle IP address for the
* host name and so must be handled separately, before
* considering this a true error.
*/
return 1;
memcpy(&addr.sin_addr.s_addr, he->h_addr, he->h_length);
addr.sin_port = htons(/* (unsigned short) */ (short) port);
addr.sin_family = he->h_addrtype;
/* Create a really short lived cache file. */
fp = tmpfile();
if (fp == NULL)
return 1;
#ifdef ORIGINAL_VERSION
while (connect(fd = socket(addr.sin_family, SOCK_STREAM, 0),/* (struct sockaddr *) */ (void *) &addr, sizeof addr) != 0) {
UPDATE_ERRNO;
if (errno == EISCONN)
break;
if (errno != EINTR)
goto error1;
}
#else
while (
connect(
fd = socket(
addr.sin_family, SOCK_STREAM, 0
),/* (struct sockaddr *) */ (void *) &addr, sizeof addr
) != 0
|| errno == EINTR
)
;
/* This should work, because for EISCONN we break the loop
* and proceed to send the request. For other errors, we
* break the loop and generate another error for the send(),
* which by passes the response and closes the socket.
*/
#endif
n = snprintf(
buffer, BUFSIZ,
"GET %s%s HTTP/1.0\r\nHost: %s:%d\r\n\r\n",
url[n] == '/' ? "" : "/", url+n, host, port
);
if (send(fd, buffer, n, 0) == n) {
/* Cache the response. */
while (0 < (n = recv(fd, buffer, BUFSIZ, 0)))
fwrite(buffer, 1, n, fp);
}
#ifdef ORIGINAL_VERSION
error1:
#else
#endif
closesocket(fd);
rewind(fp);
/* We don't parse the response status or handle redirection,
* since RFC 2616 stipulates for most error responses SHOULD
* provide content explaining the error or a hypertext link
* for the user to follow for pre HTTP/1.1 software.
*/
(void) fnext("*\r\n\r\n");
nextpage:
row = 3;
/* The start of the buffer must contain a sentinel space,
* else the printc() line wrapping can seg.fault.
*/
buffer[0] = ' ';
while (row < winsz[0] && (ch = fgetc(fp)) != EOF) {
if (ch == '<') {
void **p = table;
while (*p != NULL) {
if (fnext(*p)) {
if (p[1] != NULL)
(* (void (*)(char *))
p[1])(*p);
break;
}
p += 2;
}
} else {
if (ch == '&') {
fscanf(fp, "%9[^;];", text);
ch = entity(text);
}
printc(isspace(ch) ? ' ' : ch);
}
}
printf("\n? ");
fflush(stdout);
fgets(text, LENGTH, stdin);
if (*text == '\n')
goto nextpage;
url = links[strtol(text, NULL, 0)];
fclose(fp);
}
return 0;
}
+4227
View File
File diff suppressed because it is too large. Load diff
+77
View File
@@ -0,0 +1,77 @@
#######################################################################
# Thus it begins...
#######################################################################
AC_PREREQ(2.59)
AC_INIT(mynx, 1.0, [Public Domain 2005 by Anthony Howe.])
platform=`uname -s|sed -e 's/^\([[a-zA-Z0-9]]*\)[[^a-zA-Z0-9]].*/\1/'`
echo "platform is... $platform"
my_configure_command="$[]0 $[]@"
AC_CHECK_TOOL(autoconf_tool, autoconf)
if test ${autoconf_tool:-no} != 'no' -a \( aclocal.m4 -nt configure -o configure.in -nt configure \); then
echo 'Rebuilding the configure script first...'
autoconf -f
echo 'Restarting configure script...'
echo $my_configure_command
exec $my_configure_command
fi
AC_SUBST(platform, $platform)
#######################################################################
# Auxliary files to be modified later
#######################################################################
AC_CONFIG_SRCDIR($PACKAGE_NAME.c)
AC_CONFIG_FILES(makefile)
#######################################################################
# Configuration options
#######################################################################
AC_ARG_ENABLE(w32,
[AC_HELP_STRING([--disable-w32],[generate Cygwin binary in Cygwin environment])]
)
#######################################################################
# Setup defaults
#######################################################################
if test $platform = 'CYGWIN' -a ${enable_w32:-yes} != 'no' ; then
CFLAGS="-mno-cygwin ${CFLAGS}"
LIBS="-lws2_32 ${LIBS}"
fi
#######################################################################
# We find things...
#######################################################################
AC_PROG_CC
AC_HEADER_STDC
AC_SEARCH_LIBS(socket, [socket nsl],[AC_DEFINE_UNQUOTED([AS_TR_CPP([HAVE_SOCKET])])])
AC_CHECK_HEADERS(
[arpa/inet.h netdb.h netinet/in.h sys/socket.h sys/ioctl.h],
[], [AC_MSG_FAILURE([Missing required network I/O header.], 1)]
)
AC_CHECK_HEADERS([windows.h winsock2.h])
#######################################################################
# Generate output.
#######################################################################
AC_OUTPUT()
echo
echo $PACKAGE_STRING
echo
AC_MSG_RESULT([ platform...: $platform])
AC_MSG_RESULT([ prefix.....: $prefix])
AC_MSG_RESULT([ CFLAGS.....: $CFLAGS])
AC_MSG_RESULT([ LDFLAGS....: $LDFLAGS])
AC_MSG_RESULT([ LIBS.......: $LIBS])
echo
+52
View File
@@ -0,0 +1,52 @@
#
# Public Domain 2005 by Anthony Howe.
#
.POSIX :
########################################################################
### No further configuration beyond this point.
########################################################################
top_srcdir = ..
PACKAGE = @PACKAGE_NAME@
CC = @CC@
CFLAGS = @CFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
E = @EXEEXT@
#######################################################################
build: ${PACKAGE}$E
clean:
-rm ${PACKAGE}$E
distclean: clean
-rm config.status configure.lineno config.log makefile
-rm -rf autom4te.cache
-rm ioccc$E right$E
${PACKAGE}$E: ${PACKAGE}.c
${CC} ${CFLAGS} ${LDFLAGS} -o${PACKAGE} ${PACKAGE}.c ${LIBS}
${top_srcdir}/${PACKAGE}.c: ${PACKAGE}.c transform.sed ioccc$E ${top_srcdir}/entities.txt
@echo '***************************************************************'
@sed -f transform.sed ${PACKAGE}.c | ioccc$E | sed -e '/^[ ]*$$/d' >${top_srcdir}/${PACKAGE}.c
@echo '***************************************************************'
${top_srcdir}/${PACKAGE}-alt.c: ${top_srcdir}/${PACKAGE}.c right$E
right <${top_srcdir}/${PACKAGE}.c >${top_srcdir}/${PACKAGE}-alt.c
${top_srcdir}/entities.txt: entities.txt
cp entities.txt ${top_srcdir}/entities.txt
ioccc$E: ioccc.c
$(CC) -oioccc$E ioccc.c
right$E: right.c
$(CC) -oright$E right.c
tar: ${top_srcdir}/entities.txt ${top_srcdir}/${PACKAGE}.c ${top_srcdir}/${PACKAGE}-alt.c
+184
View File
@@ -0,0 +1,184 @@
#
# Keywords & Phrases
#
#/LOG/d
#/NDEBUG/d
/^#if/,/^#else/d
/^#endif/d
/UPDATE_ERRNO/d
#
# Replace macros.
#
/^#define peek/d
s/peek(fp)/ungetc(fgetc(fp), fp)/
/^#.*define closesocket/d
s/closesocket/close/
/^#.*define SOCKET/d
s/SOCKET/int/
#
#
#
s/\<int\>/I/
1i\
#define I int
s/char \*/c /
1i\
#define c char *
s/fscanf(fp,/G/
1i\
#define G fscanf(f,
#s/break;/B/
#1i\
##define B break;
#s/goto/j/
#1i\
##define j goto
s/while (/W /
1i\
#define W while(
s/return/k/
1i\
#define k return
s/if (/Q /
1i\
#define Q if(
#s/ else / E /
#1i\
##define E else
#s/fgetc(stdin)/G/
#1i\
##define G fgetc(stdin)
#
#s/fputc(\(.*\), stdout);/p(\1)/
#1i\
##define p(c) fputc(c, stdout);
#
#s/ungetc(\(.*\), stdin)/u(\1)/
#1i\
##define u(c) ungetc(c, stdin)
#
# Constant expansion
#
s/LENGTH/Z/g
s/BUFSIZ/Z/g
s/NULL/0/g
s/(void)//g
s/'\\0'/0/g
s/bufferLength/B/g
s/buffer/b/g
s/\<host\>/h/g
s/\<port\>/H/g
s/linksLength/L/g
s/links/l/g
#
# Functions & Types
#
s/printc(/P(/
s/prints(/p(/
s/mynx(/M(/
s/head/d/
s/spit/D/
s/link/a/
s/fnext(/X(/
s/entity(/e(/
#
# Labels
#
s/error0/a/
s/error1/b/
s/error2/c/
s/display/d/
s/nextpage/e/
#
# Variables
#
# n, m, *s, *t, x, y are used for parameters and local variables.
#
s/fmtbuf/s/g
s/fmt/t/g
s/args/x/g
s/url/t/g
s/mark/m/g
s/rows/R/g
s/row/r/g
s/cols/C/g
s/fp/f/g
s/fd/m/g
s/table/Y/g
s/text/T/g
s/entities\[/S[/g
s/lastspace/q/g
s/next/N/g
s/argc/V/g
s/argv/v/g
s/winsz/w/g
s/\<addr\>/A/g
s/\([^t]\)ch\([^ar]\)/\1x\2/g
s/\([^t]\)he\([^a]\)/\1y\2/g
#
# Expressions
#
#s/([a-z ]*\*) 0/0/g
#s/0 == /!/g
#s/0 == /!/g
s/\([^ ]*[^)]\) == 0/!\1/g
s/\([a-z]*(.*)\) == 0/!\1/g
#s/\((.*)\) == 0/!\1/g
#s/0 < sscanf/sscanf/
s/(0 < /(/g
s/ != 0//g
s/\([^ ]*[^[]\)\[0\]/*\1/g
#s/0 > //g
#s/ < 0)/)/g
#s/R (\(.*\))/R \1/
#
# Braces
#
#/[ ]{/ {
#h
#s/[ ]{//
#a\
#{
#
#}
#
##s/^[ ]*//
#s/^[ ]*}/}/
#
##/^[ ]*$/d
# Expand tabs...
#s/ /&&&&/g
# Compress tabs...
#s/ / /g