Some file plugin structures RAII'ed.

This commit is contained in:
2025-04-27 11:41:19 -04:00
parent c64846c02c
commit 0c350a85c1

View File

@ -38,6 +38,11 @@
#include "dpiutil.hh" #include "dpiutil.hh"
#include "d_size.h" #include "d_size.h"
#include <memory>
#include <string>
#include <vector>
#include <compare>
/* /*
* Debugging macros * Debugging macros
*/ */
@ -69,18 +74,20 @@ typedef enum {
st_err st_err
} FileState; } FileState;
typedef struct { struct FileInfo {
char *full_path; std::string full_path;
const char *filename; const char *filename;
off_t size; off_t size;
mode_t mode; mode_t mode;
time_t mtime; time_t mtime;
} FileInfo;
typedef struct { std::strong_ordering operator <=> ( const FileInfo & ) const;
char *dirname; };
Dlist *flist; /* List of files and subdirectories (for sorting) */
} DilloDir; struct DilloDir {
std::string dirname;
std::vector< std::unique_ptr< FileInfo > > flist; /* List of files and subdirectories (for sorting) */
};
typedef struct { typedef struct {
Dsh *sh; Dsh *sh;
@ -202,6 +209,17 @@ static int File_comp(const FileInfo *f1, const FileInfo *f2)
} }
} }
std::strong_ordering
FileInfo::operator <=> ( const FileInfo &rhs ) const
{
const auto &lhs= *this;
const auto result= File_comp( &lhs, &rhs );
if( result < 0 ) return std::strong_ordering::less;
if( result > 0 ) return std::strong_ordering::greater;
return std::strong_ordering::equal;
}
/* /*
* Allocate a DilloDir structure, set safe values in it and sort the entries. * Allocate a DilloDir structure, set safe values in it and sort the entries.
*/ */
@ -210,19 +228,17 @@ static DilloDir *File_dillodir_new(char *dirname)
struct stat sb; struct stat sb;
struct dirent *de; struct dirent *de;
DIR *dir; DIR *dir;
DilloDir *Ddir; std::unique_ptr< FileInfo > fifo;
FileInfo *finfo; std::string fname;
char *fname;
int dirname_len; int dirname_len;
if (!(dir = opendir(dirname))) if (!(dir = opendir(dirname)))
return NULL; return NULL;
Ddir = dNew(DilloDir, 1); auto Ddir = std::make_unique< DilloDir >();
Ddir->dirname = dStrdup(dirname); Ddir->dirname = dirname;
Ddir->flist = dList_new(512);
dirname_len = strlen(Ddir->dirname); dirname_len = Ddir->dirname.size();
/* Scan every name and sort them */ /* Scan every name and sort them */
while ((de = readdir(dir)) != 0) { while ((de = readdir(dir)) != 0) {
@ -238,28 +254,28 @@ static DilloDir *File_dillodir_new(char *dirname)
continue; continue;
} }
fname = dStrconcat(Ddir->dirname, de->d_name, NULL); fname = Ddir->dirname + de->d_name;
if (stat(fname, &sb) == -1) { if (stat(fname.c_str(), &sb) == -1) {
dFree(fname);
continue; /* ignore files we can't stat */ continue; /* ignore files we can't stat */
} }
finfo = dNew(FileInfo, 1); auto finfo = std::make_unique< FileInfo >();
finfo->full_path = fname; finfo->full_path = fname;
finfo->filename = fname + dirname_len; finfo->filename = finfo->full_path.c_str() + dirname_len;
finfo->size = sb.st_size; finfo->size = sb.st_size;
finfo->mode = sb.st_mode; finfo->mode = sb.st_mode;
finfo->mtime = sb.st_mtime; finfo->mtime = sb.st_mtime;
dList_append(Ddir->flist, finfo); Ddir->flist.push_back( std::move( finfo ) );
} }
closedir(dir); closedir(dir);
/* sort the entries */ /* sort the entries */
dList_sort(Ddir->flist, (dCompareFunc)File_comp); std::sort( begin( Ddir->flist ), end( Ddir->flist ),
[]( const auto &lhs, const auto &rhs ) { return *lhs < *rhs; } );
return Ddir; return Ddir.release();
} }
/* /*
@ -267,20 +283,7 @@ static DilloDir *File_dillodir_new(char *dirname)
*/ */
static void File_dillodir_free(DilloDir *Ddir) static void File_dillodir_free(DilloDir *Ddir)
{ {
int i; delete Ddir;
FileInfo *finfo;
dReturn_if (Ddir == NULL);
for (i = 0; i < dList_length(Ddir->flist); ++i) {
finfo = reinterpret_cast< FileInfo * >( dList_nth_data(Ddir->flist, i) );
dFree(finfo->full_path);
dFree(finfo);
}
dList_free(Ddir->flist);
dFree(Ddir->dirname);
dFree(Ddir);
} }
/* /*
@ -359,7 +362,7 @@ static void File_info2html(ClientInfo *client, FileInfo *finfo, int n)
} else if (finfo->mode & (S_IXUSR | S_IXGRP | S_IXOTH)) { } else if (finfo->mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
filecont = "Executable"; filecont = "Executable";
} else { } else {
filecont = File_content_type(finfo->full_path); filecont = File_content_type(finfo->full_path.c_str());
if (!filecont || !strcmp(filecont, "application/octet-stream")) if (!filecont || !strcmp(filecont, "application/octet-stream"))
filecont = "unknown"; filecont = "unknown";
} }
@ -424,9 +427,9 @@ static void File_send_dir(ClientInfo *client)
/* send HTTP header and HTML top part */ /* send HTTP header and HTML top part */
/* Send page title */ /* Send page title */
auto Udirname = Escape_uri_str(Ddir->dirname, NULL); auto Udirname = Escape_uri_str(Ddir->dirname.c_str(), NULL);
HUdirname = Escape_html_str(Udirname.c_str()); HUdirname = Escape_html_str(Udirname.c_str());
Hdirname = Escape_html_str(Ddir->dirname); Hdirname = Escape_html_str(Ddir->dirname.c_str());
a_Dpip_dsh_printf(client->sh, 0, a_Dpip_dsh_printf(client->sh, 0,
"HTTP/1.1 200 OK\r\n" "HTTP/1.1 200 OK\r\n"
@ -445,13 +448,13 @@ static void File_send_dir(ClientInfo *client)
} }
/* Output the parent directory */ /* Output the parent directory */
File_print_parent_dir(client, Ddir->dirname); File_print_parent_dir(client, Ddir->dirname.c_str());
/* HTML style toggle */ /* HTML style toggle */
a_Dpip_dsh_write_str(client->sh, 0, a_Dpip_dsh_write_str(client->sh, 0,
"&nbsp;&nbsp;<a href='dpi:/file/toggle'>%</a>\n"); "&nbsp;&nbsp;<a href='dpi:/file/toggle'>%</a>\n");
if (dList_length(Ddir->flist)) { if (not Ddir->flist.empty()) {
if (client->old_style) { if (client->old_style) {
a_Dpip_dsh_write_str(client->sh, 0, "\n\n"); a_Dpip_dsh_write_str(client->sh, 0, "\n\n");
} else { } else {
@ -473,13 +476,13 @@ static void File_send_dir(ClientInfo *client)
} else if (client->state == st_http) { } else if (client->state == st_http) {
/* send directories as HTML contents */ /* send directories as HTML contents */
for (n = 0; n < dList_length(Ddir->flist); ++n) { for (n = 0; n < Ddir->flist.size(); ++n) {
File_info2html(client, reinterpret_cast< FileInfo * >( dList_nth_data(Ddir->flist,n) ), n+1); File_info2html(client, Ddir->flist.at( n ).get(), n+1);
} }
if (client->old_style) { if (client->old_style) {
a_Dpip_dsh_write_str(client->sh, 0, "</pre>\n"); a_Dpip_dsh_write_str(client->sh, 0, "</pre>\n");
} else if (dList_length(Ddir->flist)) { } else if (not Ddir->flist.empty()) {
a_Dpip_dsh_write_str(client->sh, 0, "</table>\n"); a_Dpip_dsh_write_str(client->sh, 0, "</table>\n");
} }