Logo Search packages:      
Sourcecode: xawtv version File versions  Download package

page.c

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <wchar.h>
#include <wctype.h>
#include <iconv.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <libzvbi.h>

#include "httpd.h"
#include "vbi-data.h"

/* ---------------------------------------------------------------------- */

static char stylesheet[] =
#include "alevt.css.h"
;

static char page_about[] =
#include "about.html.h"
;

static wchar_t page_top[] = L""
#include "top.html.h"
;

static wchar_t page_bottom[] = L""
#include "bottom.html.h"
;

#if 0
/*                          01234567890123456789012345678901 */
static char graphic1[32] = " '-.:::.;;;.}/}./#";
/*                          012345 6789 0123 456789012345678901 */
static char graphic2[32] = ".:::.\\{{.\\||.\\#_:::.[.||].###";
#endif

enum mime_type {
    TYPE_TEXT = 1,
    TYPE_HTML = 2,
};

#define CHARSET "utf-8"
#define TXTBUF  (25*41*8)
#define HTMLBUF (25*1024)

/* ---------------------------------------------------------------------- */

static int vbi_export_html(wchar_t *dest, int size,
                     struct vbi_state *vbi, struct vbi_page *pg,
                     int pagenr, int subnr)
{
    int x,y,i,link;
    int fg,bg,len=0;
    vbi_char *ch;
    wchar_t wch,*obuf;
    struct vbi_page dummy;

    obuf = dest;
    link = -1;
    len  = swprintf(obuf,size,page_top,pagenr,subnr);
    obuf += len; size -= len;
    for (y = 0; y < 25; y++) {
      ch = pg->text + 41*y;
      fg = -1;
      bg = -1;
      for (x = 0; x <= 40; x++) {
          /* close link tags */
          if (link >= 0) {
            if (0 == link) {
                len = swprintf(obuf,size,L"</a>");
                obuf += len; size -= len;
            }
            link--;
          }
          
          /* this char */
          wch = ch[x].unicode;
          if (ch[x].size > VBI_DOUBLE_SIZE)
            wch = ' ';
          if (ch[x].conceal)
            wch = ' ';

          /* handle colors */
          if (fg != ch[x].foreground || bg != ch[x].background) {
            if (-1 != fg) {
                len = swprintf(obuf,size,L"</span>");
                obuf += len; size -= len;
            }
            fg  = ch[x].foreground;
            bg  = ch[x].background;
            len = swprintf(obuf,size,L"<span class=\"c%02d\">",
                         fg * 10 + bg);
            obuf += len;
            size -= len;
          }

          /* check for references to other pages */
          if (y > 0 && -1 == link && x > 0 && x < 39 &&
            iswdigit(ch[x+0].unicode)  &&
            iswdigit(ch[x+1].unicode)  &&
            iswdigit(ch[x+2].unicode)  &&
            !iswdigit(ch[x-1].unicode) &&
            !iswdigit(ch[x+3].unicode)) {
            len = swprintf(obuf,size,L"<a href=\"/%lc%lc%lc/00.html\">",
                         (wchar_t)ch[x+0].unicode,
                         (wchar_t)ch[x+1].unicode,
                         (wchar_t)ch[x+2].unicode);
            obuf += len; size -= len;
            link = 2;
          }
          if (y > 0 && -1 == link && x > 0 && x < 40 &&
            '>' == ch[x+0].unicode &&
            '>' == ch[x+1].unicode) {
            len = swprintf(obuf,size,L"<a href=\"/%03x/00.html\">",
                         vbi_calc_page(pagenr, +0x01));
            link = 1;
          }
          if (y > 0 && -1 == link && x > 0 && x < 40 &&
            '<' == ch[x+0].unicode &&
            '<' == ch[x+1].unicode) {
            len = swprintf(obuf,size,L"<a href=\"/%03x/00.html\">",
                         vbi_calc_page(pagenr, -0x01));
            link = 1;
          }

          /* check for references to other subpages */
          if (subnr > 0 && y > 0 && -1 == link && x > 0 && x < 39 &&
            iswdigit(ch[x+0].unicode)  &&
            '/' == ch[x+1].unicode     &&
            iswdigit(ch[x+2].unicode)  &&
            !iswdigit(ch[x-1].unicode) &&
            !iswdigit(ch[x+3].unicode)) {
            if (ch[x+0].unicode == ch[x+2].unicode) {
                len = swprintf(obuf,size,L"<a href=\"01.html\">");
            } else {
                len = swprintf(obuf,size,L"<a href=\"%02x.html\">",
                           ch[x+0].unicode-'0' +1);
            }
            len = swprintf(obuf,size,L"<a href=\"/%lc%lc%lc/00.html\">",
                         (wchar_t)ch[x+0].unicode,
                         (wchar_t)ch[x+1].unicode,
                         (wchar_t)ch[x+2].unicode);
            obuf += len; size -= len;
            link = 2;
          }

#if 0
          /* check for references to WWW pages */
          if (html && y > 0 && -1 == link && x < W-9 &&
            (((tolower(L[x+0].ch) == 'w') &&
              (tolower(L[x+1].ch) == 'w') &&
              (tolower(L[x+2].ch) == 'w') &&
              (L[x+3].ch == '.')) ||
             ((tolower(L[x+0].ch) == 'h') &&
              (tolower(L[x+1].ch) == 't') &&
              (tolower(L[x+2].ch) == 't') &&
              (tolower(L[x+3].ch) == 'p')))) {
            int offs = 0;
            
            len += sprintf(out+len,"<a href=\"");
            if(tolower(L[x].ch == 'w'))
                len += sprintf(out+len,"http://");
            while ((L[x+offs].ch!=' ') && (x+offs < W)) {
                len += sprintf(out+len,"%c",tolower(L[x+offs].ch));
                offs++;
            }
            while ( (*(out+len-1)<'a') || (*(out+len-1)>'z') ) {
                len--;
                offs--;
            }
            len += sprintf(out+len,"\">");
            link = offs - 1;
          }
#endif
          /* FIXME: fasttext links */
          
          if (size > 0) {
            *obuf = wch;
            obuf++;
            size--;
          }
      }
      if (-1 != fg) {
          len   = swprintf(obuf,size,L"</span>");
          obuf += len;
          size -= len;
      }
      if (size > 0) {
          *obuf = '\n';
          obuf++;
          size--;
      }
    }
    len = swprintf(obuf,size,L"</pre>\n<div class=quick>\n");
    obuf += len; size -= len;

    if (0 != subnr) {
      /* link all subpages */
      for (i = 1; i <= VBI_MAX_SUBPAGES; i++) {
          if (!vbi_fetch_vt_page(vbi->dec,&dummy,pagenr,i,
                           VBI_WST_LEVEL_1p5,0,0))
            continue;
          if (i != subnr) {
            len = swprintf(obuf,size,L" <a href=\"/%03x/%02x.html\">%02x</a>",
                         pagenr, i, i);
          } else {
            len = swprintf(obuf,size,L" %02x", i);
          }
          obuf += len; size -= len;
          len = swprintf(obuf,size,L"<br>\n");
          obuf += len; size -= len;
      }
    }
    /* page navigation links */
    len = swprintf(obuf,size,L"<a href=\"/%03x/00.html\">&lt;&lt;</a> &nbsp;",
               vbi_calc_page(pagenr, -0x10));
    obuf += len; size -= len;
    len = swprintf(obuf,size,L"<a href=\"/%03x/00.html\">&lt;</a> &nbsp;",
               vbi_calc_page(pagenr, -0x01));
    obuf += len; size -= len;
    len = swprintf(obuf,size,L"<a href=\"/%03x/%02x.html\">o</a> &nbsp;",
               pagenr, subnr);
    obuf += len; size -= len;
    len = swprintf(obuf,size,L"<a href=\"/%03x/00.html\">&gt;</a> &nbsp;",
               vbi_calc_page(pagenr, +0x01));
    obuf += len; size -= len;
    len = swprintf(obuf,size,L"<a href=\"/%03x/00.html\">&gt;&gt;</a>",
               vbi_calc_page(pagenr, +0x10));
    obuf += len; size -= len;
    len = swprintf(obuf,size,L"<br>\n") ;
    obuf += len; size -= len;
    len = swprintf(obuf,size,page_bottom);
    obuf += len; size -= len;
    *obuf = 0;
    return obuf - dest;
}

