📄 file.c
字号:
} if ( fd < 0 ) { File_not_found_msg(web, filename, fd); a_Chain_fcb(OpAbort, 1, Info, NULL, NULL); } else { /* End the requesting CCC */ a_Chain_fcb(OpEnd, 1, Info, NULL, ExtraData); /* receive answer */ io = a_IO_new(fd); io->Op = IORead; io->IOVec.iov_base = g_malloc(IOBufLen_File); io->IOVec.iov_len = IOBufLen_File; io->Flags |= IOFlag_FreeIOVec; io->ExtData = (void *) Url; a_IO_ccc(OpStart, 2, a_Chain_new(), io, NULL); } g_free(filename); return;}/* * CCC function for the FILE module */void a_File_ccc(int Op, int Branch, ChainLink *Info, void *Data, void *ExtraData){ if ( Op == OpStart ) { File_get(Info, Data, ExtraData); }}/* * 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 char *File_info2html(struct stat *SPtr, const char *name, const char *dirname, const char *date){ static char *dots = ".. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .."; static char buf[1200]; gint size, ndots; char *sizeunits;#define MAXNAMESIZE 30 char namebuf[MAXNAMESIZE + 1]; const char *ref; char anchor[1024]; char *cont; char *longcont; if (!name) return NULL; 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'; } sprintf(buf, "<a href=\"file:%s\">%s</a>\n<p>\n", parent, "Parent directory"); g_free(parent); } else strcpy(buf, "<br>\n"); return buf; } 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"; longcont = "Directory"; } else if (SPtr->st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) { cont = "application/executable"; longcont = "Executable"; } else { cont = File_content_type(name); longcont = cont; if (!cont) { cont = "unknown"; longcont = ""; } }#if 0 /* Setup ref before shortening name so we have the full filename */ if (fileinfo->symlink) ref = fileinfo->symlink; else#endif 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); if (ref[0] == '/') sprintf(anchor, "file:%s", ref); else sprintf(anchor, "file:%s%s", dirname, ref); sprintf(buf, /* "<img src=\"internal:icon/%s\">" Not yet... --Jcid */ "%s<a href=\"%s\">%s</a> %s%10s %5d %-5s %s\n", S_ISDIR (SPtr->st_mode) ? ">" : " ", anchor, name,/* "<a href=\"%s\">%s</a>%s %s%10s %5d %-5s %s\n", anchor, name, S_ISDIR (SPtr->st_mode) ? "/" : " ",*/ dots+50-ndots, longcont, size, sizeunits, date); return buf;}/* * 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 char *File_dir2html(DilloDir *Ddir){ struct dirent *de; struct stat sb; char *name, *s; 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, ".") == 0) continue; /* skip "." */ 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 enries */ 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->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); s = File_info2html(&sb, name, Ddir->dirname, datebuf); g_free(name); ++(*index); return s;}/* * 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 g_print("Warning: Can't find <%s>\n", filename);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -