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

📄 file.c

📁 浏览器的源代码,可移植到嵌入式设备.
💻 C
📖 第 1 页 / 共 2 页
字号:
      if ((fd = open(filename, O_RDONLY)) >= 0) {         if ((buf_size = read(fd, buf, 256)) > 12 ) {            ct = a_Misc_get_content_type_from_data(buf, buf_size);         }         File_close(fd);      }   }   return ct;}/* * Create a new file connection for 'Url', and asynchronously * feed the bytes that come back to the cache. * ( Data1 = Requested Url; Data2 = Web structure ) */static void File_get(ChainLink *Info, void *Data1, void *Data2){   const gchar *path;   gchar *filename;   gint fd;   struct stat sb;   const DilloUrl *Url = Data1;   DilloWeb *web = Data2;   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);   }   if ( fd < 0 ) {      File_not_found_msg(web, filename, fd);      a_Chain_fcb(OpAbort, Info, NULL, NULL);   } else {      /* Tell the cache to start the receiving CCC */      a_Chain_fcb(OpSend, Info, &fd, NULL);      /* End the requesting CCC */      a_Chain_fcb(OpEnd, Info, NULL, NULL);   }   g_free(filename);   return;}/* * Create a pipe connection for URL 'url', which is a directory, * and feed an ordered html listing through it. * (The feeding function runs on its own thread) */static gint File_get_dir(const gchar *DirName){   GString *g_dirname;   DilloDir *Ddir;   /* Let's make sure this directory url has a trailing slash */   g_dirname = g_string_new(DirName);   if ( g_dirname->str[g_dirname->len - 1] != '/' )      g_string_append(g_dirname, "/");   /* Let's get a structure ready for transfer */   Ddir = File_dillodir_new(g_dirname->str);   g_string_free(g_dirname, TRUE);   if ( Ddir ) {      gint fd = Ddir->FD_Read;      pthread_create(&Ddir->th1, NULL, File_transfer_dir, Ddir);      return fd;   } else      return -1;}/* * Create a pipe connection for URL 'url', which is a file, * send the MIME content/type through it and then send the file itself. * (The feeding function runs on its own thread) */static gint File_get_file(const gchar *FileName){   DilloFile *Dfile;   /* Create a control structure for this transfer */   Dfile = File_dillofile_new(FileName);   if ( Dfile ) {      gint fd = Dfile->FD_Read;      pthread_create(&Dfile->th1, NULL, File_transfer_file, Dfile);      return fd;   } else      return -1;}/* * Return a HTML-line from file info. */static GString * File_info2html(struct stat *SPtr, const char *fname,                const char *name, const char *dirname, const char *date){   static char *dots = ".. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..";   GString *gstr;   gint size, ndots;   char *sizeunits;#define MAXNAMESIZE 30   char namebuf[MAXNAMESIZE + 1];   const char *ref, *Cparent, *HCparent, *Cref, *HCref, *Hname;   const gchar *cont, *filecont;   gchar *s1, *s2, *s3;   if (!name)      return NULL;   gstr = g_string_sized_new(128);   if (strcmp(name, "..") == 0) {      if ( strcmp(dirname, "/") != 0 ){        /* Not the root dir */         char *parent = g_strdup(dirname);         char *p;         /* cut trailing '/' */         parent[strlen(parent) - 1] = '\0';         /* make 'parent' have the parent dir path */         if ( (p = strrchr(parent, '/')) )            *(p + 1) = '\0';         else { /* in case name == ".." */            g_free(parent);            parent = g_get_current_dir();            if ( (p = strrchr(parent, '/')) )              *p = '\0'; /* already cut trailing '/' */            if ( (p = strrchr(parent, '/')) )              *(p + 1) = '\0';         }         Cparent = (s1 = a_Misc_escape_chars(parent, "%#:' ")) ? s1: parent;         HCparent = (s2 = File_html_escape(Cparent)) ? s2 : Cparent;         g_string_sprintf(gstr, "<a href='file:%s'>%s</a>\n\n\n",                          HCparent, "Parent directory");         g_free(s2);         g_free(s1);         g_free(parent);      } else         g_string_sprintf(gstr, "<br>\n");      return gstr;   }   if (SPtr->st_size <= 9999) {      size = SPtr->st_size;      sizeunits = "bytes";   } else if (SPtr->st_size / 1024 <= 9999) {      size = rint(SPtr->st_size / 1024.0);      sizeunits = "Kb";   } else {      size = rint(SPtr->st_size / 1048576.0);      sizeunits = "Mb";   }   /* we could note if it's a symlink... */   if S_ISDIR (SPtr->st_mode) {      cont = "application/directory";      filecont = "Directory";   } else if (SPtr->st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {      cont = "application/executable";      filecont = "Executable";   } else {      filecont = cont = File_content_type(fname);      if (!strcmp(filecont, "application/octet-stream"))         filecont = "unknown";   }   ref = name;   if (strlen(name) > MAXNAMESIZE) {      memcpy(namebuf, name, MAXNAMESIZE - 3);      strcpy(namebuf + (MAXNAMESIZE - 3), "...");      name = namebuf;   }   ndots = MAXNAMESIZE - strlen(name);   ndots = MAX(ndots, 0);   /* escape problematic filenames */   Cref = (s1 = a_Misc_escape_chars(ref, "%#:' ")) ? s1 : ref;   HCref = (s2 = File_html_escape(Cref)) ? s2 : Cref;   Hname = (s3 = File_html_escape(name)) ? s3 : name;   g_string_sprintf(gstr,                    "%s<a href='%s'>%s</a> %s%10s %5d %-5s %s\n",                    S_ISDIR (SPtr->st_mode) ? ">" : " ", HCref, Hname,                    dots+50-ndots, filecont, size, sizeunits, date);   g_free(s3);   g_free(s2);   g_free(s1);   return gstr;}/* * Given a timestamp, create a date string and place it in 'datestr' */static void File_get_datestr(time_t *mtime, char *datestr){   time_t currenttime;   char *ds;   time(&currenttime);   ds = ctime(mtime);   if (currenttime - *mtime > 15811200) {      /* over about 6 months old */      sprintf(datestr, "%6.6s  %4.4s", ds + 4, ds + 20);   } else {      /* less than about 6 months old */      sprintf(datestr, "%6.6s %5.5s", ds + 4, ds + 11);   }}/* * Compare two strings * This function is used for sorting directories */static gint File_comp(const void *a, const void *b){   return strcmp(*(char **)a, *(char **)b);}/* * Read directory entries to a list, sort them alphabetically, and return * formatted HTML, line by line, one per entry. * When there're no more entries, return NULL */static GString *File_dir2html(DilloDir *Ddir){   struct dirent *de;   struct stat sb;   char *name;   GString *gs;   gint *index;#ifndef MAXPATHLEN#define MAXPATHLEN 1024#endif   char fname[MAXPATHLEN + 1];   char datebuf[64];   if ( !Ddir->scanned ) {      /* Lets scan every name and sort them */      while ((de = readdir(Ddir->dir)) != 0) {         if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))            continue;              /* skip "." and ".." */         sprintf(fname, "%s/%s", Ddir->dirname, de->d_name);         if (stat(fname, &sb) == -1)            continue;              /* ignore files we can't stat */         if ( S_ISDIR(sb.st_mode) ) {            a_List_add(Ddir->dlist, Ddir->dlist_size, Ddir->dlist_max);            Ddir->dlist[Ddir->dlist_size] = g_strdup(de->d_name);            ++Ddir->dlist_size;         } else {            a_List_add(Ddir->flist, Ddir->flist_size, Ddir->flist_max);            Ddir->flist[Ddir->flist_size] = g_strdup(de->d_name);            ++Ddir->flist_size;         }      }      /* sort the entries */      qsort(Ddir->dlist, Ddir->dlist_size, sizeof(char *), File_comp);      qsort(Ddir->flist, Ddir->flist_size, sizeof(char *), File_comp);      /* Directory scanning done */      Ddir->scanned = TRUE;   }   if ( !Ddir->parent_dir ) {      name = g_strdup("..");      index = &Ddir->parent_dir;   } else if ( Ddir->dlist_idx < Ddir->dlist_size ) {      /* We still have directory entries */      name = Ddir->dlist[Ddir->dlist_idx];      index = &Ddir->dlist_idx;   } else if ( Ddir->flist_idx < Ddir->flist_size ) {      /* We still have file entries */      name = Ddir->flist[Ddir->flist_idx];      index = &Ddir->flist_idx;   } else {      g_free(Ddir->flist);      g_free(Ddir->dlist);      return NULL;   }   sprintf(fname, "%s/%s", Ddir->dirname, name);   stat(fname, &sb);   File_get_datestr(&sb.st_mtime, datebuf);   gs = File_info2html(&sb, fname, name, Ddir->dirname, datebuf);   g_free(name);   ++(*index);   return gs;}/* * Give a file-not-found error (an HTML page). * Return Value: -1 */static void File_not_found_msg(DilloWeb *web, const char *filename, int fd){   if ( web->flags & WEB_RootUrl )      a_Interface_msg(web->bw, "ERROR: Can't find %s %s",                         (fd == -2) ? "" : "file", filename);   else      DEBUG_MSG(4, "Warning: Can't find <%s>\n", filename);}/* * CCC function for the FILE module */void a_File_ccc(int Op, int Branch, int Dir, ChainLink *Info,                void *Data1, void *Data2){   a_Chain_debug_msg("a_File_ccc", Op, Branch, Dir);   if ( Branch == 1 ) {      /* Start file method */      if (Dir == BCK) {         switch (Op) {         case OpStart:            /* (Data1 = Url;  Data2 = Web) */            File_get(Info, Data1, Data2);            break;         }      }   }}

⌨️ 快捷键说明

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