static int wchar_to_charset(wchar_t *istr, int ilen, char *charset,
                       char **ostr, int *olen)
{
    size_t   il,ol;
    wchar_t  *err;
    char     *ib,*ob;
    iconv_t  ic;
    int      rc;

    ic = iconv_open(CHARSET,"WCHAR_T");
    if (NULL == ic) {
      if (debug)
          fprintf(stderr,"iconf_open failed on %s => %s\n",
                CHARSET,"WCHAR_T");
      return -1;
    }
    ib  = (char*)istr;
    il  = ilen * sizeof(wchar_t);
    ob  = malloc(ilen * 8);
    ol  = ilen * 8;
    *ostr = ob;

    for (;;) {
      rc = iconv(ic,&ib,&il,&ob,&ol);
      if (rc >= 0) {
          /* done */
          break;
      }
      /* handle errors */
      err = (wchar_t*)ib;
      if (EILSEQ == errno && *err != '?') {
          *err = '?';
          continue;
      }
      /* unknown error */
      if (debug)
          fprintf(stderr,"unknown iconv error\n");
      return -1;
    }
    iconv_close(ic);
    *olen = ob - *ostr;
    return 0;
}

static int vbi_render_page(struct REQUEST *req,
                     struct vbi_state *vbi, struct vbi_page *pg,
                     int pagenr, int subnr, enum mime_type type)
{
    wchar_t  *wpage;
    int      wlen;

    switch (type) {
    case TYPE_TEXT:
      req->body  = malloc(TXTBUF);
      req->lbody = vbi_export_txt(req->body, CHARSET, TXTBUF, pg,
                            &vbi_fullrect, 0);
      req->mime  = "text/plain; charset=" CHARSET;
      break;
    case TYPE_HTML:
      wpage = malloc(HTMLBUF*sizeof(wchar_t));
      wlen  = vbi_export_html(wpage,HTMLBUF,vbi,pg,pagenr,subnr);
      if (-1 == wchar_to_charset(wpage,wlen,CHARSET,&req->body,&req->lbody))
          return -1;
      free(wpage);
      req->mime  = "text/html; charset=" CHARSET;
      break;
    }

    req->free_the_mallocs = 1;
    mkheader(req,200,-1);
    return 0;
}

