📄 file.c
字号:
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(¤ttime); 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 + -