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

backend.c

/* $Id: backend.c,v 1.13 2003/09/22 21:02:16 ukai Exp $ */
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include "fm.h"
#include <gc.h>
#include "terms.h"


/* Prototype declaration of internal functions */
#ifdef HAVE_READLINE
#include <readline/readline.h>
#else                   /* ! HAVE_READLINE */
static char *readline(char *);
#endif                        /* ! HAVE_READLINE */
static TextList *split(char *);


/* Prototype declaration of command functions */
static void get(TextList *);
static void post(TextList *);
static void set(TextList *);
static void show(TextList *);
static void quit(TextList *);
static void help(TextList *);


/* *INDENT-OFF* */
/* Table of command functions */
struct {
    const char *name;
    const char *option_string;
    const char *help;
    void (*func)(TextList*);
} command_table[] = {
    {"get", "[-download_only] URL", "Retrieve URL.", get},
    {"post", "[-download_only] [-target TARGET] [-charset CHARSET]"
     " [-enctype ENCTYPE] [-body BODY] [-boundary BOUNDARY] [-length LEN] URL",
     "Retrieve URL.", post},
    {"set", "VARIABLE VALUE", "Set VALUE to VARIABLE.", set},
    {"show", "VARIABLE", "Show value of VARIABLE.", show},
    {"quit", "", "Quit program.", quit},
    {"help", "", "Display help messages.", help},
    {NULL, NULL, NULL, NULL},
};
/* *INDENT-ON* */

/* Prototype declaration of functions to manipulate configuration variables */
static void set_column(TextList *);
static void show_column(TextList *);


/* *INDENT-OFF* */
/* Table of configuration variables */
struct {
    const char *name;
    void (*set_func)(TextList*);
    void (*show_func)(TextList*);
} variable_table[] = {
    {"column", set_column, show_column},
    {NULL, NULL, NULL},
};
/* *INDENT-ON* */

static void
print_headers(Buffer *buf, int len)
{
    TextListItem *tp;

    if (buf->document_header) {
      for (tp = buf->document_header->first; tp; tp = tp->next)
          printf("%s\n", tp->ptr);
    }
    printf("w3m-current-url: %s\n", parsedURL2Str(&buf->currentURL)->ptr);
    if (buf->baseURL)
      printf("w3m-base-url: %s\n", parsedURL2Str(buf->baseURL)->ptr);
    printf("w3m-content-type: %s\n", buf->type);
#ifdef USE_M17N
    if (buf->document_charset)
      printf("w3m-content-charset: %s\n",
             wc_ces_to_charset(buf->document_charset));
#endif
    if (len > 0)
      printf("w3m-content-length: %d\n", len);
}


static void
internal_get(char *url, int flag, FormList *request)
{
    Buffer *buf;

    backend_halfdump_buf = NULL;
    do_download = flag;
    buf = loadGeneralFile(url, NULL, NO_REFERER, 0, request);
    do_download = FALSE;
    if (buf != NULL && buf != NO_BUFFER) {
      if (!strcasecmp(buf->type, "text/html") && backend_halfdump_buf) {
          TextLineListItem *p;
          Str first, last;
          int len = 0;
          for (p = backend_halfdump_buf->first; p; p = p->next) {
            p->ptr->line = Str_conv_to_halfdump(p->ptr->line);
            len += p->ptr->line->length + 1;
          }
          first = Strnew_charp("<pre>\n");
          last = Strnew_m_charp("</pre><title>", html_quote(buf->buffername),
                          "</title>\n", NULL);
          print_headers(buf, len + first->length + last->length);
          printf("\n");
          printf("%s", first->ptr);
          for (p = backend_halfdump_buf->first; p; p = p->next)
            printf("%s\n", p->ptr->line->ptr);
          printf("%s", last->ptr);
      }
      else {
          if (!strcasecmp(buf->type, "text/plain")) {
            Line *lp;
            int len = 0;
            for (lp = buf->firstLine; lp; lp = lp->next) {
                len += lp->len;
                if (lp->lineBuf[lp->len - 1] != '\n')
                  len++;
            }
            print_headers(buf, len);
            printf("\n");
            saveBuffer(buf, stdout, TRUE);
          }
          else {
            print_headers(buf, 0);
          }
      }
    }
}


/* Command: get */
static void
get(TextList *argv)
{
    char *p, *url = NULL;
    int flag = FALSE;

    while ((p = popText(argv))) {
      if (!strcasecmp(p, "-download_only"))
          flag = TRUE;
      else
          url = p;
    }
    if (url) {
      internal_get(url, flag, NULL);
    }
}


