w3m

Unnamed repository; edit this file to name it for gitweb.
git clone https://logand.com/git/w3m.git/
Log | Files | Refs | README

backend.c (8584B)


      1 /* $Id$ */
      2 #include <stdio.h>
      3 #include <string.h>
      4 #include <sys/types.h>
      5 #include "fm.h"
      6 #include <gc.h>
      7 #include "terms.h"
      8 
      9 
     10 /* Prototype declaration of internal functions */
     11 #ifdef HAVE_READLINE
     12 #include <readline/readline.h>
     13 #else				/* ! HAVE_READLINE */
     14 static char *readline(char *);
     15 #endif				/* ! HAVE_READLINE */
     16 static TextList *split(char *);
     17 
     18 
     19 /* Prototype declaration of command functions */
     20 static void get(TextList *);
     21 static void post(TextList *);
     22 static void set(TextList *);
     23 static void show(TextList *);
     24 static void quit(TextList *);
     25 static void help(TextList *);
     26 
     27 
     28 /* *INDENT-OFF* */
     29 /* Table of command functions */
     30 struct {
     31     const char *name;
     32     const char *option_string;
     33     const char *help;
     34     void (*func)(TextList*);
     35 } command_table[] = {
     36     {"get", "[-download_only] URL", "Retrieve URL.", get},
     37     {"post", "[-download_only] [-target TARGET] [-charset CHARSET]"
     38      " [-enctype ENCTYPE] [-body BODY] [-boundary BOUNDARY] [-length LEN] URL",
     39      "Retrieve URL.", post},
     40     {"set", "VARIABLE VALUE", "Set VALUE to VARIABLE.", set},
     41     {"show", "VARIABLE", "Show value of VARIABLE.", show},
     42     {"quit", "", "Quit program.", quit},
     43     {"help", "", "Display help messages.", help},
     44     {NULL, NULL, NULL, NULL},
     45 };
     46 /* *INDENT-ON* */
     47 
     48 /* Prototype declaration of functions to manipulate configuration variables */
     49 static void set_column(TextList *);
     50 static void show_column(TextList *);
     51 
     52 
     53 /* *INDENT-OFF* */
     54 /* Table of configuration variables */
     55 struct {
     56     const char *name;
     57     void (*set_func)(TextList*);
     58     void (*show_func)(TextList*);
     59 } variable_table[] = {
     60     {"column", set_column, show_column},
     61     {NULL, NULL, NULL},
     62 };
     63 /* *INDENT-ON* */
     64 
     65 static void
     66 print_headers(Buffer *buf, int len)
     67 {
     68     TextListItem *tp;
     69 
     70     if (buf->document_header) {
     71 	for (tp = buf->document_header->first; tp; tp = tp->next)
     72 	    printf("%s\n", tp->ptr);
     73     }
     74     printf("w3m-current-url: %s\n", parsedURL2Str(&buf->currentURL)->ptr);
     75     if (buf->baseURL)
     76 	printf("w3m-base-url: %s\n", parsedURL2Str(buf->baseURL)->ptr);
     77     printf("w3m-content-type: %s\n", buf->type);
     78 #ifdef USE_M17N
     79     if (buf->document_charset)
     80 	printf("w3m-content-charset: %s\n",
     81 	       wc_ces_to_charset(buf->document_charset));
     82 #endif
     83     if (len > 0)
     84 	printf("w3m-content-length: %d\n", len);
     85 }
     86 
     87 
     88 static void
     89 internal_get(char *url, int flag, FormList *request)
     90 {
     91     Buffer *buf;
     92 
     93     backend_halfdump_buf = NULL;
     94     do_download = flag;
     95     buf = loadGeneralFile(url, NULL, NO_REFERER, 0, request);
     96     do_download = FALSE;
     97     if (buf != NULL && buf != NO_BUFFER) {
     98 	if (is_html_type(buf->type) && backend_halfdump_buf) {
     99 	    TextLineListItem *p;
    100 	    Str first, last;
    101 	    int len = 0;
    102 	    for (p = backend_halfdump_buf->first; p; p = p->next) {
    103 		p->ptr->line = Str_conv_to_halfdump(p->ptr->line);
    104 		len += p->ptr->line->length + 1;
    105 	    }
    106 	    first = Strnew_charp("<pre>\n");
    107 	    last = Strnew_m_charp("</pre><title>", html_quote(buf->buffername),
    108 				  "</title>\n", NULL);
    109 	    print_headers(buf, len + first->length + last->length);
    110 	    printf("\n");
    111 	    printf("%s", first->ptr);
    112 	    for (p = backend_halfdump_buf->first; p; p = p->next)
    113 		printf("%s\n", p->ptr->line->ptr);
    114 	    printf("%s", last->ptr);
    115 	}
    116 	else {
    117 	    if (!strcasecmp(buf->type, "text/plain")) {
    118 		Line *lp;
    119 		int len = 0;
    120 		for (lp = buf->firstLine; lp; lp = lp->next) {
    121 		    len += lp->len;
    122 		    if (lp->lineBuf[lp->len - 1] != '\n')
    123 			len++;
    124 		}
    125 		print_headers(buf, len);
    126 		printf("\n");
    127 		saveBuffer(buf, stdout, TRUE);
    128 	    }
    129 	    else {
    130 		print_headers(buf, 0);
    131 	    }
    132 	}
    133     }
    134 }
    135 
    136 
    137 /* Command: get */
    138 static void
    139 get(TextList *argv)
    140 {
    141     char *p, *url = NULL;
    142     int flag = FALSE;
    143 
    144     while ((p = popText(argv))) {
    145 	if (!strcasecmp(p, "-download_only"))
    146 	    flag = TRUE;
    147 	else
    148 	    url = p;
    149     }
    150     if (url) {
    151 	internal_get(url, flag, NULL);
    152     }
    153 }
    154 
    155 
    156 /* Command: post */
    157 static void
    158 post(TextList *argv)
    159 {
    160     FormList *request;
    161     char *p, *target = NULL, *charset = NULL,
    162 	*enctype = NULL, *body = NULL, *boundary = NULL, *url = NULL;
    163     int flag = FALSE, length = 0;
    164 
    165     while ((p = popText(argv))) {
    166 	if (!strcasecmp(p, "-download_only"))
    167 	    flag = TRUE;
    168 	else if (!strcasecmp(p, "-target"))
    169 	    target = popText(argv);
    170 	else if (!strcasecmp(p, "-charset"))
    171 	    charset = popText(argv);
    172 	else if (!strcasecmp(p, "-enctype"))
    173 	    enctype = popText(argv);
    174 	else if (!strcasecmp(p, "-body"))
    175 	    body = popText(argv);
    176 	else if (!strcasecmp(p, "-boundary"))
    177 	    boundary = popText(argv);
    178 	else if (!strcasecmp(p, "-length"))
    179 	    length = atol(popText(argv));
    180 	else
    181 	    url = p;
    182     }
    183     if (url) {
    184 	request =
    185 	    newFormList(NULL, "post", charset, enctype, target, NULL, NULL);
    186 	request->body = body;
    187 	request->boundary = boundary;
    188 	request->length = (length > 0) ? length : (body ? strlen(body) : 0);
    189 	internal_get(url, flag, request);
    190     }
    191 }
    192 
    193 
    194 /* Command: set */
    195 static void
    196 set(TextList *argv)
    197 {
    198     if (argv->nitem > 1) {
    199 	int i;
    200 	for (i = 0; variable_table[i].name; i++) {
    201 	    if (!strcasecmp(variable_table[i].name, argv->first->ptr)) {
    202 		popText(argv);
    203 		if (variable_table[i].set_func)
    204 		    variable_table[i].set_func(argv);
    205 		break;
    206 	    }
    207 	}
    208     }
    209 }
    210 
    211 
    212 /* Command: show */
    213 static void
    214 show(TextList *argv)
    215 {
    216     if (argv->nitem >= 1) {
    217 	int i;
    218 	for (i = 0; variable_table[i].name; i++) {
    219 	    if (!strcasecmp(variable_table[i].name, argv->first->ptr)) {
    220 		popText(argv);
    221 		if (variable_table[i].show_func)
    222 		    variable_table[i].show_func(argv);
    223 		break;
    224 	    }
    225 	}
    226     }
    227 }
    228 
    229 
    230 /* Command: quit */
    231 static void
    232 quit(TextList *argv)
    233 {
    234 #ifdef USE_COOKIE
    235     save_cookies();
    236 #endif				/* USE_COOKIE */
    237     w3m_exit(0);
    238 }
    239 
    240 
    241 /* Command: help */
    242 static void
    243 help(TextList *argv)
    244 {
    245     int i;
    246     for (i = 0; command_table[i].name; i++)
    247 	printf("%s %s\n    %s\n",
    248 	       command_table[i].name,
    249 	       command_table[i].option_string, command_table[i].help);
    250 }
    251 
    252 
    253 /* Sub command: set COLS */
    254 static void
    255 set_column(TextList *argv)
    256 {
    257     if (argv->nitem == 1) {
    258 	COLS = atol(argv->first->ptr);
    259     }
    260 }
    261 
    262 /* Sub command: show COLS */
    263 static void
    264 show_column(TextList *argv)
    265 {
    266     fprintf(stdout, "column=%d\n", COLS);
    267 }
    268 
    269 
    270 /* Call appropriate command function based on given string */
    271 static void
    272 call_command_function(char *str)
    273 {
    274     int i;
    275     TextList *argv = split(str);
    276     if (argv->nitem > 0) {
    277 	for (i = 0; command_table[i].name; i++) {
    278 	    if (!strcasecmp(command_table[i].name, argv->first->ptr)) {
    279 		popText(argv);
    280 		if (command_table[i].func)
    281 		    command_table[i].func(argv);
    282 		break;
    283 	    }
    284 	}
    285     }
    286 }
    287 
    288 
    289 /* Main function */
    290 int
    291 backend(void)
    292 {
    293     char *str;
    294 
    295     w3m_dump = 0;
    296     if (COLS == 0)
    297 	COLS = DEFAULT_COLS;
    298 #ifdef USE_MOUSE
    299     use_mouse = FALSE;
    300 #endif				/* USE_MOUSE */
    301 
    302     if (backend_batch_commands) {
    303 	while ((str = popText(backend_batch_commands)))
    304 	    call_command_function(str);
    305     }
    306     else {
    307 	while ((str = readline("w3m> ")))
    308 	    call_command_function(str);
    309     }
    310     quit(NULL);
    311     return 0;
    312 }
    313 
    314 
    315 /* Dummy function of readline(). */
    316 #ifndef HAVE_READLINE
    317 static char *
    318 readline(char *prompt)
    319 {
    320     Str s;
    321     fputs(prompt, stdout);
    322     fflush(stdout);
    323     s = Strfgets(stdin);
    324     if (feof(stdin) && (strlen(s->ptr) == 0))
    325 	return NULL;
    326     else
    327 	return s->ptr;
    328 }
    329 #endif				/* ! HAVE_READLINE */
    330 
    331 
    332 /* Splits a string into a list of tokens and returns that list. */
    333 static TextList *
    334 split(char *p)
    335 {
    336     int in_double_quote = FALSE, in_single_quote = FALSE;
    337     Str s = Strnew();
    338     TextList *tp = newTextList();
    339 
    340     for (; *p; p++) {
    341 	switch (*p) {
    342 	case '"':
    343 	    if (in_single_quote)
    344 		Strcat_char(s, '"');
    345 	    else
    346 		in_double_quote = !in_double_quote;
    347 	    break;
    348 	case '\'':
    349 	    if (in_double_quote)
    350 		Strcat_char(s, '\'');
    351 	    else
    352 		in_single_quote = !in_single_quote;
    353 	    break;
    354 	case '\\':
    355 	    if (!in_single_quote) {
    356 		/* Process escape characters. */
    357 		p++;
    358 		switch (*p) {
    359 		case 't':
    360 		    Strcat_char(s, '\t');
    361 		    break;
    362 		case 'r':
    363 		    Strcat_char(s, '\r');
    364 		    break;
    365 		case 'f':
    366 		    Strcat_char(s, '\f');
    367 		    break;
    368 		case 'n':
    369 		    Strcat_char(s, '\n');
    370 		    break;
    371 		case '\0':
    372 		    goto LAST;
    373 		default:
    374 		    Strcat_char(s, *p);
    375 		}
    376 	    }
    377 	    else {
    378 		Strcat_char(s, *p);
    379 	    }
    380 	    break;
    381 	case ' ':
    382 	case '\t':
    383 	case '\r':
    384 	case '\f':
    385 	case '\n':
    386 	    /* Separators are detected. */
    387 	    if (in_double_quote || in_single_quote) {
    388 		Strcat_char(s, *p);
    389 	    }
    390 	    else if (s->length > 0) {
    391 		pushText(tp, s->ptr);
    392 		s = Strnew();
    393 	    }
    394 	    break;
    395 	default:
    396 	    Strcat_char(s, *p);
    397 	}
    398     }
    399   LAST:
    400     if (s->length > 0)
    401 	pushText(tp, s->ptr);
    402     return tp;
    403 }