/* $Id: more.c,v 1.11 2002/04/27 15:50:17 in2 Exp $ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>

#include "config.h"
#include "pttstruct.h"
#include "common.h"
#include "modes.h"
#include "perm.h"
#include "proto.h"

extern int showansi;
extern int t_lines, t_columns;  /* Screen size / width */
extern int b_lines;             /* Screen bottom line number: t_lines-1 */
extern char *str_author1;
extern char *str_author2;
extern char *str_post1;
extern char *str_post2;
extern char *msg_seperator;
extern char reset_color[];

#define MORE_BUFSIZE	4096
#define MORE_WINSIZE	4096
#define STR_ANSICODE    "[0123456789;,"

static int more_base, more_size, more_head;
static unsigned char more_pool[MORE_BUFSIZE];


#define MAXPATHLEN 256
static char *more_help[] = {
    "\0�\\Ū�峹�\\����ϥλ���",
    "\01��в��ʥ\\����",
    "(��)                  �W���@��",
    "(��)(Enter)           �U���@��",
    "(^B)(PgUp)(BackSpace) �W���@��",
    "(��)(PgDn)(Space)     �U���@��",
    "(0)(g)(Home)          �ɮ׶}�Y",
    "($)(G) (End)          �ɮ׵���",
    "\01��L�\\����",
    "(/)                   �j�M�r��",
    "(n/N)                 ���ƥ�/�ϦV�j�M",
    "(TAB)                 URL�s��",
    "(Ctrl-T)              �s��Ȧs��",
    "(:/f/b)               ���ܬY��/�U/�W�g",
    "(F/B)                 ���ܦP�@�j�M�D�D�U/�W�g",
    "(a/A)                 ���ܦP�@�@�̤U/�W�g",
    "([/])                 �D�D���\\Ū �W/�U",
    "(t)                   �D�D���`�Ǿ\\Ū",
    "(Ctrl-C)              �p�p���",
    "(q)(��)               ����",
    "(h)(H)(?)             ���U�����e��",
    NULL
};

int beep = 0;

static void
more_goto (int fd, off_t off)
{ 
  int base = more_base;

  if (off < base || off >= base + more_size)
  { 
    more_base = base = off & (-MORE_WINSIZE);
    lseek (fd, base, SEEK_SET);
    more_size = read (fd, more_pool, MORE_BUFSIZE);
  }
  more_head = off - base;
}

static int
more_readln (int fd, unsigned char *buf)
{
  int ch;

  unsigned char *data, *tail, *cc;
  int len, bytes, in_ansi;
  int size, head, ansilen;

  len = bytes = in_ansi = ansilen = 0;
  tail = buf + ANSILINELEN - 1;
  size = more_size;
  head = more_head;
  data = &more_pool[head];

  do
  {
    if (head >= size)
    {
      more_base += size;
      data = more_pool;
      more_size = size = read (fd, data, MORE_BUFSIZE);
      if (size == 0)
        break;
      head = 0;
    }

    ch = *data++;
    head++;
    bytes++;
    if (ch == '\n')
    { 
      break;
    }
    if (ch == '\t')
    { 
      do
      { 
        *buf++ = ' ';
      }
      while ((++len & 7) && len < 80);
    }
    else if (ch == '\033')
    { 
      if (atoi ((char *)(data + 1)) > 47)
      { 
        if ((cc = (unsigned char *)strchr ((char *)(data + 1), 'm')) != NULL)
        { 
          ch = cc - data + 1;

          data += ch;
          head += ch;
          bytes += ch;
        }
      }
      else
      { 
        if (showansi)
          *buf++ = ch;
        in_ansi = 1;
      }
    }
    else if (in_ansi)
    {
      if (showansi)
        *buf++ = ch;
      if (!strchr (STR_ANSICODE, ch))
        in_ansi = 0;
    }
    else if (isprint2 (ch))
    { 
      len++;
      *buf++ = ch;
    }
  }
  while (len < 80 && buf < tail);
  *buf = '\0';
  more_head = head;
  return bytes;
}

