/**
* Scout HTML Parser
*
* Copyright (C) 2002 by
* Jeffrey Fulmer -
* Ken Jones -
* This file is distributed as part of Scout
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include
#include
#include
#include
#include
#include
#include
#include
#define BUF 512
#define URLBUF 1024
void *html_lower(char *html_text);
void *assemble_url( char *ref, char *req );
void *parse_control( char *path, char *token );
char *strstart( char *sstr, char *tstr );
int
test_string( char *s )
{
while( *s ){
if( !ISASCII( *s ) ) return 0;
printf( " %d[%s] ", *s, s );
s++;
}
return 1;
}
char *
url_trim( char *str )
{
register char c;
int x = 0;
char *a;
char *s = (char *) str;
if( str == NULL ) return NULL;
/**
* advance the ptr omitting any
* HTML anchors...
*/
do {
c = *s;
switch((char)*s){
case '\n':
case '\r':
case '#':
case '\\':
case '\'':
break;
case '/':
if( x > 6 )
if( a[x-1]=='/' )
break;
a[x] = c;
x++;
break;
default:
a[x] = c;
x++;
break;
}
s++;
} while( *s && *s != '#' );
a[x] = '\0';
return (char*)a; /* UNIX friendly */
}
void *
parse_text( char *path, char *html_text )
{
int i;
char *tmp;
char buf[MEDFILE];
memset( buf, 0, MEDFILE );
html_lower( html_text );
tmp = html_text;
while( *tmp != (char)NULL ) {
if( *tmp == '<' ){
tmp++;
/**
* ignore comments
*/
if( tmp == strstart( tmp, "!--" )){
tmp++;
while( *tmp != (char)NULL ){
if ( tmp == strstart(tmp, "-->")){
tmp += 3;
break;
}
tmp++;
}
}
/**
* scripts
*/
else if( tmp == strstart( tmp,"script" )) {
i = 0;
tmp++;
while( *tmp != (char)NULL && i < ( MEDFILE-1 )) {
if ( tmp == strstart( tmp, "" )){
tmp+=9;
break;
}
else {
buf[i] = *tmp;
i++;
tmp++;
}
}
buf[i] = 0;
parse_control( path, buf );
}
/**
* standard html
*/
else{
i = 0;
while( *tmp != (char)NULL && *tmp != '>' && i < ( MEDFILE-1 )) {
buf[i] = *tmp;
i++;
tmp++;
}
buf[i] = 0;
parse_control( path, buf );
}
} /* end tmp!=NULL */
if ( *tmp != (char)NULL ) {
tmp++;
}
} /* end while loop */
return;
}
char *
strstart( char *sstr, char *tstr )
{
char *ret_str;
ret_str = sstr;
if( sstr == NULL || tstr == NULL ){
return(NULL);
}
while( *sstr != 0 && *tstr != 0 ){
if( *sstr != *tstr ){
return(NULL);
}
++sstr;
++tstr;
}
if( *tstr == 0 ){
return(ret_str);
}
return(NULL);
}
void *
parse_control( char *path, char *token )
{
char *tmp;
char **dirs;
int count;
char buf[BUF];
char url[URLBUF];
tmp = strtok(token, TOKENS);
while ( tmp != NULL ) {
/* search for "link href=tokens_plus" */
if( !strncmp( tmp, "link", 3 )){
tmp = strtok(NULL, TOKENS);
if( tmp != NULL ){
if( !strncmp( tmp, "href", 3 )){
tmp = strtok( NULL, TOKENS_PLUS );
if ( tmp != NULL ) {
assemble_url( path, tmp );
}
}
}
}
/* search for "a href=tokens_plus" */
else if( !strncmp( tmp, "href", 4 )){
tmp = strtok( NULL, TOKENS_PLUS );
if( tmp != NULL ){
assemble_url( path, tmp );
}
return;
}
else if( !strncmp( tmp, "location.href", 13 )){
tmp = strtok(NULL, TOKENS_PLUS);
if ( tmp != NULL ) {
assemble_url( path, tmp );
}
}
else if( !strncmp( tmp, "img", 3 )){
if( my.images ){
tmp = strtok(NULL, TOKENS);
if( tmp != NULL ){
if( !strncmp( tmp, "src", 3 )){
tmp = strtok( NULL, TOKENS_PLUS );
if ( tmp != NULL ) {
assemble_url( path, tmp );
}
}
}
}
/* user doesn't want images */
else{ return; }
}
else if( !strncmp( tmp, "frame", 5 )){
tmp = strtok(NULL, TOKENS);
while( tmp != NULL ){
if( !strncmp( tmp, "src", 3 )){
tmp = strtok(NULL, TOKENS_PLUS);
if( tmp != NULL ){
assemble_url( path, tmp );
}
}
tmp = strtok(NULL, TOKENS);
}
}
else if( !strncmp( tmp, "background", 10 )){
tmp = strtok(NULL, TOKENS_PLUS);
if ( tmp != NULL ) {
assemble_url( path, tmp );
}
}
tmp = strtok(NULL, TOKENS);
}
}
void *
assemble_url( char *ref, char *req )
{
char buf[BUF];
char url[URLBUF];
memset( buf, 0, BUF );
memset( url, 0, URLBUF );
strncpy( buf, req, BUF-1 );
if( !strncmp( buf, "#", 1 ))
return; /* we're not a browswer... */
else if( has_protocol( buf )){
if( is_supported( buf ))
snprintf( url, URLBUF, "%s", buf );
else
return;
}
else if( !strncmp( buf, "/", 1 )){
snprintf( url, URLBUF, "http://%s%s", my.hostname, buf );
if( url ){
url_trim( url );
if( !find_node( url )){
add_node( url );
}
}
else
return;
}
else if(( !strncmp( buf, ".", 1 )) || ( isalpha( buf[0] ))){
int x, y, r1, r2;
char **reference;
char **request;
char uri[256];
reference = split( '/', ref, &r1 );
if( !strstr( buf, "/" )){
/* top level, no refernce to '/' */
strncpy( uri, "/", sizeof( uri ));
strncat( uri, buf, sizeof( uri ));
snprintf( url, URLBUF, "http://%s%s", my.hostname, uri );
url_trim( url );
if( !find_node( url )){
add_node( url );
}
return;
}
else{
request = split( '/', buf, &r2 );
}
strncpy( uri, "", sizeof( uri ));
for( x = 0; x < r2; x ++ ){
if( !strncmp( request[x], "..", 2 )){
strncat( uri, "/", sizeof( uri ));
strncat( uri, reference[x], sizeof( uri ));
}
else if( !strncmp( request[x], ".", 1 )){
for( y = 0; y < r1 - 1; y++ ){
strncat( uri, "/", sizeof( uri ));
strncat( uri, reference[y], sizeof( uri ));
}
}
else if( !strncmp( request[x], "/", 1 )){
strncat( uri, request[x], sizeof( uri ));
}
else{
if( strncmp( uri, "/", strlen( uri )))
strncat( uri, "/", sizeof( uri ));
strncat( uri, request[x], sizeof( uri ));
}
}
if( uri[0] == '/' )
snprintf( url, URLBUF, "http://%s%s", my.hostname, uri );
else
snprintf( url, URLBUF, "http://%s/%s", my.hostname, uri );
if( url ){
url_trim( url );
if( !find_node( url )){
add_node( url );
}
}
else
return;
}
else{
snprintf( url, URLBUF, "http://%s/%s", my.hostname, buf );
if( url ){
url_trim( url );
if( !find_node( url )){
add_node( url );
}
}
else
return;
}
} /* end of assemble_url */
void *
html_lower(char *html_text)
{
char *tmp;
int in_angle;
int in_quotes;
int i;
tmp = html_text;
in_angle = 0;
in_quotes = 0;
i = 0;
while( *tmp != 0 ) {
if ( in_angle == 1 ) {
if ( in_quotes == 1 ) {
if ( *tmp == '"' ) {
in_quotes = 0;
}
} else if ( *tmp == '>' ) {
in_angle = 0;
} else if ( *tmp == '"') {
in_quotes = 1;
} else if ( isupper(*tmp) ) {
*tmp = tolower(*tmp);
} else if ( *tmp == '\n' ) {
*tmp = ' ';
}
} else if ( *tmp == '<' ) {
in_angle = 1;
}
i++;
tmp++;
}
}
char *
cleanupName(char *name)
{
char *buf, *p, *q;
buf = strdup( name );
p = buf;
q = name;
while (*q != '\0') {
if( strncmp(p, "/../", 4) == 0) { /* foo/bar/../FOO */
if( p - 2 == buf && strncmp(p - 2, "..", 2) == 0) {
/* ../../ */
p += 3;
q += 3;
}
else if (p - 3 >= buf && strncmp(p - 3, "/..", 3) == 0) {
/* ../../../ */
p += 3;
q += 3;
}
else {
while (p != buf && *--p != '/') ; /* ->foo/FOO */
*p = '\0';
q += 3;
strcat(buf, q);
}
}
else if (strcmp(p, "/..") == 0) { /* foo/bar/.. */
if (p - 2 == buf && strncmp(p - 2, "..", 2) == 0) {
/* ../.. */
}
else if (p - 3 >= buf && strncmp(p - 3, "/..", 3) == 0) {
/* ../../.. */
}
else {
while (p != buf && *--p != '/') ; /* ->foo/ */
*++p = '\0';
}
break;
}
else if (strncmp(p, "../", 3) == 0){
while (p != buf && *--p != '/') ; /* ->foo/ */
*++p = '\0';
}
else if (strncmp(p, "/./", 3) == 0) { /* foo/./bar */
*p = '\0'; /* -> foo/bar */
q += 2;
strcat(buf, q);
}
else if (strcmp(p, "/.") == 0) { /* foo/. */
*++p = '\0'; /* -> foo/ */
break;
}
else if (strncmp(p, "//", 2) == 0) { /* foo//bar */
/* -> foo/bar */
*p = '\0';
q++;
strcat(buf, q);
}
else {
p++;
q++;
}
}
return buf;
}