/**************************************************************************** * apps/netutils/webserver/httpd_dirlist.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. The * ASF licenses this file to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the * License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. * ****************************************************************************/ /**************************************************************************** * Included Files ****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "netutils/httpd.h" #include "httpd.h" /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ #ifdef CONFIG_ARCH_BOARD_CUSTOM # ifndef CONFIG_ARCH_BOARD_CUSTOM_NAME # define BOARD_NAME g_unknown # else # define BOARD_NAME CONFIG_ARCH_BOARD_CUSTOM_NAME # endif #else # ifndef CONFIG_ARCH_BOARD # define BOARD_NAME g_unknown # else # define BOARD_NAME CONFIG_ARCH_BOARD # endif #endif #define BUF_SIZE 1024 #define HEADER \ "\n" \ "\n" \ "\n" #define TITLE \ " Index of /%s\n" \ "\n" \ "\n" \ "

Index of /%s

\n" \ "\n" #define TABLE \ " \n" \ " \n" #define PARENT \ " \n" \ " " \ "\n" #define ENTRY \ " \n" \ " " \ "\n" #define FOOTER \ " \n" \ "
NameLast modified" \ "Size

../ - -  
%s%s%4d-%02d-%02d %02d:%02d %s  

\n" \ "
uIP web server (%s %s %s %s %s)
\n" \ "\n" \ "\n" /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** * Name: httpd_is_file ****************************************************************************/ bool httpd_is_file(FAR const char *filename) { char *path; int fd; bool ret = true; path = malloc(CONFIG_NAME_MAX); ASSERT(path); snprintf(path, CONFIG_NAME_MAX, "%s/%s", CONFIG_NETUTILS_HTTPD_PATH, filename); fd = open(path, O_DIRECTORY); if (-1 != fd) { close(fd); ret = false; } free(path); return ret; } /**************************************************************************** * Name: httpd_dirlist ****************************************************************************/ ssize_t httpd_dirlist(int outfd, FAR struct httpd_fs_file *file) { struct dirent *dent; struct utsname info; struct stat buf; struct tm tm; ssize_t total; ssize_t ret; char size[16]; char *path; char *tmp; DIR *dir; total = 0; tmp = (char *)calloc(1, BUF_SIZE); ASSERT(tmp); /* exclude document root path */ path = file->path + sizeof(CONFIG_NETUTILS_HTTPD_PATH); /* compose hdr/title/path/table and write them */ if ('\0' == *path) { snprintf(tmp, BUF_SIZE, HEADER TITLE TABLE, "", ""); } else { snprintf(tmp, BUF_SIZE, HEADER TITLE TABLE PARENT, path, path); } ret = write(outfd, tmp, strlen(tmp)); if (-1 == ret) { goto errout; } total += ret; dir = opendir(file->path); if (NULL == dir) { goto errout_with_hdr; } while (true) { dent = readdir(dir); if (NULL == dent) { break; } ret = asprintf(&path, "%s/%s", file->path, dent->d_name); ASSERT(ret > 0 && path); /* call stat() to obtain modified time and size */ ret = stat(path, &buf); ASSERT(0 == ret); free(path); localtime_r(&buf.st_mtime, &tm); /* compose an entry name for directory or file */ if (dent->d_type == DTYPE_DIRECTORY) { snprintf(tmp, BUF_SIZE, ENTRY, dent->d_name, "/", dent->d_name, "/", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, "-" ); } else { snprintf(size, sizeof(size), "%jd", (uintmax_t)buf.st_size); snprintf(tmp, BUF_SIZE, ENTRY, dent->d_name, "", dent->d_name, "", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, size ); } ret = write(outfd, tmp, strlen(tmp)); if (-1 == ret) { break; } total += ret; } closedir(dir); errout_with_hdr: memset(&info, 0, sizeof(info)); uname(&info); snprintf(tmp, BUF_SIZE, FOOTER, info.sysname, info.release, info.version, info.machine, BOARD_NAME); ret = write(outfd, tmp, strlen(tmp)); if (-1 != ret) { total += ret; } ret = total; errout: free(tmp); return ret; }