aboutsummaryrefslogtreecommitdiff
path: root/dpi/ftp.c
diff options
context:
space:
mode:
Diffstat (limited to 'dpi/ftp.c')
-rw-r--r--dpi/ftp.c90
1 files changed, 53 insertions, 37 deletions
diff --git a/dpi/ftp.c b/dpi/ftp.c
index 0d7bc23a..6b1e2f31 100644
--- a/dpi/ftp.c
+++ b/dpi/ftp.c
@@ -171,17 +171,18 @@ static void make_wget_argv(char *url)
/*
* Fork, exec command, get its output and send via stdout.
- * Return: Number of bytes transfered.
+ * Return: Number of bytes transfered, -1 if file-not_found, -2 if aborted.
*/
static int try_ftp_transfer(char *url)
{
-#define MinSZ 256
+#define MIN_SZ 256
+#define READ_SZ 16*1024
ssize_t n;
- int nb, has_mime_type, has_html_header;
+ int nb, has_mime_type, has_html_header, no_such_file, offer_download;
const char *mime_type = "application/octet-stream";
- char buf[4096], *d_cmd;
- Dstr *dbuf = dStr_sized_new(4096);
+ char buf[READ_SZ], *d_cmd;
+ Dstr *dbuf = dStr_sized_new(READ_SZ);
pid_t ch_pid;
int aborted = 0;
int DataPipe[2];
@@ -214,18 +215,24 @@ static int try_ftp_transfer(char *url)
nb = 0;
has_mime_type = 0;
has_html_header = 0;
+ no_such_file = 0;
+ offer_download = 0;
do {
- while ((n = read(DataPipe[0], buf, 4096)) < 0 && errno == EINTR);
+ while ((n = read(DataPipe[0], buf, READ_SZ)) < 0 && errno == EINTR);
if (n > 0) {
dStr_append_l(dbuf, buf, n);
- if (!has_mime_type && dbuf->len < MinSZ)
+ if (!has_mime_type && dbuf->len < MIN_SZ)
continue;
} else if (n < 0)
break;
if (!has_mime_type) {
- if (dbuf->len > 0)
- a_Misc_get_content_type_from_data2(dbuf->str,dbuf->len,&mime_type);
+ if (dbuf->len == 0) {
+ /* When the file doesn't exist, the transfer size is zero */
+ no_such_file = 1;
+ break;
+ }
+ a_Misc_get_content_type_from_data2(dbuf->str, dbuf->len, &mime_type);
has_mime_type = 1;
if (strcmp(mime_type, "application/octet-stream") == 0) {
@@ -233,11 +240,12 @@ static int try_ftp_transfer(char *url)
kill(ch_pid, SIGTERM);
/* The "application/octet-stream" MIME type will be sent and
* Dillo will offer a download dialog */
+ offer_download = 1;
aborted = 1;
}
}
- if (!has_html_header && dbuf->len) {
+ if (offer_download || (!aborted && !has_html_header && dbuf->len)) {
/* Send dpip tag */
d_cmd = a_Dpip_build_cmd("cmd=%s url=%s", "start_send_page", url);
a_Dpip_dsh_write_str(sh, 1, d_cmd);
@@ -246,18 +254,19 @@ static int try_ftp_transfer(char *url)
/* Send HTTP header. */
a_Dpip_dsh_write_str(sh, 0, "Content-type: ");
a_Dpip_dsh_write_str(sh, 0, mime_type);
- a_Dpip_dsh_write_str(sh, 1, "\n\n");
+ a_Dpip_dsh_write_str(sh, 1, "\r\n\r\n");
has_html_header = 1;
}
if (!aborted && dbuf->len) {
- a_Dpip_dsh_write(sh, 0, dbuf->str, dbuf->len);
+ a_Dpip_dsh_write(sh, 1, dbuf->str, dbuf->len);
nb += dbuf->len;
dStr_truncate(dbuf, 0);
}
} while (n > 0 && !aborted);
- return nb;
+ dStr_free(dbuf, 1);
+ return (no_such_file ? -1 : (aborted ? -2 : nb));
}
/*
@@ -265,17 +274,11 @@ static int try_ftp_transfer(char *url)
*/
int main(int argc, char **argv)
{
+ const char *err_msg = "404 Not Found\nNo such file or directory";
char *dpip_tag = NULL, *cmd = NULL, *url = NULL, *url2 = NULL;
- int nb, rc;
+ int st, rc;
char *p, *d_cmd;
- /* Debugging with a command line argument */
- if (argc == 2)
- dpip_tag = dStrdup(argv[1]);
-
- /* Initialize the SockHandler */
- sh = a_Dpip_dsh_new(STDIN_FILENO, STDOUT_FILENO, 8*1024);
-
/* wget may need to write a temporary file... */
rc = chdir("/tmp");
if (rc == -1) {
@@ -283,17 +286,24 @@ int main(int argc, char **argv)
dStrerror(errno));
}
- /* Authenticate our client... */
- if (!(dpip_tag = a_Dpip_dsh_read_token(sh, 1)) ||
- a_Dpip_check_auth(dpip_tag) < 0) {
- MSG("can't authenticate request: %s\n", dStrerror(errno));
- a_Dpip_dsh_close(sh);
- return 1;
- }
- dFree(dpip_tag);
+ /* Initialize the SockHandler */
+ sh = a_Dpip_dsh_new(STDIN_FILENO, STDOUT_FILENO, 8*1024);
- /* Read the dpi command from STDIN */
- dpip_tag = a_Dpip_dsh_read_token(sh, 1);
+ if (argc == 2) {
+ /* Debugging with a command line argument */
+ dpip_tag = dStrdup(argv[1]);
+ } else {
+ /* Authenticate our client... */
+ if (!(dpip_tag = a_Dpip_dsh_read_token(sh, 1)) ||
+ a_Dpip_check_auth(dpip_tag) < 0) {
+ MSG("can't authenticate request: %s\n", dStrerror(errno));
+ a_Dpip_dsh_close(sh);
+ return 1;
+ }
+ dFree(dpip_tag);
+ /* Read the dpi command from STDIN */
+ dpip_tag = a_Dpip_dsh_read_token(sh, 1);
+ }
MSG("tag=[%s]\n", dpip_tag);
cmd = a_Dpip_get_attr(dpip_tag, "cmd");
@@ -303,21 +313,27 @@ int main(int argc, char **argv)
exit (EXIT_FAILURE);
}
- if ((nb = try_ftp_transfer(url)) == 0) {
+ if ((st = try_ftp_transfer(url)) == -1) {
/* Transfer failed, the requested file may not exist or be a symlink
* to a directory. Try again... */
if ((p = strrchr(url, '/')) && p[1]) {
url2 = dStrconcat(url, "/", NULL);
- nb = try_ftp_transfer(url2);
+ st = try_ftp_transfer(url2);
}
}
- if (nb == 0) {
+ if (st == -1) {
/* The transfer failed, let dillo know... */
- d_cmd = a_Dpip_build_cmd("cmd=%s to_cmd=%s msg=%s",
- "answer", "open_url", "not a directory");
- a_Dpip_dsh_write_str(sh, 1, d_cmd);
+ d_cmd = a_Dpip_build_cmd("cmd=%s url=%s", "start_send_page", url);
+ a_Dpip_dsh_write_str(sh, 0, d_cmd);
dFree(d_cmd);
+ a_Dpip_dsh_printf(sh, 1,
+ "HTTP/1.1 404 Not Found\r\n"
+ "Content-Type: text/plain\r\n"
+ "Content-Length: %d\r\n"
+ "\r\n"
+ "%s",
+ strlen(err_msg), err_msg);
}
dFree(cmd);