⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftp.c

📁 浏览器的源代码,可移植到嵌入式设备.
💻 C
字号:
/* * Dpi for FTP. * * This server checks the ftp-URL to be a directory (requires wget). * If true, it sends back an html representation of it, and if not * a dpip message (which is catched by dillo who redirects the ftp URL * to the downloads server). * * THIS IS A PROTOTYPE to illustrate how it is done. Feel free to polish! * * Copyright 2003 Jorge Arellano Cid <jcid@dillo.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * *//* * TODO: * - Check dpi command syntax * - Handle simultaneous connections. *   (note that if it becomes resident there's less forking). * - Send feedback about the FTP login process from wget's stderr. *   i.e. capture our child's stderr, process it, and report back. * - Add error handling * - etc * *   If ftp.dpi is implemented with a low level ftp library, it becomes *   possible to keep the connection alive, and thus make browsing of ftp *   directories faster (this avoids one login per page, and forks). Perhaps *   it's not worth, but can be done. * *   Currently, anything the user clicks is sent back to Dillo. This *   may be better handled by inserting file type detection here. If *   we detect a binary, the connection is aborted and a download request *   dpi tag is sent instead. * *   This ftp plugin profits from the fact that given no MIME type in *   the HTTP header, dillo tries to detect the filetype itself. */#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/un.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <signal.h>#include <sys/wait.h>#include <errno.h>#include <sys/time.h>#include <glib.h>#define BUFLEN 256#define TOUT 300/*---------------------------------------------------------------------------*//* * Task: given a tag and an attribute name, return its value. *       (character stuffing is removed here) * Return value: the attribute value, or NULL if not present or malformed. * (copied from bookmarks.c) */char *Get_attr_value(char *tag, int tagsize, char *attrname){   char *p, *q, *ltag, quote, *start, *val = NULL;   ltag = g_strndup(tag, tagsize);   if ((p = strstr(ltag, attrname)) &&       (p = strchr(p, '=')) &&       (p = strpbrk(p, "'\"")) ) {      quote = *p;      start = ++p;      while ((q = strchr(p, quote)) && q[1] == quote)         p = q + 2;      if (q) {         val = g_strndup(start, q - start);         for (p = q = val; (*q = *p); ++p, ++q)            if ((*p == '"' || *p == '\'') && p[1] == p[0])               ++p;      }   }   g_free(ltag);   return val;}/*---------------------------------------------------------------------------*//* * Build a shell command using wget for this URL. */gchar *make_wget_cmd(gchar *url){   gchar *p, *wcmd = NULL;   if ((p = strrchr(url, '/')) != NULL){      /* if it does not end with a slash, append one */      wcmd =      // g_strdup_printf("wget -O - %s%s 2>/dev/null", url, p[1] ? "/" : "");         g_strdup_printf("wget -O - '%s' 2>/dev/null", url);   }   return wcmd;}/* * Send the stream char by char (useful for slow transfer test) * Return value: bytes written */gint send_stream_1(FILE *in_stream, gchar *url){   gint i, ch;   for (i = 0; (ch = fgetc(in_stream)) != EOF; ++i) {      if (i == 0) {        printf("<dpi cmd='start_send_page' url='%s'>", url);        fflush(stdout);        printf("Content-type: text/html\n\n");        fflush(stdout);      }      printf("%c", ch);      g_printerr("%c", ch);      fflush(stdout);   }   return i;}/* * Send the stream with default buffering (somewhat faster) * Return value: bytes written */gint send_stream_2(FILE *in_stream, gchar *url){   gint i, ch;   for (i = 0; (ch = fgetc(in_stream)) != EOF; ++i) {      if (i == 0) {        printf("<dpi cmd='start_send_page' url='%s'>", url);        printf("Content-type: text/html\n\n");      }      printf("%c", ch);      g_printerr("%c", ch);   }   return i;}/* * Send the stream with coarse buffering (fastest) * Return value: 1: data sent,  0: nothing sent */gint send_stream_3(FILE *in_stream, gchar *url){   gint header = 0;   gchar buf[4096];   size_t n;   while ((n = fread (buf, 1, 4096, in_stream)) > 0) {      //g_printerr("ftp.dpi::fread: read n = %d bytes\n", n);      if (n > 0 && !header) {         printf("<dpi cmd='start_send_page' url='%s'>", url);         //printf("Content-type: text/html\n\n");         printf("\n\n");         header = 1;      }      fwrite(buf, 1, n, stdout);      //fwrite(buf, 1, n, stderr);   }// g_printerr("ftp.dpi::fread: read n = %d bytes\n", n);   return header;}/* * Fork, exec command, get its output and redirect to stdout. * Return: Number of bytes transfered. */gint try_ftp_transfer(gchar *wget_cmd, gchar *url){   FILE *in_stream;   gint nb, ret;   if ((in_stream = popen(wget_cmd, "r")) == NULL) {      perror("popen");      exit (EXIT_FAILURE);   }   /* Read/Write */   nb = send_stream_3(in_stream, url);   if ((ret = pclose(in_stream)) != 0)      g_printerr("ftp.dpi::pclose: [%d] %s\n", ret, g_strerror(errno));   return nb;}/* * */int main(void){   FILE *F_stdin;   gchar *dpip_tag = NULL, *cmd = NULL, *url = NULL, *url2 = NULL,         *wget_cmd = NULL, *wget_cmd2 = NULL;   gint nb, rd_len;   gchar buf[4096], *p;   /* wget may need to write a temporary file... */   chdir("/tmp");   /* Read the dpi command from STDIN */   F_stdin = fdopen (STDIN_FILENO, "r");   rd_len = read(STDIN_FILENO, buf, 4096);   dpip_tag = g_strndup(buf, rd_len);   fclose(F_stdin);// close(STDIN_FILENO); /* Necessary? */// g_printerr("[%s]\n", dpip_tag);   cmd = Get_attr_value(dpip_tag, strlen(dpip_tag), "cmd");   url = Get_attr_value(dpip_tag, strlen(dpip_tag), "url");   if (!cmd || !url) {      g_printerr("ftp.dpi:: Error, cmd=%s, url=%s\n", cmd, url);      exit (EXIT_FAILURE);   }   /* make command string */   wget_cmd = make_wget_cmd(url);   g_printerr("ftp.dpi::[%s]\n", wget_cmd);   if ((nb = try_ftp_transfer(wget_cmd, url)) == 0) {      /* Transfer failed, the requested file may not exist or be a symlnk       * to a directory. Try again... */      if ((p = strrchr(url, '/')) && p[1]) {         url2 = g_strconcat(url, "/", NULL);         wget_cmd2 = make_wget_cmd(url2);         nb = try_ftp_transfer(wget_cmd2, url);      }   }   if (nb == 0) {      /* The transfer failed, let dillo know... */      printf("<dpi cmd='answer' to_cmd='open_url' msg='not a directory'>");      fflush(stdout);   }   g_free(cmd);   g_free(url);   g_free(url2);   g_free(dpip_tag);   g_free(wget_cmd);   g_free(wget_cmd2);   return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -