diff options
Diffstat (limited to 'dpi/ftp.c')
-rw-r--r-- | dpi/ftp.c | 90 |
1 files changed, 53 insertions, 37 deletions
@@ -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); |