diff --git a/dpi/file.cc b/dpi/file.cc index 70ae7fe..57d62ee 100644 --- a/dpi/file.cc +++ b/dpi/file.cc @@ -38,6 +38,11 @@ #include "dpiutil.hh" #include "d_size.h" +#include +#include +#include +#include + /* * Debugging macros */ @@ -69,18 +74,20 @@ typedef enum { st_err } FileState; -typedef struct { - char *full_path; +struct FileInfo { + std::string full_path; const char *filename; off_t size; mode_t mode; time_t mtime; -} FileInfo; -typedef struct { - char *dirname; - Dlist *flist; /* List of files and subdirectories (for sorting) */ -} DilloDir; + std::strong_ordering operator <=> ( const FileInfo & ) const; +}; + +struct DilloDir { + std::string dirname; + std::vector< std::unique_ptr< FileInfo > > flist; /* List of files and subdirectories (for sorting) */ +}; typedef struct { 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. */ @@ -210,19 +228,17 @@ static DilloDir *File_dillodir_new(char *dirname) struct stat sb; struct dirent *de; DIR *dir; - DilloDir *Ddir; - FileInfo *finfo; - char *fname; + std::unique_ptr< FileInfo > fifo; + std::string fname; int dirname_len; if (!(dir = opendir(dirname))) return NULL; - Ddir = dNew(DilloDir, 1); - Ddir->dirname = dStrdup(dirname); - Ddir->flist = dList_new(512); + auto Ddir = std::make_unique< DilloDir >(); + Ddir->dirname = dirname; - dirname_len = strlen(Ddir->dirname); + dirname_len = Ddir->dirname.size(); /* Scan every name and sort them */ while ((de = readdir(dir)) != 0) { @@ -238,28 +254,28 @@ static DilloDir *File_dillodir_new(char *dirname) continue; } - fname = dStrconcat(Ddir->dirname, de->d_name, NULL); - if (stat(fname, &sb) == -1) { - dFree(fname); + fname = Ddir->dirname + de->d_name; + if (stat(fname.c_str(), &sb) == -1) { continue; /* ignore files we can't stat */ } - finfo = dNew(FileInfo, 1); + auto finfo = std::make_unique< FileInfo >(); finfo->full_path = fname; - finfo->filename = fname + dirname_len; + finfo->filename = finfo->full_path.c_str() + dirname_len; finfo->size = sb.st_size; finfo->mode = sb.st_mode; finfo->mtime = sb.st_mtime; - dList_append(Ddir->flist, finfo); + Ddir->flist.push_back( std::move( finfo ) ); } closedir(dir); /* 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) { - int i; - 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); + delete 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)) { filecont = "Executable"; } else { - filecont = File_content_type(finfo->full_path); + filecont = File_content_type(finfo->full_path.c_str()); if (!filecont || !strcmp(filecont, "application/octet-stream")) filecont = "unknown"; } @@ -424,9 +427,9 @@ static void File_send_dir(ClientInfo *client) /* send HTTP header and HTML top part */ /* 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()); - Hdirname = Escape_html_str(Ddir->dirname); + Hdirname = Escape_html_str(Ddir->dirname.c_str()); a_Dpip_dsh_printf(client->sh, 0, "HTTP/1.1 200 OK\r\n" @@ -445,13 +448,13 @@ static void File_send_dir(ClientInfo *client) } /* Output the parent directory */ - File_print_parent_dir(client, Ddir->dirname); + File_print_parent_dir(client, Ddir->dirname.c_str()); /* HTML style toggle */ a_Dpip_dsh_write_str(client->sh, 0, "  %\n"); - if (dList_length(Ddir->flist)) { + if (not Ddir->flist.empty()) { if (client->old_style) { a_Dpip_dsh_write_str(client->sh, 0, "\n\n"); } else { @@ -473,13 +476,13 @@ static void File_send_dir(ClientInfo *client) } else if (client->state == st_http) { /* send directories as HTML contents */ - for (n = 0; n < dList_length(Ddir->flist); ++n) { - File_info2html(client, reinterpret_cast< FileInfo * >( dList_nth_data(Ddir->flist,n) ), n+1); + for (n = 0; n < Ddir->flist.size(); ++n) { + File_info2html(client, Ddir->flist.at( n ).get(), n+1); } if (client->old_style) { a_Dpip_dsh_write_str(client->sh, 0, "\n"); - } else if (dList_length(Ddir->flist)) { + } else if (not Ddir->flist.empty()) { a_Dpip_dsh_write_str(client->sh, 0, "\n"); }