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:
1 parent
60ce3d9155
commit
0d65af1b2b
65 files changed
+15579
-218
No files matched your search
@@ -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;
|
||||
}
|
||||
Reference in new issue
Block a user