/* ---------------------------------------------------------------------- */

void buildpage(struct REQUEST *req)
{
    int pagenr, subpage;
    char type[10];
    struct vbi_page page;
    enum mime_type t;

    /* style sheet */
    if (0 == strcmp(req->path,"/alevt.css")) {
      req->mime  = "text/css; charset=us-ascii";
      req->body  = stylesheet;
      req->lbody = sizeof(stylesheet);
      mkheader(req,200,start);
      return;
    }

    /* about */
    if (0 == strcmp(req->path,"/about.html")) {
      req->mime  = "text/html; charset=utf-8";
      req->body  = page_about;
      req->lbody = sizeof(page_about);
      mkheader(req,200,start);
      return;
    }

    /* entry page */
    if (0 == strcmp(req->path,"/")) {
      strcpy(req->path,"/100/00.html");
      mkredirect(req);
      return;
    }

    /* pages */
    if (3 == sscanf(req->path,"/%3x/%2x.%8s",&pagenr,&subpage,type)) {
      t = 0;
      if (0 == strcmp(type,"html"))
          t = TYPE_HTML;
      if (0 == strcmp(type,"txt"))
          t = TYPE_TEXT;
      if (0 == t) {
          mkerror(req,404,1);
          return;
      }
      if (debug)
          fprintf(stderr,"%03d: lookup %03x/%02x [%s]\n",
                req->fd,pagenr,subpage,type);
      memset(&page,0,sizeof(page));
      if (!vbi_fetch_vt_page(vbi->dec,&page,pagenr,subpage,
                         VBI_WST_LEVEL_1p5,25,1)) {
          if (!vbi_fetch_vt_page(vbi->dec,&page,pagenr,VBI_ANY_SUBNO,
                           VBI_WST_LEVEL_1p5,25,1)) {
            mkerror(req,404,1);
            return;
          }
          sprintf(req->path,"/%03x/%02x.html",pagenr,page.subno);
          mkredirect(req);
          return;
      }
      if (-1 == vbi_render_page(req,vbi,&page,pagenr,subpage,t))
          mkerror(req,500,1);
      return;
    }

    /* goto form */
    if (1 == sscanf(req->path,"/goto/?p=%d",&pagenr)) {
      sprintf(req->path,"/%d/00.html",pagenr);
      mkredirect(req);
      return;
    }
    
    mkerror(req,404,1);
    return;
}

Generated by  Doxygen 1.6.0   Back to index