/* not used 
static int readln(FILE *fp, char *buf) {
    register int ch, i, len, bytes, in_ansi;

    len = bytes = in_ansi = i = 0;
    while(len < 80 && i < ANSILINELEN && (ch = getc(fp)) != EOF) {
	bytes++;
	if(ch == '\n')
	    break;
	else if(ch == '\t')
	    do {
		buf[i++] = ' ';
	    } while((++len & 7) && len < 80);
	else if(ch == '\a')
	    beep = 1;
	else if(ch == '\033') {
	    if(showansi)
		buf[i++] = ch;
	    in_ansi = 1;
	} else if(in_ansi) {
	    if(showansi)
		buf[i++] = ch;
	    if(!strchr("[0123456789;,", ch))
		in_ansi = 0;
	} else if(isprint2(ch)) {
	    len++;
	    buf[i++] = ch;
	}
    }
    buf[i] = '\0';
    return bytes;
}
*/

extern userec_t cuser;

static int more_web(char *fpath, int promptend);
extern int *GLOBE;
int more(char *fpath, int promptend) {
    extern char* strcasestr();
    static char *head[4] = {"�@��", "���D", "�ɶ�" ,"��H"};
    char *ptr, *word = NULL, buf[ANSILINELEN + 1], *ch1;
    struct stat st;

/* rocker */
    //FILE *fp;
    int fd, fsize;

    unsigned int pagebreak[MAX_PAGES], pageno, lino = 0;
    int line, ch, viewed, pos, numbytes;
    int header = 0;
    int local = 0;
    char search_char0=0;
    static char search_str[81]="";
    typedef char* (*FPTR)();
    static FPTR fptr;
    int searching = 0;
    int scrollup = 0;
    char *printcolor[3]= {"44","33;45","0;34;46"}, color =0;
    char *http[80]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
		    NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
		    NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
		    NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
		    NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
		    NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
		    NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
		    NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
    /* Ptt */
    char pagemode = 0;
    char pagecount = 0;

    memset(pagebreak, 0, sizeof(pagebreak));
    if(*search_str)
	search_char0 = *search_str;
    *search_str = 0;

#ifdef MDCACHE
    fd = mdcacheopen(fpath);
#else    
    fd = open (fpath, O_RDONLY, 0600); 
#endif
    if (fd < 0) return -1;
    
    if(fstat(fd, &st) || ((fsize = st.st_size) <= 0) || S_ISDIR (st.st_mode))
     {
        close(fd); //Ptt
	return -1;
     }
    pagebreak[0] = pageno = viewed = line = pos = 0;
    clear();

/* rocker */

   more_base = more_head = more_size = 0;
    
    while((numbytes = more_readln(fd, (unsigned char *)buf)) || (line == t_lines)) {
	if(scrollup) {
	    rscroll();
	    move(0, 0);
	}
	if(numbytes) {              /* �@���ƳB�z */
	    if(!viewed) {             /* begin of file */
		if(showansi) {          /* header processing */
		    if(!strncmp(buf, str_author1, LEN_AUTHOR1)) {
			line = 3;
			word = buf + LEN_AUTHOR1;
			local = 1;
		    } else if(!strncmp(buf, str_author2, LEN_AUTHOR2)) {
			line = 4;
			word = buf + LEN_AUTHOR2;
		    }
		    
		    while(pos < line) {
			if(!pos && ((ptr = strstr(word, str_post1)) ||
				    (ptr = strstr(word, str_post2)))) {
			    ptr[-1] = '\0';
			    prints("\033[47;34m %s \033[44;37m%-53.53s"
				   "\033[47;34m %.4s \033[44;37m%-13s\033[m\n",
				   head[0], word, ptr, ptr + 5);
			} else if (pos < line)
			    prints("\033[47;34m %s \033[44;37m%-72.72s"
				   "\033[m\n", head[pos], word);
			
			viewed += numbytes;
			numbytes = more_readln(fd, (unsigned char *)buf);
			
			/* �Ĥ@��Ӫ��F */			
			if(!pos && viewed > 79) {
                            /* �ĤG�椣�O [��....] */
			    if(memcmp( buf, head[1], 2)) { 
				/* Ū�U�@��i�ӳB�z */
				viewed += numbytes;
				numbytes = more_readln(fd, (unsigned char *)buf);
			    }
			}
			pos++;
		    }
		    if(pos) {
			header = 1;
			
			prints("\033[36m%s\033[m\n", msg_seperator);
			++line; ++pos;
		    }
		}
		lino = pos;
		word = NULL;
	    }

	    /* ���B�z�ޥΪ� & �ި� */
	    if((buf[1] == ' ') && (buf[0] == ':' || buf[0] == '>'))
		word = "\033[36m";
	    else if(!strncmp(buf, "��", 2) || !strncmp(buf, "==>", 3))
		word = "\033[32m";
	    
	    ch1 = buf;
	    while(1) {
		int i;
		char e,*ch2;

		if((ch2 = strstr(ch1, "http://")))
		    ;
		else if((ch2 = strstr(ch1,"gopher://")))
		    ;
		else if((ch2 = strstr(ch1,"mailto:")))
		    ;
		else
		    break;
		for(e = 0; ch2[(int)e] != ' ' && ch2[(int)e] != '\n' &&
			ch2[(int)e] != '\0' && ch2[(int)e] != '"' &&
			ch2[(int)e] != ';' && ch2[(int)e] != ']'; e++);
		for(i = 0; http[i] && i < 80; i++)
		    if(!strncmp(http[i], ch2, e) && http[(int)e] == 0)
			break;
		if(!http[i]) {
		    http[i] = (char *)malloc(e + 1);
		    strncpy(http[i], ch2, e);
		    http[i][(int)e] = 0;
		    pagecount++;
                }
		ch1 = &ch2[7];
	    }
	    if(word)
		outs(word);
	    {
		char msg[500], *pos;
		
		if(*search_str && (pos = fptr(buf, search_str))) {
		    char SearchStr[81];
		    char buf1[100], *pos1;
		    
		    strncpy(SearchStr, pos, strlen(search_str));
		    SearchStr[strlen(search_str)] = 0;
		    searching = 0;
		    sprintf(msg, "%.*s\033[7m%s\033[m", pos - buf, buf,
			    SearchStr);
		    while((pos = fptr(pos1 = pos + strlen(search_str),
				      search_str))) {
			sprintf(buf1, "%.*s\033[7m%s\033[m", pos - pos1,
				pos1, SearchStr);
			strcat(msg, buf1);
		    }
		    strcat(msg, pos1);
		    outs(Ptt_prints(msg,NO_RELOAD));
		} else
		    outs(Ptt_prints(buf,NO_RELOAD));
	    }
	    if(word) {
		outs("\033[m");
		word = NULL;
	    }
	    outch('\n');
	    
	    if(beep) {
		bell();
		beep = 0;
	    }

	    if(line < b_lines)       /* �@����Ū�� */
		line++;
	    
	    if(line == b_lines && searching == -1) {
		if(pageno > 0)
		    more_goto(fd, viewed = pagebreak[--pageno]);
		else
		    searching = 0;
		lino = pos = line = 0;
		clear();
		continue;
	    }
	    
	    if(scrollup) {
		move(line = b_lines, 0);
		clrtoeol();
		for(pos = 1; pos < b_lines; pos++)
		    viewed += more_readln(fd, (unsigned char *)buf);
	    } else if(pos == b_lines)  /* ���ʿù� */
		scroll();
	    else
		pos++;

	    if(!scrollup && ++lino >= b_lines && pageno < MAX_PAGES - 1) {
		pagebreak[++pageno] = viewed;
		lino = 1;
	    }

	    if(scrollup) {
		lino = scrollup;
		scrollup = 0;
	    }
	    viewed += numbytes;       /* �֭pŪ�L��� */
	} else
	    line = b_lines;           /* end of END */
	
	if(promptend &&
	   ((!searching && line == b_lines) || viewed == fsize)) {
	    /* Kaede ��n 100% �ɤ��� */
	    move(b_lines, 0);
	    if(viewed == fsize) {
		if(searching == 1)
		    searching = 0;
		color = 0;
	    } else if(pageno == 1 && lino == 1) {
		if(searching == -1)
		    searching = 0;
		color = 1;
	    } else
		color = 2;

	    prints("\033[m\033[%sm  �s�� P.%d(%d%%)  %s  %-30.30s%s",
		   printcolor[(int)color], 
		   pageno, 
		   (int)((viewed * 100) / fsize),
		   pagemode ? "\033[30;47m" : "\033[31;47m",
		   pagemode ? http[pagemode-1] : "(h)\033[30m�D�U  \033[31m����[PgUp][",
		   pagemode ? "\033[31m[TAB]\033[30m���� \033[31m[Enter]\033[30m��w \033[31m��\033[30m���\033[m" : "PgDn][Home][End]\033[30m����  \033[31m��[q]\033[30m����   \033[m");
	    
	    
	    while(line == b_lines || (line > 0 && viewed == fsize)) {
		switch((ch = egetch())) {
		case ':':
		{
		    char buf[10];
		    int i = 0;
		    
		    getdata(b_lines - 1, 0, "Goto Page: ", buf, 5, DOECHO);
		    sscanf(buf, "%d", &i);
		    if(0 < i && i <  MAX_PAGES && (i == 1 || pagebreak[i - 1]))
			pageno = i - 1;
		    else if(pageno)
			pageno--;
		    lino = line = 0;
		    break;
		}
		case '/':
		{
		    char ans[4] = "n";
		    
		    *search_str = search_char0;
		    getdata_buf(b_lines - 1, 0,"[�j�M]����r:", search_str,
				40, DOECHO);
		    if(*search_str) {
			searching = 1;
			if(getdata(b_lines - 1, 0, "�Ϥ��j�p�g(Y/N/Q)? [N] ",
				   ans, 4, LCECHO) && *ans == 'y')
			    fptr = strstr;
			else
			    fptr = strcasestr;
		    }
		    if(*ans == 'q')
			searching = 0;
		    if(pageno)
			pageno--;
		    lino = line = 0;
		    break;
		}
		case 'n':
		    if(*search_str) {
			searching = 1;
			if(pageno)
			    pageno--;
			lino = line = 0;
		    }
		    break;
		case 'N':
		    if(*search_str) {
			searching = -1;
			if(pageno)
			    pageno--;
			lino = line = 0;
		    }
		    break;
		case 'r':
		case 'R':
		case 'Y':
		    close(fd);
		    return 7;
		case 'y':
		    close(fd);
		    return 8;
		case 'A':
		    close(fd);
		    return 9;
		case 'a':
		    close(fd);
		    return 10;
		case 'F':
		    close(fd);
		    return 11;
		case 'B':
		    close(fd);
		    return 12;
		case KEY_LEFT:
		    if(pagemode) {
			pagemode = 0;
			*search_str = 0;
			if(pageno)
			    pageno--;
			lino = line = 0;
			break;
		    }
		    close(fd);
		    return 6;
		case 'q':
		    close(fd);
		    return 0;
		case 'b':
		    close(fd);
		    return 1;
		case 'f':
		    close(fd);
		    return 3;
		case ']':       /* Kaede ���F�D�D�\Ū��K */
		    close(fd);
		    return 4;
		case '[':       /* Kaede ���F�D�D�\Ū��K */
		    close(fd);
		    return 2;
		case '=':       /* Kaede ���F�D�D�\Ū��K */
		    close(fd);
		    return 5;
		case Ctrl('F'):
		case KEY_PGDN:
		    line = 1;
		    break;
		case 't':
		    if(viewed == fsize) {
			close(fd);
			return 4;
		    }
		    line = 1;
		    break;
		case ' ':
		    if(viewed == fsize) {
			close(fd);
			return 3;
		    }
		    line = 1;
		    break;
		case KEY_RIGHT:
		    if(viewed == fsize) {
			close(fd);
			return 0;
		    }
		    line = 1;
		    break;
		case '\r':
		case '\n':
		    if(pagemode) {
			more_web(http[pagemode-1],YEA);
			pagemode = 0;
			*search_str = 0;
			if(pageno)
			    pageno--;
			lino = line = 0;
			break;
		    }
		case KEY_DOWN:
		    if(viewed == fsize ||
		       (promptend == 2 && (ch == '\r' || ch == '\n'))) {
			close(fd);
			return 3;
		    }
		    line = t_lines - 2;
		    break;
		case '$':
		case 'G':
		case KEY_END:
		    line = t_lines;
		    break;
		case '0':
		case 'g':
		case KEY_HOME:
		    pageno = line = 0;
		    break;
		case 'h':
		case 'H':
		case '?':
		    /* Kaede Buggy ... */
		    show_help(more_help);
		    if(pageno)
			pageno--;
		    lino = line = 0;
		    break;
		case 'E':
		    if(HAS_PERM(PERM_SYSOP) && strcmp(fpath, "etc/ve.hlp")) {
			close(fd);
			vedit(fpath, NA, NULL);
			return 0;
		    }
		    break;
		case Ctrl('C'):
		    cal();
		    if(pageno)
			pageno--;
		    lino = line = 0;
		    break;

		case Ctrl('T'):
		    getdata(b_lines - 2, 0, "��o�g�峹���J��Ȧs�ɡH[y/N] ",
			    buf, 4, LCECHO);
		    if(buf[0] == 'y') {
			char tmpbuf[128];
			
			setuserfile(tmpbuf, ask_tmpbuf(b_lines - 1));
			sprintf(buf, "cp -f %s %s", fpath, tmpbuf);
			system(buf);
		    }
		    if(pageno)
			pageno--;
		    lino = line = 0;
		    break;
#if 0
		case Ctrl('I'):
		    if(!pagecount)
			break;
		    pagemode = (pagemode % pagecount) + 1;
		    strncpy(search_str,http[pagemode-1],80);
		    search_str[80] =0;
		    fptr = strstr;
		    if(pageno)
			pageno--;
		    lino = line = 0;
		    break;
#endif
		case KEY_UP:
		    line = -1;
		    break;
		case Ctrl('B'):
		case KEY_PGUP:
		    if(pageno > 1) {
			if(lino < 2)
			    pageno -= 2;
			else
			    pageno--;
			lino = line = 0;
		    } else if(pageno && lino > 1)
			pageno = line = 0;
		    break;
		case Ctrl('H'):
		    if(pageno > 1) {
			if(lino < 2)
			    pageno -= 2;
			else
			    pageno--;
			lino = line = 0;
		    } else if(pageno && lino > 1)
			pageno = line = 0;
		    else {
			close(fd);
			return 1;
		    }
		}
	    }
	    
	    if(line > 0) {
		move(b_lines, 0);
		clrtoeol();
		refresh();
	    } else if(line < 0) {                      /* Line scroll up */
		if(pageno <= 1) {
		    if(lino == 1 || !pageno) {
			close(fd);
			return 1;
		    }
		    if(header && lino <= 5) {
			more_goto(fd, viewed = pagebreak[scrollup = lino =
						    pageno = 0] = 0);
			clear();
		    }
		}
		if(pageno && lino > 1 + local) {
		    line =  (lino - 2) - local;
		    if(pageno > 1 && viewed == fsize)
			line += local;
		    scrollup = lino - 1;
		    more_goto(fd, viewed = pagebreak[pageno - 1]);
		    while(line--)
			viewed += more_readln(fd, (unsigned char *)buf);
		} else if(pageno > 1) {
		    scrollup = b_lines - 1;
		    line = (b_lines - 2) - local;
		    more_goto(fd, viewed = pagebreak[--pageno - 1]);
		    while(line--)
			viewed += more_readln(fd, (unsigned char *)buf);
		}
		line = pos = 0;
	    } else {
		pos = 0;
		more_goto (fd, viewed = pagebreak[pageno]);
		move(0,0);
		clear();
	    }
	}
    }

    close(fd);
    if(promptend) {
	pressanykey();
	clear();
    } else
	outs(reset_color);
    return 0;
}

static int more_web(char *fpath, int promptend) {
    char *ch, *ch1 = NULL;
    char *hostname = fpath,userfile[MAXPATHLEN],file[MAXPATHLEN]="/";
    char genbuf[200];
    time_t dtime;
#if !defined(USE_LYNX) && defined(USE_PROXY)
    int a;
    FILE *fp;
    struct hostent *h;
    struct sockaddr_in sin;
#endif

    if((ch = strstr(fpath, "mailto:"))) {
        if(!HAS_PERM(PERM_LOGINOK)) {
	    move(b_lines - 1,0);
	    outs("\033[41m �z���v�������L�k�ϥ�internet mail... \033[m");
	    refresh();
	    return 0;
	}
        if(!invalidaddr(&ch[7]) &&
	   getdata(b_lines - 1, 0, "[�H�H]�D�D�G", genbuf, 40, DOECHO))
	    do_send(&ch[7], genbuf);
	else {
	    move(b_lines - 1,0);
	    outs("\033[41m ���H�Hemail �� ���D ���~... \033[m");
	    refresh();
	}
        return 0;
    }
    if((ch = strstr(fpath, "gopher://"))) {
	item_t item;

	strcpy(item.X.G.server, &ch[9]);
	strcpy(item.X.G.path, "1/");
	item.X.G.port = 70;
	gem(fpath , &item, 0);
        return 0;
    }
    if((ch = strstr(fpath, "http://")))
	hostname=&ch[7];
    if((ch = strchr(hostname, '/'))) {
        *ch = 0;
        if(&ch1[1])
	    strcat(file,&ch[1]);
    }
    if(file[strlen(file) - 1] == '/')
	strcat(file,"index.html");
    move(b_lines-1,0);
    clrtoeol();
#ifdef USE_PROXY
    sprintf(genbuf, "\033[33;44m ���b�s��%s.(proxy:%s).....�еy��....\033[m",
	    hostname, PROXYSERVER);
#else
    sprintf(genbuf, "\033[33;44m ���b�s��%s......�еy��....\033[m", hostname);
#endif
    outs(genbuf);
    refresh();

#ifdef LOCAL_PROXY
/* ���� local disk �� proxy */
    time(&dtime);
    sprintf(userfile,"hproxy/%s%s",hostname,file);
    if(dashf(userfile) && (dtime - dasht(userfile)) <  HPROXYDAY * 24 * 60
       && more(userfile,promptend)) {
        return 1;
    }
    ch=userfile - 1;
    while((ch1 = strchr(ch + 1,'/'))) {
        *ch1 = 0;
        if(!dashd(ch))
	    mkdir(ch+1,0755);
        chdir(ch+1);
        *ch1 = '/';
        ch = ch1;
    }
    chdir(BBSHOME);
#endif

#ifndef USE_LYNX
#ifdef USE_PROXY
    if(!(h = gethostbyname(PROXYSERVER))) {
	outs("\033[33;44m �䤣��o��proxy server!..\033[m");
	refresh();
	return;
    }
    ()memset((char *)&sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;

    if(h == NULL)
	sin.sin_addr.s_addr = inet_addr(PROXYSERVER);
    else
	()memcpy(&sin.sin_addr.s_addr, h->h_addr, h->h_length);

    sin.sin_port = htons((ushort)PROXYPORT);  /* HTTP port */
    a = socket(AF_INET, SOCK_STREAM, 0);
    if((connect(a, (struct sockaddr *) & sin, sizeof sin)) < 0) {
	outs("\033[1;44m �s����proxy����ڵ� ! \033[m");
	refresh();
	return;
    }
    sprintf(genbuf,"GET http://%s/%s HTTP/1.1\n",hostname,file);
#else
    if(!(h = gethostbyname(hostname))) {
	outs("\033[33;44m �䤣��o��server!..\033[m");
	refresh();
	return;
    }
    ()memset((char *) &sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    
    if(h == NULL)
	sin.sin_addr.s_addr = inet_addr(hostname);
    else
	()memcpy(&sin.sin_addr.s_addr, h->h_addr, h->h_length);
    
    sin.sin_port =  htons((ushort)80);  
    a = socket(AF_INET, SOCK_STREAM, 0);
    if((connect(a, (struct sockaddr *) & sin, sizeof sin)) < 0) {
	outs("\033[1;44m �s������ڵ� ! \033[m");
	refresh();
	return;
    }
    sprintf(genbuf, "GET %s\n", file);
#endif

    for(i = strlen(file); file[i - 1] != '/' && i > 0 ; i--);
    file[i] = 0;

    i = strlen(genbuf);
    write(a, genbuf, i);

#define BLANK   001
#define ISPRINT 002
#define PRE     004
#define CENTER  010
    if((fp = fopen(userfile,"w"))) {
	int flag = 2, c;
	char path[MAXPATHLEN];
	unsigned char j, k;

	while((i = read(a,genbuf,200))) {
	    if(i < 0)
		return;
	    genbuf[i]=0;
	    
	    for(j = 0, k = 0; genbuf[j] && j < i; j++) {
		if((flag & ISPRINT) && genbuf[j] == '<')
		    flag |= BLANK;
		else if((flag & ISPRINT) && genbuf[j] == '>')
		    flag &= ~BLANK;
		else {
		    if(!(flag & BLANK)) {
			if(j != k && (genbuf[j] != '\n' || flag & PRE))
			    genbuf[k++] = genbuf[j];
		    } else {
			switch(char_lower(genbuf[j])) {
			case 'a':
			    break;
			case 'b':
			    if(genbuf[j + 1] == 'r' && genbuf[j + 2] == '>') 
				genbuf[k++] = '\n';
			    break;
			case 'h':
			    if(genbuf[j + 1] == 'r' && 
			       (genbuf[j + 2] == '>' ||
				genbuf[j + 2] == 's')) {
				strncpy(&genbuf[k], "\n--\n", 4);
				k += 4;
			    }
			    break;
			case 'l':
			    if(genbuf[j + 1] == 'i' && genbuf[j + 2]=='>') {
				strncpy(&genbuf[k], "\n�� ", 4);
				k += 4;
			    }
			    break;
			case 'p':
			    if(genbuf[j + 1]=='>') {
				genbuf[k++] = '\n';
				genbuf[k++] = '\n';
			    } else if(genbuf[j + 1] == 'r' &&
				      genbuf[j + 2] == 'e')
				flag ^= PRE;
			    break;
			case 't':
			    if(genbuf[j + 1] == 'd' && genbuf[j + 2]=='>') {
				strncpy(&genbuf[k], "\n-\n", 3);
				k += 3;
			    }
			    break;
			}
		    }
		    if((genbuf[j] & 0x80) && (flag & ISPRINT))
			flag &= ~ISPRINT;
		    else
			flag |= ISPRINT;
                }
	    }
	    genbuf[k]=0;
	    fputs(genbuf, fp);
	}
	fclose(fp);
	close(a);
	return more(userfile, promptend);
    }
    return 0;
#else  /* use lynx dump */
    sprintf(genbuf, "lynx -dump http://%s%s > %s", hostname, file, userfile);
    system(genbuf);
    return more(userfile, promptend);
#endif
}