[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:
Fumitoshi UKAI
2003-01-31 16:25:02 +00:00
parent 1ecacc5ad1
commit 92fc697f22
4 changed files with 108 additions and 121 deletions
+22 -6
View File
@@ -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">
+14 -1
View File
@@ -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 $
+63 -77
View File
@@ -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) {
+9 -37
View File
@@ -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);