📄 index_dir.c
字号:
/* * Copyright (C) 1997-2002 Jon Nelson <jnelson@boa.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 1, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *//* $Id: index_dir.c,v 1.32 2002/01/30 03:41:45 jnelson Exp $*/#include <stdio.h>#include <sys/stat.h>#include <limits.h> /* for PATH_MAX */#include <time.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include <fcntl.h>#include "compat.h"#define MAX_FILE_LENGTH MAXNAMLEN#define MAX_PATH_LENGTH PATH_MAX#define INT_TO_HEX(x) \ ((((x)-10)>=0)?('A'+((x)-10)):('0'+(x)))#include "escape.h"char *html_escape_string(char *inp, char *buf, const int len);char *http_escape_string(char *inp, char *buf, const int len);#if defined __GNUC__ && \ (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 0))#define CONST const#else#define CONST#endifint select_files(CONST struct dirent *d);int index_directory(char *dir, char *title);/* * Name: html_escape_string */char *html_escape_string(char *inp, char *dest, const int len){ int max; char *buf; unsigned char c; max = len * 5; if (dest == NULL && max) dest = malloc(sizeof (unsigned char) * (max + 1)); if (dest == NULL) return NULL; buf = dest; while ((c = *inp++)) { switch (c) { case '>': *dest++ = '&'; *dest++ = 'g'; *dest++ = 't'; *dest++ = ';'; break; case '<': *dest++ = '&'; *dest++ = 'l'; *dest++ = 't'; *dest++ = ';'; break; case '&': *dest++ = '&'; *dest++ = 'a'; *dest++ = 'm'; *dest++ = 'p'; *dest++ = ';'; break; default: *dest++ = c; } } *dest = '\0'; return buf;}/* * Name: escape_string * * Description: escapes the string inp. Uses variable buf. If buf is * NULL when the program starts, it will attempt to dynamically allocate * the space that it needs, otherwise it will assume that the user * has already allocated enough space for the variable buf, which * could be up to 3 times the size of inp. If the routine dynamically * allocates the space, the user is responsible for freeing it afterwords * Returns: NULL on error, pointer to string otherwise. */char *http_escape_string(char *inp, char *buf, const int len){ int max; char *index; unsigned char c; max = len * 3; if (buf == NULL && max) buf = malloc(sizeof (unsigned char) * (max + 1)); if (buf == NULL) return NULL; index = buf; while ((c = *inp++)) { if (needs_escape((unsigned int) c)) { *index++ = '%'; *index++ = INT_TO_HEX(c >> 4); *index++ = INT_TO_HEX(c & 15); } else *index++ = c; } *index = '\0'; return buf;}void send_error(int error){ char *the_error; switch (error) { case 1: the_error = "Not enough arguments were passed to the indexer."; break; case 2: the_error = "The Directory Sorter ran out of Memory"; break; case 3: the_error = "The was a problem changing to the appropriate directory."; break; case 4: the_error = "There was an error escaping a string."; case 5: the_error = "Too many arguments were passed to the indexer."; break; case 6: the_error = "No files in this directory."; break; default: the_error = "An unknown error occurred producing the directory."; break; } printf("<html>\n<head>\n<title>\n%s\n</title>\n" "<body>\n%s\n</body>\n</html>\n", the_error, the_error);}int select_files(CONST struct dirent *dirbuf){ if (dirbuf->d_name[0] == '.') return 0; else return 1;}/* * Name: index_directory * Description: Called from get_dir_mapping if a directory html * has to be generated on the fly * If no_slash is true, prepend slashes to hrefs * returns -1 for problem, else 0 */int index_directory(char *dir, char *title){ struct dirent *dirbuf; int numdir; struct dirent **array; struct stat statbuf; char http_filename[MAX_FILE_LENGTH * 3]; char html_filename[MAX_FILE_LENGTH * 4]; int i; if (chdir(dir) == -1) { send_error(3); return -1; } numdir = scandir(".", &array, select_files, alphasort); if (numdir == -1) { send_error(2); return -1; } else if (numdir == -2) { send_error(6); return -1; } printf("<html>\n" "<head>\n<title>Index of %s</title>\n</head>\n\n" "<body bgcolor=\"#ffffff\">\n" "<H2>Index of %s</H2>\n" "<table>\n%s", title, title, (strcmp(title, "/") == 0 ? "" : "<tr><td colspan=3><h3>Directories</h3></td></tr>" "<tr><td colspan=3><a href=\"../\">Parent Directory</a></td></tr>\n")); for (i = 0; i < numdir; ++i) { dirbuf = array[i]; if (stat(dirbuf->d_name, &statbuf) == -1) continue; if (!S_ISDIR(statbuf.st_mode)) continue; if (html_escape_string(dirbuf->d_name, html_filename, NAMLEN(dirbuf)) == NULL) { send_error(4); return -1; } if (http_escape_string(dirbuf->d_name, http_filename, NAMLEN(dirbuf)) == NULL) { send_error(4); return -1; } printf("<tr>" "<td width=\"40%%\"><a href=\"%s/\">%s/</a></td>" "<td align=right>%s</td>" "<td align=right>%ld bytes</td>" "</tr>\n", http_filename, html_filename, ctime(&statbuf.st_mtime), (long) statbuf.st_size); } printf ("<tr><td colspan=3> </td></tr>\n<tr><td colspan=3><h3>Files</h3></td></tr>\n"); for (i = 0; i < numdir; ++i) { int len; dirbuf = array[i]; if (stat(dirbuf->d_name, &statbuf) == -1) continue; if (S_ISDIR(statbuf.st_mode)) continue; if (html_escape_string(dirbuf->d_name, html_filename, NAMLEN(dirbuf)) == NULL) { send_error(4); return -1; } if (http_escape_string(dirbuf->d_name, http_filename, NAMLEN(dirbuf)) == NULL) { send_error(4); return -1; } len = strlen(http_filename);#ifdef GUNZIP if (len > 3 && !memcmp(http_filename + len - 3, ".gz", 3)) { http_filename[len - 3] = '\0'; html_filename[strlen(html_filename) - 3] = '\0'; printf("<tr>" "<td width=\"40%%\"><a href=\"%s\">%s</a> " "<a href=\"%s.gz\">(.gz)</a></td>" "<td align=right>%s</td>" "<td align=right>%ld bytes</td>" "</tr>\n", http_filename, html_filename, http_filename, ctime(&statbuf.st_mtime), (long) statbuf.st_size); } else {#endif printf("<tr>" "<td width=\"40%%\"><a href=\"%s\">%s</a></td>" "<td align=right>%s</td>" "<td align=right>%ld bytes</td>" "</tr>\n", http_filename, html_filename, ctime(&statbuf.st_mtime), (long) statbuf.st_size);#ifdef GUNZIP }#endif } /* hey -- even though this is a one-shot deal, we should * still free memory we ought to free * You never know -- this code might get used elsewhere! */ for (i = 0; i < numdir; ++i) { free(array[i]); array[i] = NULL; } free(array); array = NULL; return 0; /* success */}int main(int argc, char *argv[]){ time_t timep; struct tm *timeptr; char *now; if (argc < 3) { send_error(1); return -1; } else if (argc > 3) { send_error(5); return -1; } build_needs_escape(); if (argv[2] == NULL) index_directory(argv[1], argv[1]); else index_directory(argv[1], argv[2]); time(&timep);#ifdef USE_LOCALTIME timeptr = localtime(&timep);#else timeptr = gmtime(&timep);#endif now = strdup(asctime(timeptr)); now[strlen(now) - 1] = '\0';#ifdef USE_LOCALTIME printf("</table>\n<hr noshade>\nIndex generated %s %s\n" "<!-- This program is part of the Boa Webserver Copyright (C) 1991-2002 http://www.boa.org -->\n" "</body>\n</html>\n", now, TIMEZONE(timeptr));#else printf("</table>\n<hr noshade>\nIndex generated %s UTC\n" "<!-- This program is part of the Boa Webserver Copyright (C) 1991-2002 http://www.boa.org -->\n" "</body>\n</html>\n", now);#endif return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -