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

📄 file.c

📁 浏览器的源代码,可移植到嵌入式设备.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * File: file.c :) * * Copyright (C) 2000 - 2004 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. *//* * Directory scanning is no longer streamed, but it gets sorted instead! * Directory entries on top, files next. * Not forked anymore; pthread handled. * With new HTML layout. */#include <pthread.h>#include <ctype.h>           /* for tolower */#include <unistd.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <dirent.h>#include <fcntl.h>#include <string.h>#include <time.h>#include <stdio.h>#include <signal.h>#include <math.h>            /* for rint */#include <errno.h>           /* for errno */#include "Url.h"#include "IO.h"#include "../list.h"#include "../misc.h"#include "../web.h"#include "../interface.h"#define DEBUG_LEVEL 5#include "../debug.h"typedef struct _DilloDir {   gint FD_Write, FD_Read;   char *dirname;   DIR *dir;   gboolean scanned;   /* Flag: Have we scanned it? */   gint parent_dir;    /* Flag: Have we shown parent directory? */   char **dlist;       /* List of subdirectories (for sorting) */   gint dlist_size;   gint dlist_max;   gint dlist_idx;   char **flist;       /* List of files (for sorting) */   gint flist_size;   gint flist_max;   gint flist_idx;   pthread_t th1;      /* This transfer's thread id. */} DilloDir;typedef struct {   gint FD_Write,   /* Where we write */        FD_Read;    /* Where our clients read */   gint FD;         /* Our local-file descriptor */   char *FileName;   glong FileSize;   pthread_t th1;      /* This transfer's thread id. */} DilloFile;/* * Local data *//* * Forward references */static const char *File_content_type(const char *filename);static gint File_get_file(const gchar *FileName);static gint File_get_dir(const gchar *DirName);static GString *File_dir2html(DilloDir *Ddir);static void File_not_found_msg(DilloWeb *web, const char *filename, int fd);static gchar *File_html_escape(const gchar *str);/* * Close a file descriptor, but handling EINTR */static void File_close(int fd){   gint st;   while ((st = close(fd)) < 0 && errno == EINTR);}/* * Escape unsafe characters as html entities. * Return value: NULL if there's no need to escape, New string otherwise. */static gchar *File_html_escape(const gchar *str){   static const char *unsafe_chars = "&<>\"'";   static const char *unsafe_rep[] =     { "&amp;", "&lt;", "&gt;", "&quot;", "&#39;" };   gchar *p;   GString *gstr;   gint i;   if ((p = strpbrk(str, unsafe_chars))) {      gstr = g_string_sized_new(64);      for (i = 0; str[i]; ++i) {         if ((p = strchr(unsafe_chars, str[i])))            g_string_append(gstr, unsafe_rep[p - unsafe_chars]);         else            g_string_append_c(gstr, str[i]);      }      p = gstr->str;      g_string_free(gstr, FALSE);   }   return p;}/* * Allocate a DilloFile structure, and set working values in it. */static DilloFile *File_dillofile_new(const char *filename){   gint fds[2], fd;   struct stat sb;   DilloFile *Dfile;   if ( (fd = open(filename, O_RDONLY)) < 0 || pipe(fds) )      return NULL;   Dfile = g_new(DilloFile, 1);   Dfile->FD_Read  = fds[0];   Dfile->FD_Write = fds[1];   Dfile->FD = fd;   Dfile->FileName = g_strdup(filename);   Dfile->FileSize = fstat(fd, &sb) ? -1 : (glong) sb.st_size;   return Dfile;}/* * Deallocate a DilloFile structure. */static void File_dillofile_free(DilloFile *Dfile){   g_free(Dfile->FileName);   g_free(Dfile);}/* * Allocate a DilloDir structure, and set safe values in it. */static DilloDir *File_dillodir_new(char *dirname){   DIR *dir;   gint fds[2];   DilloDir *Ddir;   if ( !(dir = opendir(dirname)) || pipe(fds) )      return NULL;   Ddir = g_new(DilloDir, 1);   Ddir->dir = dir;   Ddir->scanned = FALSE;   Ddir->parent_dir = FALSE;   Ddir->dirname = g_strdup(dirname);   Ddir->FD_Read  = fds[0];   Ddir->FD_Write = fds[1];   Ddir->dlist = NULL;   Ddir->dlist_size = 0;   Ddir->dlist_max = 256;   Ddir->dlist_idx = 0;   Ddir->flist = NULL;   Ddir->flist_size = 0;   Ddir->flist_max = 256;   Ddir->flist_idx = 0;   return Ddir;}/* * Deallocate a DilloDir structure. */static void File_dillodir_free(DilloDir *Ddir){   g_free(Ddir->dirname);   g_free(Ddir);}/* * Read a local file, and send it through a pipe. * (This function runs on its own thread) */static void *File_transfer_file(void *data){#define LBUF 16*1024   char buf[LBUF];   DilloFile *Dfile = data;   ssize_t nbytes;   const gchar *ct;   /* Set this thread to detached state */   pthread_detach(Dfile->th1);   /* Content type info: as we may misdetect a lot of files,    * every unknown type is rendered as "text/plain".    * todo: a better approach could be to detect&reject those types we know    * for sure we don't handle (as gzip, bzip, ELF, etc)    */   ct = File_content_type(Dfile->FileName);   if (!strcmp(ct, "application/octet-stream"))      ct = "text/plain";   /* Send content type info */   g_snprintf(buf, LBUF, "Content-Type: %s\n", ct);   write(Dfile->FD_Write, buf, strlen(buf));   /* Send File Size info */   if (Dfile->FileSize != -1) {      g_snprintf(buf, LBUF, "Content-length: %ld\n", Dfile->FileSize);      write(Dfile->FD_Write, buf, strlen(buf));   }   /* Send end-of-header */   strcpy(buf, "\n");   write(Dfile->FD_Write, buf, strlen(buf));   /* Append raw file contents */   while ( (nbytes = read(Dfile->FD, buf, LBUF)) != 0 ) {      write(Dfile->FD_Write, buf, nbytes);   }   File_close(Dfile->FD);   File_close(Dfile->FD_Write);   File_dillofile_free(Dfile);   return NULL;}/* * Read a local directory, translate it to html, and send it through a pipe. * (This function runs on its own thread) */static void *File_transfer_dir(void *data){   char *s1, *s2, *s3, *Hdirname, *Cdirname, *HCdirname;   GString *gstr, *gs;   DilloDir *Ddir = data;   FILE *F_Write;   /* Set this thread to detached state */   pthread_detach(Ddir->th1);   /* With a stream, the buffering speeds up the transfer */   F_Write = fdopen(Ddir->FD_Write, "w");   gstr = g_string_sized_new(128);   /* Send MIME content/type info */   g_string_sprintf(gstr, "Content-Type: %s\n\n",                    File_content_type("dir.html"));   fwrite(gstr->str, gstr->len, 1, F_Write);   /* Send page title */   Cdirname =      (s1 = a_Misc_escape_chars(Ddir->dirname, "%#:' ")) ? s1 : Ddir->dirname;   HCdirname = (s2 = File_html_escape(Cdirname)) ? s2 : Cdirname;   Hdirname = (s3 = File_html_escape(Ddir->dirname)) ? s3 : Ddir->dirname;   g_string_sprintf(gstr, "<HTML>\n<HEAD>\n <BASE href='%s%s'>\n"                    " <TITLE>%s%s</TITLE>\n</HEAD>\n",                    "file:", HCdirname,                    "file:", Hdirname);   fwrite(gstr->str, gstr->len, 1, F_Write);   g_string_sprintf(gstr, "<BODY><H1>%s %s</H1>\n<pre>\n",                    "Directory listing of", Hdirname);   fwrite(gstr->str, gstr->len, 1, F_Write);   g_free(s3);   g_free(s2);   g_free(s1);   /* Append formatted directory contents */   while ( (gs = File_dir2html(Ddir)) ){      fwrite(gs->str, gs->len, 1, F_Write);      g_string_free(gs, TRUE);   }   /* Close open HTML tags */   g_string_sprintf(gstr, "\n</pre></BODY></HTML>\n");   fwrite(gstr->str, gstr->len, 1, F_Write);   fclose(F_Write);   File_close(Ddir->FD_Write);   closedir(Ddir->dir);   Ddir->dir = NULL;   File_dillodir_free(Ddir);   g_string_free(gstr, TRUE);   return NULL;}/* * Return 1 if the extension matches that of the filename. */static gint File_ext(const char *filename, const char *ext){   char *e;   if ( !(e = strrchr(filename, '.')) )      return 0;   return (g_strcasecmp(ext, ++e) == 0);}/* * Based on the extension, return the content_type for the file. * (if there's no extension, analize the data and try to figure it out) */static const char *File_content_type(const char *filename){   gint fd;   gchar buf[256];   const gchar *ct;   ssize_t buf_size;   ct = "text/plain";   if (File_ext(filename, "gif")) {      ct = "image/gif";   } else if (File_ext(filename, "jpg") || File_ext(filename, "jpeg")) {      ct = "image/jpeg";   } else if (File_ext(filename, "png")) {      ct = "image/png";   } else if (File_ext(filename, "html") || File_ext(filename, "htm") ||              File_ext(filename, "shtml")) {      ct = "text/html";   } else {      /* everything failed, let's analize the data... */

⌨️ 快捷键说明

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