/*
- * $Id: ftp.cc,v 1.167 1997/11/12 00:08:50 wessels Exp $
+ * $Id: ftp.cc,v 1.168 1997/11/12 22:50:22 wessels Exp $
*
* DEBUG: section 9 File Transfer Protocol (FTP)
* AUTHOR: Harvest Derived
FTP_USE_BASE,
FTP_ROOT_DIR,
FTP_NO_DOTDOT,
- FTP_HTML_HEADER_SENT
+ FTP_HTML_HEADER_SENT,
+ FTP_MAYBE_TRY_SLASH_HACK
};
static const char *const crlf = "\r\n";
static char cbuf[1024];
-static char auth_msg[AUTH_MSG_SZ];
typedef enum {
BEGIN,
}
}
-#ifdef OLD_FTP_CLEANUP
-static void
-ftpCleanupUrlpath(FtpStateData * ftpState)
-{
- request_t *request = ftpState->request;
- int again;
- int l;
- char *t = NULL;
- char *s = NULL;
- do {
- again = 0;
- l = strlen(request->urlpath);
- /* check for null path */
- if (*request->urlpath == '\0') {
- xstrncpy(request->urlpath, ".", MAX_URL);
- EBIT_SET(ftpState->flags, FTP_ROOT_DIR);
- EBIT_SET(ftpState->flags, FTP_ISDIR);
- again = 1;
- } else if ((l >= 1) && (*(request->urlpath + l - 1) == '/')) {
- /* remove any trailing slashes from path */
- *(request->urlpath + l - 1) = '\0';
- EBIT_SET(ftpState->flags, FTP_ISDIR);
- EBIT_CLR(ftpState->flags, FTP_USE_BASE);
- again = 1;
- } else if ((l >= 2) && (!strcmp(request->urlpath + l - 2, "/."))) {
- /* remove trailing /. */
- *(request->urlpath + l - 2) = '\0';
- EBIT_SET(ftpState->flags, FTP_ISDIR);
- EBIT_CLR(ftpState->flags, FTP_USE_BASE);
- again = 1;
- } else if (*request->urlpath == '/') {
- /* remove any leading slashes from path */
- t = xstrdup(request->urlpath + 1);
- xstrncpy(request->urlpath, t, MAX_URL);
- xfree(t);
- again = 1;
- } else if (!strncmp(request->urlpath, "./", 2)) {
- /* remove leading ./ */
- t = xstrdup(request->urlpath + 2);
- xstrncpy(request->urlpath, t, MAX_URL);
- xfree(t);
- again = 1;
- } else if ((t = strstr(request->urlpath, "/./"))) {
- /* remove /./ */
- s = xstrdup(t + 2);
- xstrncpy(t, s, strlen(s));
- xfree(s);
- again = 1;
- } else if ((t = strstr(request->urlpath, "//"))) {
- /* remove // */
- s = xstrdup(t + 1);
- xstrncpy(t, s, strlen(s));
- xfree(s);
- again = 1;
- }
- } while (again);
-}
-#endif
-
static void
ftpBuildTitleUrl(FtpStateData * ftpState)
{
strcat(t, request->host);
if (request->port != urlDefaultPort(PROTO_FTP))
snprintf(&t[strlen(t)], len - strlen(t), ":%d", request->port);
-#ifdef OLD_FTP_CLEANUP
- strcat(t, "/");
- if (!EBIT_TEST(ftpState->flags, FTP_ROOT_DIR))
- strcat(t, request->urlpath);
-#else
strcat(t, request->urlpath);
-#endif
}
void
ftpStateFree(-1, ftpState);
return;
}
-#ifdef OLD_FTP_CLEANUP
- ftpCleanupUrlpath(ftpState);
-#else
ftpCheckUrlpath(ftpState);
-#endif
ftpBuildTitleUrl(ftpState);
debug(9, 5) ("FtpStart: host=%s, path=%s, user=%s, passwd=%s\n",
ftpState->request->host, ftpState->request->urlpath,
T = &w->next;
}
xfree(path);
- if (ftpState->pathcomps)
+ if (ftpState->pathcomps) {
+ if (*ftpState->pathcomps->key != '/')
+ EBIT_SET(ftpState->flags, FTP_MAYBE_TRY_SLASH_HACK);
ftpSendCwd(ftpState);
- else
+ } else
ftpSendPasv(ftpState);
} else {
ftpFail(ftpState);
int code = ftpState->ctrl.replycode;
size_t len = 0;
wordlist *w;
+ char *t;
debug(9, 3) ("This is ftpReadCwd\n");
w = ftpState->pathcomps;
assert(w != NULL);
ftpState->cwd_message = ftpState->ctrl.message;
ftpState->ctrl.message = NULL;
/* CWD OK */
+ EBIT_CLR(ftpState->flags, FTP_MAYBE_TRY_SLASH_HACK);
ftpState->pathcomps = w->next;
xfree(w->key);
xfree(w);
ftpSendCwd(ftpState);
+ } else if (EBIT_TEST(ftpState->flags, FTP_MAYBE_TRY_SLASH_HACK)) {
+ EBIT_CLR(ftpState->flags, FTP_MAYBE_TRY_SLASH_HACK);
+ len = strlen(w->key) + 2;
+ t = xmalloc(len);
+ snprintf(t, len, "/%s", w->key);
+ xfree(w->key);
+ w->key = t;
+ ftpSendCwd(ftpState);
} else if (EBIT_TEST(ftpState->flags, FTP_ISDIR)) {
/* CWD FAILED */
ftpFail(ftpState);
comm_close(ftpState->ctrl.fd);
}
-const char *ftpAuthText =
-"<HTML><HEAD><TITLE>Authorization needed</TITLE>\n"
-"</HEAD><BODY><H1>Authorization needed</H1>\n"
-"<P>Sorry, you have to authorize yourself to request:\n"
-"<PRE> ftp://%s@%s%256.256s</PRE>\n"
-"<P>from this cache. Please check with the\n"
-"<A HREF=\"mailto:%s\">cache administrator</A>\n"
-"if you believe this is incorrect.\n"
-"<P>\n"
-"%s\n"
-"<HR>\n"
-"<ADDRESS>\n"
-"Generated by %s/%s@%s\n"
-"</ADDRESS></BODY></HTML>\n"
-"\n";
-
static char *
ftpAuthRequired(const request_t * request, const char *realm)
{
LOCAL_ARRAY(char, content, AUTH_MSG_SZ);
+ LOCAL_ARRAY(char, buf, AUTH_MSG_SZ);
char *hdr;
int s = AUTH_MSG_SZ;
int l = 0;
/* Generate the reply body */
- l += snprintf(content + l, s - l, ftpAuthText,
+ l += snprintf(content + l, s - l,
+ "<HTML><HEAD><TITLE>Authorization needed</TITLE>\n"
+ "</HEAD><BODY><H1>Authorization needed</H1>\n"
+ "<P>Sorry, you have to authorize yourself to request:\n"
+ "<PRE> ftp://%s@%s%256.256s</PRE>\n"
+ "<P>from this cache. Please check with the\n"
+ "<A HREF=\"mailto:%s\">cache administrator</A>\n"
+ "if you believe this is incorrect.\n"
+ "<P>\n"
+ "%s\n"
+ "<HR>\n"
+ "<ADDRESS>\n"
+ "Generated by %s/%s@%s\n"
+ "</ADDRESS></BODY></HTML>\n"
+ "\n",
request->login,
request->host,
request->urlpath,
- Config.adminEmail);
- l += snprintf(content + l, s - l, "<P>\n%s\n",
- Config.errHtmlText);
- l += snprintf(content + l, s - l,
- "<HR>\n<ADDRESS>\nGenerated by %s/%s@%s\n</ADDRESS></BODY></HTML>\n",
+ Config.adminEmail,
+ Config.errHtmlText,
appname,
version_string,
getMyHostname());
/* Now stuff them together and add Authenticate header */
l = 0;
s = AUTH_MSG_SZ;
- l += snprintf(auth_msg + l, s - l, "%s", hdr);
- l += snprintf(auth_msg + l, s - l,
+ l += snprintf(buf + l, s - l, "%s", hdr);
+ l += snprintf(buf + l, s - l,
"WWW-Authenticate: Basic realm=\"%s\"\r\n",
realm);
- l += snprintf(auth_msg + l, s - l, "\r\n%s", content);
- return auth_msg;
+ l += snprintf(buf + l, s - l, "\r\n%s", content);
+ return buf;
}