/* Command: post */
static void
post(TextList *argv)
{
    FormList *request;
    char *p, *target = NULL, *charset = NULL,
      *enctype = NULL, *body = NULL, *boundary = NULL, *url = NULL;
    int flag = FALSE, length = 0;

    while ((p = popText(argv))) {
      if (!strcasecmp(p, "-download_only"))
          flag = TRUE;
      else if (!strcasecmp(p, "-target"))
          target = popText(argv);
      else if (!strcasecmp(p, "-charset"))
          charset = popText(argv);
      else if (!strcasecmp(p, "-enctype"))
          enctype = popText(argv);
      else if (!strcasecmp(p, "-body"))
          body = popText(argv);
      else if (!strcasecmp(p, "-boundary"))
          boundary = popText(argv);
      else if (!strcasecmp(p, "-length"))
          length = atol(popText(argv));
      else
          url = p;
    }
    if (url) {
      request =
          newFormList(NULL, "post", charset, enctype, target, NULL, NULL);
      request->body = body;
      request->boundary = boundary;
      request->length = (length > 0) ? length : (body ? strlen(body) : 0);
      internal_get(url, flag, request);
    }
}


/* Command: set */
static void
set(TextList *argv)
{
    if (argv->nitem > 1) {
      int i;
      for (i = 0; variable_table[i].name; i++) {
          if (!strcasecmp(variable_table[i].name, argv->first->ptr)) {
            popText(argv);
            if (variable_table[i].set_func)
                variable_table[i].set_func(argv);
            break;
          }
      }
    }
}


/* Command: show */
static void
show(TextList *argv)
{
    if (argv->nitem >= 1) {
      int i;
      for (i = 0; variable_table[i].name; i++) {
          if (!strcasecmp(variable_table[i].name, argv->first->ptr)) {
            popText(argv);
            if (variable_table[i].show_func)
                variable_table[i].show_func(argv);
            break;
          }
      }
    }
}


/* Command: quit */
static void
quit(TextList *argv)
{
#ifdef USE_COOKIE
    save_cookies();
#endif                        /* USE_COOKIE */
    w3m_exit(0);
}


/* Command: help */
static void
help(TextList *argv)
{
    int i;
    for (i = 0; command_table[i].name; i++)
      printf("%s %s\n    %s\n",
             command_table[i].name,
             command_table[i].option_string, command_table[i].help);
}


/* Sub command: set COLS */
static void
set_column(TextList *argv)
{
    if (argv->nitem == 1) {
      COLS = atol(argv->first->ptr);
    }
}

/* Sub command: show COLS */
static void
show_column(TextList *argv)
{
    fprintf(stdout, "column=%d\n", COLS);
}


/* Call appropriate command function based on given string */
static void
call_command_function(char *str)
{
    int i;
    TextList *argv = split(str);
    if (argv->nitem > 0) {
      for (i = 0; command_table[i].name; i++) {
          if (!strcasecmp(command_table[i].name, argv->first->ptr)) {
            popText(argv);
            if (command_table[i].func)
                command_table[i].func(argv);
            break;
          }
      }
    }
}


/* Main function */
int
backend(void)
{
    char *str;

    w3m_dump = 0;
    if (COLS == 0)
      COLS = 80;
#ifdef USE_MOUSE
    use_mouse = FALSE;
#endif                        /* USE_MOUSE */

    if (backend_batch_commands) {
      while ((str = popText(backend_batch_commands)))
          call_command_function(str);
    }
    else {
      while ((str = readline("w3m> ")))
          call_command_function(str);
    }
    quit(NULL);
    return 0;
}


/* Dummy function of readline(). */
#ifndef HAVE_READLINE
static char *
readline(char *prompt)
{
    Str s;
    fputs(prompt, stdout);
    fflush(stdout);
    s = Strfgets(stdin);
    if (feof(stdin) && (strlen(s->ptr) == 0))
      return NULL;
    else
      return s->ptr;
}
#endif                        /* ! HAVE_READLINE */


/* Splits a string into a list of tokens and returns that list. */
static TextList *
split(char *p)
{
    int in_double_quote = FALSE, in_single_quote = FALSE;
    Str s = Strnew();
    TextList *tp = newTextList();

    for (; *p; p++) {
      switch (*p) {
      case '"':
          if (in_single_quote)
            Strcat_char(s, '"');
          else
            in_double_quote = !in_double_quote;
          break;
      case '\'':
          if (in_double_quote)
            Strcat_char(s, '\'');
          else
            in_single_quote = !in_single_quote;
          break;
      case '\\':
          if (!in_single_quote) {
            /* Process escape characters. */
            p++;
            switch (*p) {
            case 't':
                Strcat_char(s, '\t');
                break;
            case 'r':
                Strcat_char(s, '\r');
                break;
            case 'f':
                Strcat_char(s, '\f');
                break;
            case 'n':
                Strcat_char(s, '\n');
                break;
            case '\0':
                goto LAST;
            default:
                Strcat_char(s, *p);
            }
          }
          else {
            Strcat_char(s, *p);
          }
          break;
      case ' ':
      case '\t':
      case '\r':
      case '\f':
      case '\n':
          /* Separators are detected. */
          if (in_double_quote || in_single_quote) {
            Strcat_char(s, *p);
          }
          else if (s->length > 0) {
            pushText(tp, s->ptr);
            s = Strnew();
          }
          break;
      default:
          Strcat_char(s, *p);
      }
    }
  LAST:
    if (s->length > 0)
      pushText(tp, s->ptr);
    return tp;
}

Generated by  Doxygen 1.6.0   Back to index