aboutsummaryrefslogtreecommitdiffstats
path: root/backend.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--backend.c403
1 files changed, 403 insertions, 0 deletions
diff --git a/backend.c b/backend.c
new file mode 100644
index 0000000..101e67e
--- /dev/null
+++ b/backend.c
@@ -0,0 +1,403 @@
+/* $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;
+}