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 @@
Conferences
+
+ File Areas
+
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, "\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, "Filename | Size | Description |
\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, "%s | ", 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, "%d%c | ", 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, "
\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, "\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;