1 /* $Id: local.c,v 1.35 2007/05/23 15:06:05 inu Exp $ */
12 #endif /* HAVE_READLINK */
14 #include <limits.h> /* _MAX_PATH ? */
19 #ifdef __MINGW32_VERSION
23 #define CGIFN_NORMAL 0
24 #define CGIFN_LIBDIR 1
25 #define CGIFN_CGIBIN 2
27 static Str Local_cookie = NULL;
28 static char *Local_cookie_file = NULL;
37 if (Local_cookie_file)
39 Local_cookie_file = tmpfname(TMPF_COOKIE, NULL)->ptr;
40 set_environ("LOCAL_COOKIE_FILE", Local_cookie_file);
41 f = fopen(Local_cookie_file, "wb");
45 fwrite(Local_cookie->ptr, sizeof(char), Local_cookie->length, f);
47 chmod(Local_cookie_file, S_IRUSR | S_IWUSR);
50 /* setup cookie for local CGI */
58 gethostname(hostname, 256);
59 srand48((long)New(char) + (long)time(NULL));
60 Local_cookie = Sprintf("%ld@%s", lrand48(), hostname);
65 loadLocalDir(char *dname)
78 #endif /* HAVE_READLINK */
79 #endif /* HAVE_LSTAT */
80 int i, l, nrow = 0, n = 0, maxlen = 0;
81 int nfile, nfile_max = 100;
87 dirname = Strnew_charp(dname);
88 if (Strlastchar(dirname) != '/')
89 Strcat_char(dirname, '/');
90 qdir = html_quote(Str_conv_from_system(dirname)->ptr);
91 /* FIXME: gettextize? */
92 tmp = Strnew_m_charp("<HTML>\n<HEAD>\n<BASE HREF=\"file://",
93 html_quote(file_quote(dirname->ptr)),
94 "\">\n<TITLE>Directory list of ", qdir,
95 "</TITLE>\n</HEAD>\n<BODY>\n<H1>Directory list of ",
96 qdir, "</H1>\n", NULL);
97 flist = New_N(char *, nfile_max);
99 while ((dir = readdir(d)) != NULL) {
100 flist[nfile++] = allocStr(dir->d_name, -1);
101 if (nfile == nfile_max) {
103 flist = New_Reuse(char *, flist, nfile_max);
106 l = strlen(dir->d_name);
114 l = COLS / (maxlen + 2);
117 nrow = (n + l - 1) / l;
119 Strcat_charp(tmp, "<TABLE CELLPADDING=0>\n<TR VALIGN=TOP>\n");
121 qsort((void *)flist, nfile, sizeof(char *), strCmp);
122 for (i = 0; i < nfile; i++) {
124 if (strcmp(p, ".") == 0)
126 Strcopy(fbuf, dirname);
127 if (Strlastchar(fbuf) != '/')
128 Strcat_char(fbuf, '/');
129 Strcat_charp(fbuf, p);
131 if (lstat(fbuf->ptr, &lst) < 0)
133 #endif /* HAVE_LSTAT */
134 if (stat(fbuf->ptr, &st) < 0)
138 Strcat_charp(tmp, "<TD><NOBR>");
142 if (S_ISLNK(lst.st_mode))
143 Strcat_charp(tmp, "[LINK] ");
145 #endif /* HAVE_LSTAT */
146 if (S_ISDIR(st.st_mode))
147 Strcat_charp(tmp, "[DIR] ");
149 Strcat_charp(tmp, "[FILE] ");
151 Strcat_m_charp(tmp, "<A HREF=\"", html_quote(file_quote(p)), NULL);
152 if (S_ISDIR(st.st_mode))
153 Strcat_char(tmp, '/');
154 Strcat_m_charp(tmp, "\">", html_quote(conv_from_system(p)), NULL);
155 if (S_ISDIR(st.st_mode))
156 Strcat_char(tmp, '/');
157 Strcat_charp(tmp, "</A>");
160 Strcat_charp(tmp, "</NOBR></TD>\n");
164 Strcat_charp(tmp, "<BR>\n");
168 #if defined(HAVE_LSTAT) && defined(HAVE_READLINK)
169 if (S_ISLNK(lst.st_mode)) {
170 if ((l = readlink(fbuf->ptr, lbuf, sizeof(lbuf))) > 0) {
172 Strcat_m_charp(tmp, " -> ",
173 html_quote(conv_from_system(lbuf)), NULL);
174 if (S_ISDIR(st.st_mode))
175 Strcat_char(tmp, '/');
178 #endif /* HAVE_LSTAT && HAVE_READLINK */
179 Strcat_charp(tmp, "<br>\n");
183 Strcat_charp(tmp, "</TR>\n</TABLE>\n");
185 Strcat_charp(tmp, "</BODY>\n</HTML>\n");
191 check_local_cgi(char *file, int status)
195 if (status != CGIFN_LIBDIR && status != CGIFN_CGIBIN)
197 if (stat(file, &st) < 0)
199 if (S_ISDIR(st.st_mode))
201 #ifndef __MINGW32_VERSION
202 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 */
209 set_environ(char *var, char *value)
212 if (var != NULL && value != NULL)
213 setenv(var, value, 1);
214 #else /* not HAVE_SETENV */
216 static Hash_sv *env_hash = NULL;
217 Str tmp = Strnew_m_charp(var, "=", value, NULL);
219 if (env_hash == NULL)
220 env_hash = newHash_sv(20);
221 putHash_sv(env_hash, var, (void *)tmp->ptr);
223 #else /* not HAVE_PUTENV */
224 extern char **environ;
230 /* I have no setenv() nor putenv() */
231 /* This part is taken from terms.c of skkfep */
233 for (e = environ, i = 0; *e != NULL; e++, i++) {
234 if (strncmp(e, var, l) == 0 && (*e)[l] == '=') {
235 el = strlen(*e) - l - 1;
236 if (el >= strlen(value)) {
237 strcpy(*e + l + 1, value);
241 for (; *e != NULL; e++, i++) {
249 newenv = (char **)GC_malloc((i + 2) * sizeof(char *));
252 for (e = environ, ne = newenv; *e != NULL; *(ne++) = *(e++)) ;
256 #endif /* not HAVE_PUTENV */
257 #endif /* not HAVE_SETENV */
261 set_cgi_environ(char *name, char *fn, char *req_uri)
263 set_environ("SERVER_SOFTWARE", w3m_version);
264 set_environ("SERVER_PROTOCOL", "HTTP/1.0");
265 set_environ("SERVER_NAME", "localhost");
266 set_environ("SERVER_PORT", "80"); /* dummy */
267 set_environ("REMOTE_HOST", "localhost");
268 set_environ("REMOTE_ADDR", "127.0.0.1");
269 set_environ("GATEWAY_INTERFACE", "CGI/1.1");
271 set_environ("SCRIPT_NAME", name);
272 set_environ("SCRIPT_FILENAME", fn);
273 set_environ("REQUEST_URI", req_uri);
277 checkPath(char *fn, char *path)
283 p = strchr(path, ':');
284 tmp = Strnew_charp(expandPath(p ? allocStr(path, p - path) : path));
285 if (Strlastchar(tmp) != '/')
286 Strcat_char(tmp, '/');
287 Strcat_charp(tmp, fn);
288 if (stat(tmp->ptr, &st) == 0)
300 cgi_filename(char *uri, char **fn, char **name, char **path_info)
309 if (cgi_bin != NULL && strncmp(uri, "/cgi-bin/", 9) == 0) {
311 if ((*path_info = strchr(uri + offset, '/')))
312 *name = allocStr(uri, *path_info - uri);
313 tmp = checkPath(*name + offset, cgi_bin);
323 _abspath(lib, w3m_lib_dir(), _MAX_PATH); /* Translate '\\' to '/' */
324 tmp = Strnew_charp(lib);
327 tmp = Strnew_charp(w3m_lib_dir());
329 if (Strlastchar(tmp) != '/')
330 Strcat_char(tmp, '/');
331 if (strncmp(uri, "/$LIB/", 6) == 0)
333 else if (strncmp(uri, tmp->ptr, tmp->length) == 0)
334 offset = tmp->length;
335 else if (*uri == '/' && document_root != NULL) {
336 Str tmp2 = Strnew_charp(document_root);
337 if (Strlastchar(tmp2) != '/')
338 Strcat_char(tmp2, '/');
339 Strcat_charp(tmp2, uri + 1);
340 if (strncmp(tmp2->ptr, tmp->ptr, tmp->length) != 0)
344 offset = tmp->length;
348 if ((*path_info = strchr(uri + offset, '/')))
349 *name = allocStr(uri, *path_info - uri);
350 Strcat_charp(tmp, *name + offset);
356 localcgi_post(char *uri, char *qstr, FormList *request, char *referer)
358 FILE *fr = NULL, *fw = NULL;
361 char *file = uri, *name = uri, *path_info = NULL, *tmpf = NULL;
363 #ifdef __MINGW32_VERSION
366 status = cgi_filename(uri, &file, &name, &path_info);
367 if (check_local_cgi(file, status) < 0)
370 if (request && request->enctype != FORM_ENCTYPE_MULTIPART) {
371 tmpf = tmpfname(TMPF_DFL, NULL)->ptr;
372 fw = fopen(tmpf, "w");
376 pid = open_pipe_rw(&fr, NULL);
384 setup_child(TRUE, 2, fw ? fileno(fw) : -1);
387 uri = Strnew_m_charp(uri, "?", qstr, NULL)->ptr;
388 set_cgi_environ(name, file, uri);
390 set_environ("PATH_INFO", path_info);
391 if (referer && referer != NO_REFERER)
392 set_environ("HTTP_REFERER", referer);
394 set_environ("REQUEST_METHOD", "POST");
396 set_environ("QUERY_STRING", qstr);
397 set_environ("CONTENT_LENGTH", Sprintf("%d", request->length)->ptr);
398 if (request->enctype == FORM_ENCTYPE_MULTIPART) {
399 set_environ("CONTENT_TYPE",
400 Sprintf("multipart/form-data; boundary=%s",
401 request->boundary)->ptr);
402 freopen(request->body, "r", stdin);
405 set_environ("CONTENT_TYPE", "application/x-www-form-urlencoded");
406 fwrite(request->body, sizeof(char), request->length, fw);
408 freopen(tmpf, "r", stdin);
412 set_environ("REQUEST_METHOD", "GET");
413 set_environ("QUERY_STRING", qstr ? qstr : "");
414 freopen(DEV_NULL_PATH, "r", stdin);
417 #ifdef HAVE_CHDIR /* ifndef __EMX__ ? */
418 chdir(mydirname(file));
420 execl(file, mybasename(file), NULL);
421 fprintf(stderr, "execl(\"%s\", \"%s\", NULL): %s\n",
422 file, mybasename(file), strerror(errno));