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

📄 file.c

📁 嵌入式浏览器Dillo源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * File: file.c :) * * Copyright (C) 2000, 2001 Jorge Arellano Cid <jcid@inf.utfsm.cl> * * 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 "../web.h"#include "../interface.h"typedef struct _DilloDir {   gint FD_Write, FD_Read;   char *dirname;   DIR *dir;   gboolean scanned;   /* Flag: Have we scanned it? */   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;   const char *ContentType;   glong FileSize;   pthread_t th1;      /* This transfer's thread id. */} DilloFile;/* * Local data *//* * Forward references */static char *File_content_type(const char *filename);static gint File_get_file(const gchar *FileName);static gint File_get_dir(const gchar *DirName);static char *File_dir2html(DilloDir *Ddir);static void File_not_found_msg(DilloWeb *web, const char *filename, int fd);/* * 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->ContentType = File_content_type(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->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){   char buf[8192];   DilloFile *Dfile = data;   ssize_t nbytes;   /* Set this thread to detached state */   pthread_detach(Dfile->th1);   /* Send content type info */   sprintf(buf, "Content-Type: %s\n", Dfile->ContentType);   write(Dfile->FD_Write, buf, strlen(buf));   /* Send File Size info */   if (Dfile->FileSize != -1) {      sprintf(buf, "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, 8192)) != 0 ) {      write(Dfile->FD_Write, buf, nbytes);   }   close(Dfile->FD);   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 buf[8192],        *s;   DilloDir *Ddir = data;   /* Set this thread to detached state */   pthread_detach(Ddir->th1);   /* Send MIME content/type info */   sprintf(buf, "Content-Type: %s\n\n", File_content_type("dir.html"));   write(Ddir->FD_Write, buf, strlen(buf));   /* Send page title */   sprintf(buf, "<HTML><HEAD><TITLE>%s%s</TITLE></HEAD>\n",                "file:", Ddir->dirname);   write(Ddir->FD_Write, buf, strlen(buf));   sprintf(buf, "<BODY><H1>%s %s</H1>\n<pre>\n", "Directory listing of",                Ddir->dirname);   write(Ddir->FD_Write, buf, strlen(buf));   /* Append formatted directory contents */   while ( (s = File_dir2html(Ddir)) ){      write(Ddir->FD_Write, s, strlen(s));   }   /* Close open HTML tags */   sprintf(buf, "\n</pre></BODY></HTML>\n");   write(Ddir->FD_Write, buf, strlen(buf));   close(Ddir->FD_Write);   closedir(Ddir->dir);   Ddir->dir = NULL;   File_dillodir_free(Ddir);   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 (strcasecmp(ext, ++e) == 0);}/* * Based on the extension, return the content_type for the file. */static char *File_content_type(const char *filename){   if (File_ext(filename, "gif")) {      return "image/gif";   } else if (File_ext(filename, "jpg") || File_ext(filename, "jpeg")) {      return "image/jpeg";   } else if (File_ext(filename, "png")) {      return "image/png";   } else if (File_ext(filename, "html") || File_ext(filename, "htm") ||              File_ext(filename, "shtml")) {      return "text/html";   }   return "text/plain";}/* * Create a new file connection for 'Url', and asynchronously * feed the bytes that come back to the cache. * ( Data = Requested Url; ExtraData = Web structure ) */static void File_get(ChainLink *Info, void *Data, void *ExtraData){   const gchar *path;   gchar *filename;   gint fd;   struct stat sb;   IOData_t *io;   const DilloUrl *Url = Data;   DilloWeb *web = ExtraData;   path = URL_PATH_(Url);   if (!path || !strcmp(path, ".") || !strcmp(path, "./"))      /* if there's no path in the URL, show current directory */      filename = g_get_current_dir();   else if (!strcmp(path, "~") || !strcmp(path, "~/"))      filename = g_strdup(g_get_home_dir());   else      filename = a_Url_parse_hex_path(Url);   if ( stat(filename, &sb) != 0 ) {      /* stat failed, prepare a file-not-found error. */      fd = -2;   } else if (S_ISDIR(sb.st_mode)) {      /* set up for reading directory */      fd = File_get_dir(filename);   } else {      /* set up for reading a file */      fd = File_get_file(filename);

⌨️ 快捷键说明

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