From 15ca5a41dcd73ddc01b71e91eeaad9578a4bc869 Mon Sep 17 00:00:00 2001 From: Andrew Pamment Date: Thu, 15 Feb 2018 14:43:37 +1000 Subject: [PATCH] web file bases --- dist/www-bootstrap/header.tpl | 3 + dist/www-bootstrap/static/style-mobile.css | 36 ++++ dist/www-bootstrap/static/style.css | 36 ++++ src/bbs.c | 4 +- src/bbs.h | 5 + src/main.c | 7 + src/www.c | 87 ++++++++ src/www_files.c | 222 +++++++++++++++++++++ src/www_msgs.c | 2 +- 9 files changed, 399 insertions(+), 3 deletions(-) diff --git a/dist/www-bootstrap/header.tpl b/dist/www-bootstrap/header.tpl index a2db158..7ef68c6 100644 --- a/dist/www-bootstrap/header.tpl +++ b/dist/www-bootstrap/header.tpl @@ -74,6 +74,9 @@ + diff --git a/dist/www-bootstrap/static/style-mobile.css b/dist/www-bootstrap/static/style-mobile.css index c2388a1..19e560a 100644 --- a/dist/www-bootstrap/static/style-mobile.css +++ b/dist/www-bootstrap/static/style-mobile.css @@ -363,4 +363,40 @@ textarea { padding: 0px; max-width: 100%; overflow-x: none; +} + +.filedesc { + background-color: black; + color: gray; + font-family: 'pxplus_ibm_vga8regular'; + line-height: 1; + padding: 5px; +} + +table { + width: 100%; + border-collapse: collapse; +} + +thead { + color: #eee; + background-color: #666666; +} + +thead th:nth-child(1) { + width: 5%; +} + +thead th:nth-child(2) { + width: 5%; +} + +thead th:nth-child(3) { + width: 90%; +} + +th, td { + vertical-align: top; + padding: 20px; + border-top: 1px solid #666; } \ No newline at end of file diff --git a/dist/www-bootstrap/static/style.css b/dist/www-bootstrap/static/style.css index 1b8ee14..24a9635 100644 --- a/dist/www-bootstrap/static/style.css +++ b/dist/www-bootstrap/static/style.css @@ -343,3 +343,39 @@ line-height: 1; padding: 5px; } + +.filedesc { + background-color: black; + color: gray; + font-family: 'pxplus_ibm_vga8regular'; + line-height: 1; + padding: 5px; +} + +table { + width: 100%; + border-collapse: collapse; +} + +thead { + color: #eee; + background-color: #666666; +} + +thead th:nth-child(1) { + width: 30%; +} + +thead th:nth-child(2) { + width: 10%; +} + +thead th:nth-child(3) { + width: 60%; +} + +th, td { + vertical-align: top; + padding: 20px; + border-top: 1px solid #666; +} \ No newline at end of file diff --git a/src/bbs.c b/src/bbs.c index f726944..317ca0b 100644 --- a/src/bbs.c +++ b/src/bbs.c @@ -889,7 +889,7 @@ tryagain: gUser = user; for (i=1;i<=conf.nodes;i++) { - sprintf(buffer, "%s/nodeinuse.%d", conf.bbs_path, i); + snprintf(buffer, PATH_MAX, "%s/nodeinuse.%d", conf.bbs_path, i); if (stat(buffer, &s) == 0) { nodefile = fopen(buffer, "r"); if (!nodefile) { @@ -913,7 +913,7 @@ tryagain: s_printf(get_string(24), gUser->loginname); s_getc(); for (i=1;i<=conf.nodes;i++) { - sprintf(buffer, "%s/nodeinuse.%d", conf.bbs_path, i); + snprintf(buffer, PATH_MAX, "%s/nodeinuse.%d", conf.bbs_path, i); if (stat(buffer, &s) == 0) { nodefile = fopen(buffer, "r"); if (!nodefile) { diff --git a/src/bbs.h b/src/bbs.h index 2771019..469c3ab 100644 --- a/src/bbs.h +++ b/src/bbs.h @@ -93,6 +93,7 @@ struct file_directory { char *name; char *path; int sec_level; + int display_on_web; int file_sub_count; struct file_sub **file_subs; }; @@ -367,6 +368,10 @@ extern char *www_last10(); extern void www_expire_old_links(); extern char *www_create_link(int dir, int sub, int fid); extern char *www_decode_hash(char *hash); +extern char *www_sanitize(char *inp); +extern char *www_files_display_listing(int dir, int sub); +extern char *www_files_areas(); +extern char *www_files_get_from_area(int dir, int sub, char *file); #endif extern int menu_system(char *menufile); diff --git a/src/main.c b/src/main.c index 4f28d71..d1de661 100644 --- a/src/main.c +++ b/src/main.c @@ -255,6 +255,12 @@ static int file_sub_handler(void* user, const char* section, const char* name, if (strcasecmp(section, "main") == 0) { if (strcasecmp(name, "visible sec level") == 0) { fd->sec_level = atoi(value); + } else if (strcasecmp(name, "visible on web") == 0) { + if (strcasecmp(value, "true") == 0) { + fd->display_on_web = 1; + } else { + fd->display_on_web = 0; + } } } else { // check if it's partially filled in @@ -566,6 +572,7 @@ static int handler(void* user, const char* section, const char* name, conf->file_directories[conf->file_directory_count]->name = strdup(name); conf->file_directories[conf->file_directory_count]->path = strdup(value); conf->file_directories[conf->file_directory_count]->file_sub_count = 0; + conf->file_directories[conf->file_directory_count]->display_on_web = 0; conf->file_directory_count++; } else if (strcasecmp(section, "text files") == 0) { if (conf->text_file_count == 0) { diff --git a/src/www.c b/src/www.c index 25ed557..783bc3f 100644 --- a/src/www.c +++ b/src/www.c @@ -420,6 +420,9 @@ int www_handler(void * cls, struct MHD_Connection * connection, const char * url char *filename; int email; char *endptr; + int file_dir; + int file_sub; + char *filen; // char *static_buffer; page = NULL; @@ -853,7 +856,91 @@ int www_handler(void * cls, struct MHD_Connection * connection, const char * url free(footer); return MHD_YES; } + } else if (strcasecmp(url, "/files/areas/") == 0 || strcasecmp(url, "/files/areas") == 0) { + page = www_files_areas(); + whole_page = (char *)malloc(strlen(header) + strlen(page) + strlen(footer) + 1); + sprintf(whole_page, "%s%s%s", header, page, footer); + } else if (strncasecmp(url, "/files/areas/", 13) == 0) { + file_dir = -1; + file_sub = -1; + filen = NULL; + url_copy = strdup(&url[13]); + + aptr = strtok(url_copy, "/"); + if (aptr != NULL) { + file_dir = strtol(aptr, &endptr, 10); + if (endptr == aptr) { + file_dir = -1; + } + aptr = strtok(NULL, "/"); + if (aptr != NULL) { + file_sub = strtol(aptr, &endptr, 10); + if (endptr == aptr) { + file_sub = -1; + } + aptr = strtok(NULL, "/"); + if (aptr != NULL) { + filen = strdup(aptr); + } + } + } + free(url_copy); + + if (file_dir != -1 && file_sub != -1 && filen == NULL) { + if (conf.file_directories[file_dir]->display_on_web) { + page = www_files_display_listing(file_dir, file_sub); + } + } else if (file_dir != -1 && file_sub != -1 && filen != NULL) { + if (conf.file_directories[file_dir]->display_on_web) { + // send file + filename = www_files_get_from_area(file_dir, file_sub, filen); + free(filen); + if (filename != NULL) { + if (stat(filename, &s) == 0 && S_ISREG(s.st_mode)) { + fno = open(filename, O_RDONLY); + if (fno != -1) { + response = MHD_create_response_from_fd(s.st_size, fno); + MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_TYPE, mime); + sprintf(buffer, "%ld", s.st_size); + MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_LENGTH, buffer); + + snprintf(buffer, PATH_MAX, "attachment; filename=\"%s\"", basename(filename)); + MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_DISPOSITION, buffer); + ret = MHD_queue_response (connection, MHD_HTTP_OK, response); + MHD_destroy_response (response); + free(header); + free(footer); + free(filename); + return ret; + } + } + free(filename); + } + if (www_404(header, footer, connection) != 0) { + free(header); + free(footer); + return MHD_NO; + } + free(header); + free(footer); + return MHD_YES; + } + free(filen); + } + if (page == NULL) { + if (www_403(header, footer, connection) != 0) { + free(header); + free(footer); + return MHD_NO; + } + free(header); + free(footer); + return MHD_YES; + } + whole_page = (char *)malloc(strlen(header) + strlen(page) + strlen(footer) + 1); + + sprintf(whole_page, "%s%s%s", header, page, footer); } else if (strncasecmp(url, "/files/", 7) == 0) { filename = www_decode_hash(&url[7]); if (filename != NULL) { diff --git a/src/www_files.c b/src/www_files.c index dd36d57..f14626a 100644 --- a/src/www_files.c +++ b/src/www_files.c @@ -9,6 +9,7 @@ extern struct bbs_config conf; extern struct user_record *gUser; +extern char * aha(char *input); void www_expire_old_links() { char buffer[PATH_MAX]; @@ -228,5 +229,226 @@ char *www_create_link(int dir, int sub, int fid) { return ret; } +char *www_files_display_listing(int dir, int sub) { + char *page; + int max_len; + int len; + char buffer[4096]; + char *sql = "select id, filename, description, size, dlcount, uploaddate from files where approved=1 ORDER BY filename"; + char *filename; + char c; + int size; + char *aha_out; + char *description; + sqlite3 *db; + sqlite3_stmt *res; + int rc; + int i; + + page = (char *)malloc(4096); + max_len = 4096; + len = 0; + memset(page, 0, 4096); + + snprintf(buffer, 4096, "

Files: %s - %s

\n", conf.file_directories[dir]->name, conf.file_directories[dir]->file_subs[sub]->name); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + snprintf(buffer, 4096, "%s/%s.sq3", conf.bbs_path, conf.file_directories[dir]->file_subs[sub]->database); + + rc = sqlite3_open(buffer, &db); + if (rc != SQLITE_OK) { + dolog_www("Cannot open database: %s", sqlite3_errmsg(db)); + free(page); + return NULL; + } + sqlite3_busy_timeout(db, 5000); + rc = sqlite3_prepare_v2(db, sql, -1, &res, 0); + if (rc != SQLITE_OK) { + sqlite3_close(db); + free(page); + return NULL; + } + snprintf(buffer, 4096, "\n"); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + while (sqlite3_step(res) == SQLITE_ROW) { + filename = strdup(sqlite3_column_text(res, 1)); + snprintf(buffer, 4096, "", conf.www_url, dir, sub, basename(filename), basename(filename)); + free(filename); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + size = sqlite3_column_int(res, 3); + + if (size > 1024 * 1024 * 1024) { + size = size / 1024 / 1024 / 1024; + c = 'G'; + } else if (size > 1024 * 1024) { + size = size / 1024 / 1024; + c = 'M'; + } else if (size > 1024) { + size = size / 1024; + c = 'K'; + } else { + c = 'b'; + } + + snprintf(buffer, 4096, "", size, c); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + description = www_sanitize((char *)sqlite3_column_text(res, 2)); + + for (i=0;i"); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + aha_out = aha(description); + + while (len + strlen(aha_out) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, aha_out); + len += strlen(aha_out); + + free(aha_out); + free(description); + + snprintf(buffer, 4096, "\n"); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + } + + snprintf(buffer, 4096, "
FilenameSizeDescription
%s%d%c
\n"); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + sqlite3_finalize(res); + sqlite3_close(db); + + return page; +} + +char *www_files_areas() { + char *page; + int max_len; + int len; + char buffer[4096]; + int i; + int j; + + page = (char *)malloc(4096); + max_len = 4096; + len = 0; + memset(page, 0, 4096); + + sprintf(buffer, "

File Directories

\n"); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + for (i=0;idisplay_on_web) { + sprintf(buffer, "
%s
\n", conf.file_directories[i]->name); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + for (j=0;jfile_sub_count;j++) { + sprintf(buffer, "\n", conf.www_url, i, j, conf.file_directories[i]->file_subs[j]->name); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + } + } + } + + return page; +} + +char *www_files_get_from_area(int dir, int sub, char *file) { + char *sql = "SELECT filename FROM files WHERE approved=1 AND filename LIKE ?"; + char *filenamelike; + sqlite3 *db; + sqlite3_stmt *res; + int rc; + char buffer[PATH_MAX]; + char *ret = NULL; + + filenamelike = (char *)malloc(strlen(file) + 3); + sprintf(filenamelike, "%%/%s", file); + + snprintf(buffer, PATH_MAX, "%s/%s.sq3", conf.bbs_path, conf.file_directories[dir]->file_subs[sub]->database); + + rc = sqlite3_open(buffer, &db); + if (rc != SQLITE_OK) { + dolog_www("Cannot open database: %s", sqlite3_errmsg(db)); + return NULL; + } + sqlite3_busy_timeout(db, 5000); + rc = sqlite3_prepare_v2(db, sql, -1, &res, 0); + if (rc != SQLITE_OK) { + sqlite3_close(db); + return NULL; + } + sqlite3_bind_text(res, 1, filenamelike, -1, 0); + + rc = sqlite3_step(res); + if (rc == SQLITE_ROW) { + ret = strdup(sqlite3_column_text(res, 0)); + + } + + free(filenamelike); + sqlite3_finalize(res); + sqlite3_close(db); + return ret; +} #endif diff --git a/src/www_msgs.c b/src/www_msgs.c index c1ecdcf..001ef62 100644 --- a/src/www_msgs.c +++ b/src/www_msgs.c @@ -15,7 +15,7 @@ extern struct bbs_config conf; static char *www_wordwrap(char *content, int cutoff); -static char *www_sanitize(char *inp) { +char *www_sanitize(char *inp) { int i; char *result; int len = 0;