Support the siteconf feature
Patch to support the siteconf feature, from [w3m-dev 04463] on 2012-06-27, provided by AIDA Shinra.
This commit is contained in:
222
rc.c
222
rc.c
@@ -9,7 +9,9 @@
|
||||
#include <errno.h>
|
||||
#include "parsetag.h"
|
||||
#include "local.h"
|
||||
#include "regex.h"
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
|
||||
struct param_ptr {
|
||||
char *name;
|
||||
@@ -146,6 +148,7 @@ static int OptionEncode = FALSE;
|
||||
#define CMT_DISABLE_SECRET_SECURITY_CHECK N_("Disable secret file security check")
|
||||
#define CMT_PASSWDFILE N_("Password file")
|
||||
#define CMT_PRE_FORM_FILE N_("File for setting form on loading")
|
||||
#define CMT_SITECONF_FILE N_("File for preferences for each site")
|
||||
#define CMT_FTPPASS N_("Password for anonymous FTP (your mail address)")
|
||||
#define CMT_FTPPASS_HOSTNAMEGEN N_("Generate domain part of password for FTP")
|
||||
#define CMT_USERAGENT N_("User-Agent identification string")
|
||||
@@ -619,6 +622,8 @@ struct param_ptr params9[] = {
|
||||
CMT_FTPPASS_HOSTNAMEGEN, NULL},
|
||||
{"pre_form_file", P_STRING, PI_TEXT, (void *)&pre_form_file,
|
||||
CMT_PRE_FORM_FILE, NULL},
|
||||
{"siteconf_file", P_STRING, PI_TEXT, (void *)&siteconf_file,
|
||||
CMT_SITECONF_FILE, NULL},
|
||||
{"user_agent", P_STRING, PI_TEXT, (void *)&UserAgent, CMT_USERAGENT, NULL},
|
||||
{"no_referer", P_INT, PI_ONOFF, (void *)&NoSendReferer, CMT_NOSENDREFERER,
|
||||
NULL},
|
||||
@@ -1173,6 +1178,8 @@ do_mkdir(const char *dir, long mode)
|
||||
#endif /* not __MINW32_VERSION */
|
||||
#endif /* not __EMX__ */
|
||||
|
||||
static void loadSiteconf(void);
|
||||
|
||||
void
|
||||
sync_with_option(void)
|
||||
{
|
||||
@@ -1199,6 +1206,7 @@ sync_with_option(void)
|
||||
#endif
|
||||
loadPasswd();
|
||||
loadPreForm();
|
||||
loadSiteconf();
|
||||
|
||||
if (AcceptLang == NULL || *AcceptLang == '\0') {
|
||||
/* TRANSLATORS:
|
||||
@@ -1556,3 +1564,217 @@ helpFile(char *base)
|
||||
return expandPath(Strnew_m_charp(w3m_help_dir(), "/", base, NULL)->ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* siteconf */
|
||||
/*
|
||||
* url "<url>"|/<re-url>/|m@<re-url>@i [exact]
|
||||
* substitute_url "<destination-url>"
|
||||
* url_charset <charset>
|
||||
* no_referer_from on|off
|
||||
* no_referer_to on|off
|
||||
*
|
||||
* The last match wins.
|
||||
*/
|
||||
|
||||
struct siteconf_rec {
|
||||
struct siteconf_rec *next;
|
||||
char *url;
|
||||
Regex *re_url;
|
||||
int url_exact;
|
||||
unsigned char mask[(SCONF_N_FIELD + 7) >> 3];
|
||||
|
||||
char *substitute_url;
|
||||
#ifdef USE_M17N
|
||||
wc_ces url_charset;
|
||||
#endif
|
||||
int no_referer_from;
|
||||
int no_referer_to;
|
||||
};
|
||||
#define SCONF_TEST(ent, f) ((ent)->mask[(f)>>3] & (1U<<((f)&7)))
|
||||
#define SCONF_SET(ent, f) ((ent)->mask[(f)>>3] |= (1U<<((f)&7)))
|
||||
#define SCONF_CLEAR(ent, f) ((ent)->mask[(f)>>3] &= ~(1U<<((f)&7)))
|
||||
|
||||
static struct siteconf_rec *siteconf_head = NULL;
|
||||
static struct siteconf_rec *newSiteconfRec(void);
|
||||
|
||||
static struct siteconf_rec *
|
||||
newSiteconfRec(void)
|
||||
{
|
||||
struct siteconf_rec *ent;
|
||||
|
||||
ent = New(struct siteconf_rec);
|
||||
ent->next = NULL;
|
||||
ent->url = NULL;
|
||||
ent->re_url = NULL;
|
||||
ent->url_exact = FALSE;
|
||||
memset(ent->mask, 0, sizeof(ent->mask));
|
||||
|
||||
ent->substitute_url = NULL;
|
||||
#ifdef USE_M17N
|
||||
ent->url_charset = 0;
|
||||
#endif
|
||||
return ent;
|
||||
}
|
||||
|
||||
static void
|
||||
loadSiteconf(void)
|
||||
{
|
||||
char *efname;
|
||||
FILE *fp;
|
||||
Str line;
|
||||
struct siteconf_rec *ent = NULL;
|
||||
|
||||
siteconf_head = NULL;
|
||||
if (!siteconf_file)
|
||||
return;
|
||||
if ((efname = expandPath(siteconf_file)) == NULL)
|
||||
return;
|
||||
fp = fopen(efname, "r");
|
||||
if (fp == NULL)
|
||||
return;
|
||||
while (line = Strfgets(fp), line->length > 0) {
|
||||
char *p, *s;
|
||||
|
||||
Strchop(line);
|
||||
p = line->ptr;
|
||||
SKIP_BLANKS(p);
|
||||
if (*p == '#' || *p == '\0')
|
||||
continue;
|
||||
s = getWord(&p);
|
||||
|
||||
/* The "url" begins a new record. */
|
||||
if (strcmp(s, "url") == 0) {
|
||||
char *url, *opt;
|
||||
struct siteconf_rec *newent;
|
||||
|
||||
/* First, register the current record. */
|
||||
if (ent) {
|
||||
ent->next = siteconf_head;
|
||||
siteconf_head = ent;
|
||||
ent = NULL;
|
||||
}
|
||||
|
||||
/* Second, create a new record. */
|
||||
newent = newSiteconfRec();
|
||||
url = getRegexWord((const char **)&p, &newent->re_url);
|
||||
opt = getWord(&p);
|
||||
SKIP_BLANKS(p);
|
||||
if (!newent->re_url) {
|
||||
ParsedURL pu;
|
||||
if (!url || !*url)
|
||||
continue;
|
||||
parseURL2(url, &pu, NULL);
|
||||
newent->url = parsedURL2Str(&pu)->ptr;
|
||||
}
|
||||
/* If we have an extra or unknown option, ignore this record
|
||||
* for future extensions. */
|
||||
if (strcmp(opt, "exact") == 0) {
|
||||
newent->url_exact = TRUE;
|
||||
}
|
||||
else if (*opt != 0)
|
||||
continue;
|
||||
if (*p)
|
||||
continue;
|
||||
ent = newent;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If the current record is broken, skip to the next "url". */
|
||||
if (!ent)
|
||||
continue;
|
||||
|
||||
/* Fill the new record. */
|
||||
if (strcmp(s, "substitute_url") == 0) {
|
||||
ent->substitute_url = getQWord(&p);
|
||||
SCONF_SET(ent, SCONF_SUBSTITUTE_URL);
|
||||
}
|
||||
#ifdef USE_M17N
|
||||
else if (strcmp(s, "url_charset") == 0) {
|
||||
char *charset = getWord(&p);
|
||||
ent->url_charset = (charset && *charset) ?
|
||||
wc_charset_to_ces(charset) : 0;
|
||||
SCONF_SET(ent, SCONF_URL_CHARSET);
|
||||
}
|
||||
#endif /* USE_M17N */
|
||||
else if (strcmp(s, "no_referer_from") == 0) {
|
||||
ent->no_referer_from = str_to_bool(getWord(&p), 0);
|
||||
SCONF_SET(ent, SCONF_NO_REFERER_FROM);
|
||||
}
|
||||
else if (strcmp(s, "no_referer_to") == 0) {
|
||||
ent->no_referer_to = str_to_bool(getWord(&p), 0);
|
||||
SCONF_SET(ent, SCONF_NO_REFERER_TO);
|
||||
}
|
||||
}
|
||||
if (ent) {
|
||||
ent->next = siteconf_head;
|
||||
siteconf_head = ent;
|
||||
ent = NULL;
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
const void *
|
||||
querySiteconf(const ParsedURL *query_pu, int field)
|
||||
{
|
||||
const struct siteconf_rec *ent;
|
||||
Str u;
|
||||
char *firstp, *lastp;
|
||||
|
||||
if (field < 0 || field >= SCONF_N_FIELD)
|
||||
return NULL;
|
||||
if (!query_pu || IS_EMPTY_PARSED_URL(query_pu))
|
||||
return NULL;
|
||||
u = parsedURL2Str((ParsedURL *)query_pu);
|
||||
if (u->length == 0)
|
||||
return NULL;
|
||||
|
||||
for (ent = siteconf_head; ent; ent = ent->next) {
|
||||
if (!SCONF_TEST(ent, field))
|
||||
continue;
|
||||
if (ent->re_url) {
|
||||
if (RegexMatch(ent->re_url, u->ptr, u->length, 1)) {
|
||||
MatchedPosition(ent->re_url, &firstp, &lastp);
|
||||
if (!ent->url_exact)
|
||||
goto url_found;
|
||||
if (firstp != u->ptr || lastp == firstp)
|
||||
continue;
|
||||
if (*lastp == 0 || *lastp == '?' || *(lastp - 1) == '?' ||
|
||||
*lastp == '#' || *(lastp - 1) == '#')
|
||||
goto url_found;
|
||||
}
|
||||
} else {
|
||||
int matchlen = strmatchlen(ent->url, u->ptr, u->length);
|
||||
if (matchlen == 0 || ent->url[matchlen] != 0)
|
||||
continue;
|
||||
firstp = u->ptr;
|
||||
lastp = u->ptr + matchlen;
|
||||
if (*lastp == 0 || *lastp == '?' || *(lastp - 1) == '?' ||
|
||||
*lastp == '#' || *(lastp - 1) == '#')
|
||||
goto url_found;
|
||||
if (!ent->url_exact && (*lastp == '/' || *(lastp - 1) == '/'))
|
||||
goto url_found;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
||||
url_found:
|
||||
switch (field) {
|
||||
case SCONF_SUBSTITUTE_URL:
|
||||
if (ent->substitute_url && *ent->substitute_url) {
|
||||
Str tmp = Strnew_charp_n(u->ptr, firstp - u->ptr);
|
||||
Strcat_charp(tmp, ent->substitute_url);
|
||||
Strcat_charp(tmp, lastp);
|
||||
return tmp->ptr;
|
||||
}
|
||||
return NULL;
|
||||
#ifdef USE_M17N
|
||||
case SCONF_URL_CHARSET:
|
||||
return &ent->url_charset;
|
||||
#endif
|
||||
case SCONF_NO_REFERER_FROM:
|
||||
return &ent->no_referer_from;
|
||||
case SCONF_NO_REFERER_TO:
|
||||
return &ent->no_referer_to;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
Reference in New Issue
Block a user