[w3m-dev 03721] PATH_INFO support of local CGI
* local.c (CGIFN_DROOT): deleted (CGIFN_LIBDIR): added (CGIFN_MODE): deleted (CGIFN_CONTAIN_SLASH): deleted (check_local_cgi): rewrite (cgi_filename): rewrite (localcgi_post): support PATH_INFO * url.c (openURL): rewrite * Bonus/smb.cgi: use PATH_INFO From: Hironori SAKAMOTO <hsaka@mth.biglobe.ne.jp>
This commit is contained in:
+22
-6
@@ -3,9 +3,12 @@
|
|||||||
# Workgroup list: file:/$LIB/smb.cgi
|
# Workgroup list: file:/$LIB/smb.cgi
|
||||||
# Server list: file:/$LIB/smb.cgi?workgroup
|
# Server list: file:/$LIB/smb.cgi?workgroup
|
||||||
# Sahre list: file:/$LIB/smb.cgi?//server
|
# Sahre list: file:/$LIB/smb.cgi?//server
|
||||||
|
# file:/$LIB/smb.cgi/server
|
||||||
# Directory: file:/$LIB/smb.cgi?//server/share
|
# Directory: file:/$LIB/smb.cgi?//server/share
|
||||||
# file:/$LIB/smb.cgi?//server/share/dir...
|
# file:/$LIB/smb.cgi?//server/share/dir...
|
||||||
|
# file:/$LIB/smb.cgi/server/share
|
||||||
# Get file: file:/$LIB/smb.cgi?//server/share/dir.../file
|
# Get file: file:/$LIB/smb.cgi?//server/share/dir.../file
|
||||||
|
# file:/$LIB/smb.cgi/server/share/dir.../file
|
||||||
#
|
#
|
||||||
# ----- ~/.w3m/smb -----
|
# ----- ~/.w3m/smb -----
|
||||||
# workgroup = <workgroup>
|
# workgroup = <workgroup>
|
||||||
@@ -64,9 +67,22 @@ $FILE = "F000";
|
|||||||
|
|
||||||
$CGI = "file://" . &file_encode($ENV{"SCRIPT_NAME"} || $0);
|
$CGI = "file://" . &file_encode($ENV{"SCRIPT_NAME"} || $0);
|
||||||
$QUERY = $ENV{"QUERY_STRING"};
|
$QUERY = $ENV{"QUERY_STRING"};
|
||||||
|
$PATH_INFO = $ENV{"PATH_INFO"};
|
||||||
|
|
||||||
$_ = &file_decode($QUERY);
|
if ($PATH_INFO =~ m@^/@) {
|
||||||
$DEBUG && print "DEBUG: QUERY_STRING=\"$_\"\n";
|
$_ = $PATH_INFO;
|
||||||
|
if (! m@^//@) {
|
||||||
|
$_ = "/$_";
|
||||||
|
}
|
||||||
|
s@[\r\n\0\\"]@@g;
|
||||||
|
$DEBUG && print "DEBUG: PATH_INFO=\"$_\"\n";
|
||||||
|
$Q = "";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$_ = &file_decode($QUERY);
|
||||||
|
$DEBUG && print "DEBUG: QUERY_STRING=\"$_\"\n";
|
||||||
|
$Q = "?";
|
||||||
|
}
|
||||||
if (s@^//([^/]+)@@) {
|
if (s@^//([^/]+)@@) {
|
||||||
$server = $1;
|
$server = $1;
|
||||||
# if (!$USE_OPT_A && !defined($PASSWD)) {
|
# if (!$USE_OPT_A && !defined($PASSWD)) {
|
||||||
@@ -138,7 +154,7 @@ $DEBUG && print "DEBUG: $_";
|
|||||||
$c = $&;
|
$c = $&;
|
||||||
s/^ //;
|
s/^ //;
|
||||||
$_ eq "." && next;
|
$_ eq "." && next;
|
||||||
print "<a href=\"$CGI?$service"
|
print "<a href=\"$CGI$Q$service"
|
||||||
. &cleanup("$file/" . &file_encode($_)) . "\">"
|
. &cleanup("$file/" . &file_encode($_)) . "\">"
|
||||||
. &html_quote($_) . "</a>"
|
. &html_quote($_) . "</a>"
|
||||||
. &html_quote($c) . "\n";
|
. &html_quote($c) . "\n";
|
||||||
@@ -183,7 +199,7 @@ sub share_list {
|
|||||||
for (sort @share) {
|
for (sort @share) {
|
||||||
($_, $d, @c) = split(" ");
|
($_, $d, @c) = split(" ");
|
||||||
if ($d eq 'Disk') {
|
if ($d eq 'Disk') {
|
||||||
print "<tr><td>+ <a href=\"$CGI?//$server/"
|
print "<tr><td>+ <a href=\"$CGI$Q//$server/"
|
||||||
. &file_encode($_) . "\">"
|
. &file_encode($_) . "\">"
|
||||||
. &html_quote($_) . "</a>";
|
. &html_quote($_) . "</a>";
|
||||||
} else {
|
} else {
|
||||||
@@ -213,7 +229,7 @@ sub server_list {
|
|||||||
print "<tr><td colspan=3><b>$group</b>\n";
|
print "<tr><td colspan=3><b>$group</b>\n";
|
||||||
for (sort @server) {
|
for (sort @server) {
|
||||||
($_, @c) = split(" ");
|
($_, @c) = split(" ");
|
||||||
print "<tr><td>+ <a href=\"$CGI?//"
|
print "<tr><td>+ <a href=\"$CGI$Q//"
|
||||||
. &file_encode($_) . "\">"
|
. &file_encode($_) . "\">"
|
||||||
. &html_quote($_) . "</a><td><td>"
|
. &html_quote($_) . "</a><td><td>"
|
||||||
. &html_quote("@c") . "\n";
|
. &html_quote("@c") . "\n";
|
||||||
@@ -335,7 +351,7 @@ sub print_form {
|
|||||||
Content-Type: text/html
|
Content-Type: text/html
|
||||||
|
|
||||||
<h1>$q</h1>
|
<h1>$q</h1>
|
||||||
<form action="$CGI?$_" method=POST>
|
<form action="$CGI$Q$_" method=POST>
|
||||||
<table>
|
<table>
|
||||||
<tr><td>Workgroup <td>User <td>Password
|
<tr><td>Workgroup <td>User <td>Password
|
||||||
<tr><td><input type=text size=8 name=group value="$WORKGROUP">
|
<tr><td><input type=text size=8 name=group value="$WORKGROUP">
|
||||||
|
|||||||
@@ -1,3 +1,16 @@
|
|||||||
|
2003-02-01 Hironori SAKAMOTO <hsaka@mth.biglobe.ne.jp>
|
||||||
|
|
||||||
|
* [w3m-dev 03721] PATH_INFO support of local CGI
|
||||||
|
* local.c (CGIFN_DROOT): deleted
|
||||||
|
(CGIFN_LIBDIR): added
|
||||||
|
(CGIFN_MODE): deleted
|
||||||
|
(CGIFN_CONTAIN_SLASH): deleted
|
||||||
|
(check_local_cgi): rewrite
|
||||||
|
(cgi_filename): rewrite
|
||||||
|
(localcgi_post): support PATH_INFO
|
||||||
|
* url.c (openURL): rewrite
|
||||||
|
* Bonus/smb.cgi: use PATH_INFO
|
||||||
|
|
||||||
2003-02-01 Hironori SAKAMOTO <hsaka@mth.biglobe.ne.jp>
|
2003-02-01 Hironori SAKAMOTO <hsaka@mth.biglobe.ne.jp>
|
||||||
|
|
||||||
* [w3m-dev 03720] mark remains
|
* [w3m-dev 03720] mark remains
|
||||||
@@ -6995,4 +7008,4 @@ a * [w3m-dev 03276] compile error on EWS4800
|
|||||||
* release-0-2-1
|
* release-0-2-1
|
||||||
* import w3m-0.2.1
|
* import w3m-0.2.1
|
||||||
|
|
||||||
$Id: ChangeLog,v 1.733 2003/01/31 16:14:22 ukai Exp $
|
$Id: ChangeLog,v 1.734 2003/01/31 16:25:02 ukai Exp $
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* $Id: local.c,v 1.25 2003/01/22 16:10:28 ukai Exp $ */
|
/* $Id: local.c,v 1.26 2003/01/31 16:25:09 ukai Exp $ */
|
||||||
#include "fm.h"
|
#include "fm.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -17,11 +17,8 @@
|
|||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
|
|
||||||
#define CGIFN_NORMAL 0
|
#define CGIFN_NORMAL 0
|
||||||
#define CGIFN_DROOT 1
|
#define CGIFN_LIBDIR 1
|
||||||
#define CGIFN_CGIBIN 2
|
#define CGIFN_CGIBIN 2
|
||||||
#define CGIFN_MODE(x) ((x)&3)
|
|
||||||
|
|
||||||
#define CGIFN_CONTAIN_SLASH 4
|
|
||||||
|
|
||||||
static char *Local_cookie_file = NULL;
|
static char *Local_cookie_file = NULL;
|
||||||
|
|
||||||
@@ -183,45 +180,16 @@ check_local_cgi(char *file, int status)
|
|||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
if (status & CGIFN_CONTAIN_SLASH) {
|
if (status != CGIFN_LIBDIR && status != CGIFN_CGIBIN)
|
||||||
/* local CGI file must be just under /cgi-bin/
|
|
||||||
* or /$LIB/
|
|
||||||
*/
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
#ifdef __EMX__
|
|
||||||
if (CGIFN_MODE(status) != CGIFN_CGIBIN) {
|
|
||||||
char tmp[_MAX_PATH];
|
|
||||||
int len;
|
|
||||||
|
|
||||||
_abspath(tmp, w3m_lib_dir(), _MAX_PATH); /* Translate '\\' to '/' */
|
|
||||||
len = strlen(tmp);
|
|
||||||
while (len > 1 && tmp[len - 1] == '/')
|
|
||||||
len--;
|
|
||||||
if (strnicmp(file, tmp, len) || /* and ignore case */
|
|
||||||
(file[len] != '/'))
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#else /* not __EMX__ */
|
|
||||||
if (CGIFN_MODE(status) != CGIFN_CGIBIN) {
|
|
||||||
char *tmp = Strnew_charp(w3m_lib_dir())->ptr;
|
|
||||||
int len = strlen(tmp);
|
|
||||||
|
|
||||||
while (len > 1 && tmp[len - 1] == '/')
|
|
||||||
len--;
|
|
||||||
if (strncmp(file, tmp, len) || (file[len] != '/'))
|
|
||||||
/*
|
|
||||||
* a local-CGI script should be located on either
|
|
||||||
* /cgi-bin/ directory or LIB_DIR (typically /usr/local/lib/w3m).
|
|
||||||
*/
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif /* not __EMX__ */
|
|
||||||
if (stat(file, &st) < 0)
|
if (stat(file, &st) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if ((st.st_uid == geteuid() && (st.st_mode & S_IXUSR)) || (st.st_gid == getegid() && (st.st_mode & S_IXGRP)) || (st.st_mode & S_IXOTH)) { /* executable */
|
if (S_ISDIR(st.st_mode))
|
||||||
|
return -1;
|
||||||
|
if ((st.st_uid == geteuid() && (st.st_mode & S_IXUSR)) ||
|
||||||
|
(st.st_gid == getegid() && (st.st_mode & S_IXGRP)) ||
|
||||||
|
(st.st_mode & S_IXOTH)) /* executable */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,43 +284,60 @@ checkPath(char *fn, char *path)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static int
|
||||||
cgi_filename(char *fn, int *status)
|
cgi_filename(char *uri, char **fn, char **name, char **path_info)
|
||||||
{
|
{
|
||||||
Str tmp;
|
Str tmp;
|
||||||
struct stat st;
|
int offset;
|
||||||
if (cgi_bin != NULL && strncmp(fn, "/cgi-bin/", 9) == 0) {
|
|
||||||
*status = CGIFN_CGIBIN;
|
*fn = uri;
|
||||||
if (strchr(fn + 9, '/'))
|
*name = uri;
|
||||||
*status |= CGIFN_CONTAIN_SLASH;
|
*path_info = NULL;
|
||||||
tmp = checkPath(fn + 9, cgi_bin);
|
|
||||||
|
if (cgi_bin != NULL && strncmp(uri, "/cgi-bin/", 9) == 0) {
|
||||||
|
offset = 9;
|
||||||
|
if ((*path_info = strchr(uri + offset, '/')))
|
||||||
|
*name = allocStr(uri, *path_info - uri);
|
||||||
|
tmp = checkPath(*name + offset, cgi_bin);
|
||||||
if (tmp == NULL)
|
if (tmp == NULL)
|
||||||
return fn;
|
return CGIFN_NORMAL;
|
||||||
return tmp->ptr;
|
*fn = tmp->ptr;
|
||||||
|
return CGIFN_CGIBIN;
|
||||||
}
|
}
|
||||||
if (strncmp(fn, "/$LIB/", 6) == 0) {
|
|
||||||
*status = CGIFN_NORMAL;
|
#ifdef __EMX__
|
||||||
tmp = Strnew_charp(w3m_lib_dir());
|
{
|
||||||
fn += 5;
|
char lib[_MAX_PATH];
|
||||||
if (strchr(fn + 1, '/'))
|
_abspath(lib, w3m_lib_dir(), _MAX_PATH); /* Translate '\\' to '/' */
|
||||||
*status |= CGIFN_CONTAIN_SLASH;
|
tmp = Strnew_charp(lib);
|
||||||
if (Strlastchar(tmp) == '/')
|
|
||||||
fn++;
|
|
||||||
Strcat_charp(tmp, fn);
|
|
||||||
return tmp->ptr;
|
|
||||||
}
|
}
|
||||||
if (*fn == '/' && document_root != NULL && stat(fn, &st) < 0) {
|
#else
|
||||||
*status = CGIFN_DROOT;
|
tmp = Strnew_charp(w3m_lib_dir());
|
||||||
if (strchr(fn + 1, '/'))
|
#endif
|
||||||
*status |= CGIFN_CONTAIN_SLASH;
|
if (Strlastchar(tmp) != '/')
|
||||||
tmp = Strnew_charp(document_root);
|
Strcat_char(tmp, '/');
|
||||||
if (Strlastchar(tmp) != '/')
|
if (strncmp(uri, "/$LIB/", 6) == 0)
|
||||||
Strcat_char(tmp, '/');
|
offset = 6;
|
||||||
Strcat_charp(tmp, fn);
|
else if (strncmp(uri, tmp->ptr, tmp->length) == 0)
|
||||||
return tmp->ptr;
|
offset = tmp->length;
|
||||||
|
else if (*uri == '/' && document_root != NULL) {
|
||||||
|
Str tmp2 = Strnew_charp(document_root);
|
||||||
|
if (Strlastchar(tmp2) != '/')
|
||||||
|
Strcat_char(tmp2, '/');
|
||||||
|
Strcat_charp(tmp2, uri + 1);
|
||||||
|
if (strncmp(tmp2->ptr, tmp->ptr, tmp->length) != 0)
|
||||||
|
return CGIFN_NORMAL;
|
||||||
|
uri = tmp2->ptr;
|
||||||
|
*name = uri;
|
||||||
|
offset = tmp->length;
|
||||||
}
|
}
|
||||||
*status = CGIFN_NORMAL;
|
else
|
||||||
return fn;
|
return CGIFN_NORMAL;
|
||||||
|
if ((*path_info = strchr(uri + offset, '/')))
|
||||||
|
*name = allocStr(uri, *path_info - uri);
|
||||||
|
Strcat_charp(tmp, *name + offset);
|
||||||
|
*fn = tmp->ptr;
|
||||||
|
return CGIFN_LIBDIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *
|
FILE *
|
||||||
@@ -361,9 +346,9 @@ localcgi_post(char *uri, char *qstr, FormList *request, char *referer)
|
|||||||
FILE *fr = NULL, *fw = NULL;
|
FILE *fr = NULL, *fw = NULL;
|
||||||
int status;
|
int status;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
char *file;
|
char *file = uri, *name = uri, *path_info = NULL;
|
||||||
|
|
||||||
file = cgi_filename(uri, &status);
|
status = cgi_filename(uri, &file, &name, &path_info);
|
||||||
if (check_local_cgi(file, status) < 0)
|
if (check_local_cgi(file, status) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
writeLocalCookie();
|
writeLocalCookie();
|
||||||
@@ -382,10 +367,11 @@ localcgi_post(char *uri, char *qstr, FormList *request, char *referer)
|
|||||||
}
|
}
|
||||||
setup_child(TRUE, 2, -1);
|
setup_child(TRUE, 2, -1);
|
||||||
|
|
||||||
if (qstr == NULL)
|
if (qstr)
|
||||||
set_cgi_environ(uri, file, uri);
|
uri = Strnew_m_charp(uri, "?", qstr, NULL)->ptr;
|
||||||
else
|
set_cgi_environ(name, file, uri);
|
||||||
set_cgi_environ(uri, file, Strnew_m_charp(uri, "?", qstr, NULL)->ptr);
|
if (path_info)
|
||||||
|
set_environ("PATH_INFO", path_info);
|
||||||
if (referer && referer != NO_REFERER)
|
if (referer && referer != NO_REFERER)
|
||||||
set_environ("HTTP_REFERER", referer);
|
set_environ("HTTP_REFERER", referer);
|
||||||
if (request) {
|
if (request) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* $Id: url.c,v 1.71 2003/01/29 17:33:28 ukai Exp $ */
|
/* $Id: url.c,v 1.72 2003/01/31 16:25:10 ukai Exp $ */
|
||||||
#include "fm.h"
|
#include "fm.h"
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
@@ -1463,14 +1463,13 @@ openURL(char *url, ParsedURL *pu, ParsedURL *current,
|
|||||||
URLFile *ouf, HRequest *hr, unsigned char *status)
|
URLFile *ouf, HRequest *hr, unsigned char *status)
|
||||||
{
|
{
|
||||||
Str tmp;
|
Str tmp;
|
||||||
int i, sock, scheme;
|
int sock, scheme;
|
||||||
char *p, *q, *u;
|
char *p, *q, *u;
|
||||||
URLFile uf;
|
URLFile uf;
|
||||||
HRequest hr0;
|
HRequest hr0;
|
||||||
#ifdef USE_SSL
|
#ifdef USE_SSL
|
||||||
SSL *sslh = NULL;
|
SSL *sslh = NULL;
|
||||||
#endif /* USE_SSL */
|
#endif /* USE_SSL */
|
||||||
int extlen = strlen(CGI_EXTENSION);
|
|
||||||
|
|
||||||
if (hr == NULL)
|
if (hr == NULL)
|
||||||
hr = &hr0;
|
hr = &hr0;
|
||||||
@@ -1521,49 +1520,22 @@ openURL(char *url, ParsedURL *pu, ParsedURL *current,
|
|||||||
switch (pu->scheme) {
|
switch (pu->scheme) {
|
||||||
case SCM_LOCAL:
|
case SCM_LOCAL:
|
||||||
case SCM_LOCAL_CGI:
|
case SCM_LOCAL_CGI:
|
||||||
if (request && request->body) {
|
if (request && request->body)
|
||||||
/* local CGI: POST */
|
/* local CGI: POST */
|
||||||
if ((q = strchr(pu->file, '?')) != NULL) {
|
uf.stream = newFileStream(localcgi_post(pu->real_file, pu->query,
|
||||||
p = Strnew_charp_n(pu->file, (int)(q - pu->file))->ptr;
|
request, option->referer),
|
||||||
pu->real_file = cleanupName(file_unquote(p));
|
|
||||||
q++;
|
|
||||||
}
|
|
||||||
uf.stream = newFileStream(localcgi_post(pu->real_file,
|
|
||||||
pu->query,
|
|
||||||
request,
|
|
||||||
option->referer),
|
|
||||||
(void (*)())pclose);
|
(void (*)())pclose);
|
||||||
if (uf.stream == NULL)
|
else
|
||||||
goto ordinary_local_file;
|
|
||||||
uf.is_cgi = TRUE;
|
|
||||||
uf.scheme = pu->scheme = SCM_LOCAL_CGI;
|
|
||||||
}
|
|
||||||
else if (pu->query != NULL) {
|
|
||||||
/* lodal CGI: GET */
|
/* lodal CGI: GET */
|
||||||
uf.stream = newFileStream(localcgi_get(pu->real_file, pu->query,
|
uf.stream = newFileStream(localcgi_get(pu->real_file, pu->query,
|
||||||
option->referer),
|
option->referer),
|
||||||
(void (*)())pclose);
|
(void (*)())pclose);
|
||||||
if (uf.stream == NULL) {
|
if (uf.stream) {
|
||||||
goto ordinary_local_file;
|
|
||||||
}
|
|
||||||
uf.is_cgi = TRUE;
|
uf.is_cgi = TRUE;
|
||||||
uf.scheme = pu->scheme = SCM_LOCAL_CGI;
|
uf.scheme = pu->scheme = SCM_LOCAL_CGI;
|
||||||
|
return uf;
|
||||||
}
|
}
|
||||||
else if ((i = strlen(pu->file)) > extlen &&
|
examineFile(pu->real_file, &uf);
|
||||||
!strncmp(pu->file + i - extlen, CGI_EXTENSION, extlen)) {
|
|
||||||
/* lodal CGI: GET */
|
|
||||||
uf.stream = newFileStream(localcgi_get(pu->real_file, NULL,
|
|
||||||
option->referer),
|
|
||||||
(void (*)())pclose);
|
|
||||||
if (uf.stream == NULL)
|
|
||||||
goto ordinary_local_file;
|
|
||||||
uf.is_cgi = TRUE;
|
|
||||||
uf.scheme = pu->scheme = SCM_LOCAL_CGI;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ordinary_local_file:
|
|
||||||
examineFile(pu->real_file, &uf);
|
|
||||||
}
|
|
||||||
if (uf.stream == NULL) {
|
if (uf.stream == NULL) {
|
||||||
if (dir_exist(pu->real_file)) {
|
if (dir_exist(pu->real_file)) {
|
||||||
add_index_file(pu, &uf);
|
add_index_file(pu, &uf);
|
||||||
|
|||||||
Reference in New Issue
Block a user