web file bases

This commit is contained in:
Andrew Pamment 2018-02-15 14:43:37 +10:00
parent 7b7baa0c59
commit 15ca5a41dc
9 changed files with 399 additions and 3 deletions

View File

@ -74,6 +74,9 @@
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="@@WWW_URL@@msgs/">Conferences</a> <a class="nav-link" href="@@WWW_URL@@msgs/">Conferences</a>
</li> </li>
<li class="nav-item">
<a class="nav-link" href="@@WWW_URL@@files/areas/">File Areas</a>
</li>
</ul> </ul>
</div> </div>
</div> </div>

View File

@ -363,4 +363,40 @@ textarea {
padding: 0px; padding: 0px;
max-width: 100%; max-width: 100%;
overflow-x: none; 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;
} }

View File

@ -343,3 +343,39 @@
line-height: 1; line-height: 1;
padding: 5px; 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;
}

View File

@ -889,7 +889,7 @@ tryagain:
gUser = user; gUser = user;
for (i=1;i<=conf.nodes;i++) { 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) { if (stat(buffer, &s) == 0) {
nodefile = fopen(buffer, "r"); nodefile = fopen(buffer, "r");
if (!nodefile) { if (!nodefile) {
@ -913,7 +913,7 @@ tryagain:
s_printf(get_string(24), gUser->loginname); s_printf(get_string(24), gUser->loginname);
s_getc(); s_getc();
for (i=1;i<=conf.nodes;i++) { 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) { if (stat(buffer, &s) == 0) {
nodefile = fopen(buffer, "r"); nodefile = fopen(buffer, "r");
if (!nodefile) { if (!nodefile) {

View File

@ -93,6 +93,7 @@ struct file_directory {
char *name; char *name;
char *path; char *path;
int sec_level; int sec_level;
int display_on_web;
int file_sub_count; int file_sub_count;
struct file_sub **file_subs; struct file_sub **file_subs;
}; };
@ -367,6 +368,10 @@ extern char *www_last10();
extern void www_expire_old_links(); extern void www_expire_old_links();
extern char *www_create_link(int dir, int sub, int fid); extern char *www_create_link(int dir, int sub, int fid);
extern char *www_decode_hash(char *hash); 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 #endif
extern int menu_system(char *menufile); extern int menu_system(char *menufile);

View File

@ -255,6 +255,12 @@ static int file_sub_handler(void* user, const char* section, const char* name,
if (strcasecmp(section, "main") == 0) { if (strcasecmp(section, "main") == 0) {
if (strcasecmp(name, "visible sec level") == 0) { if (strcasecmp(name, "visible sec level") == 0) {
fd->sec_level = atoi(value); 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 { } else {
// check if it's partially filled in // 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]->name = strdup(name);
conf->file_directories[conf->file_directory_count]->path = strdup(value); 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]->file_sub_count = 0;
conf->file_directories[conf->file_directory_count]->display_on_web = 0;
conf->file_directory_count++; conf->file_directory_count++;
} else if (strcasecmp(section, "text files") == 0) { } else if (strcasecmp(section, "text files") == 0) {
if (conf->text_file_count == 0) { if (conf->text_file_count == 0) {

View File

@ -420,6 +420,9 @@ int www_handler(void * cls, struct MHD_Connection * connection, const char * url
char *filename; char *filename;
int email; int email;
char *endptr; char *endptr;
int file_dir;
int file_sub;
char *filen;
// char *static_buffer; // char *static_buffer;
page = NULL; page = NULL;
@ -853,7 +856,91 @@ int www_handler(void * cls, struct MHD_Connection * connection, const char * url
free(footer); free(footer);
return MHD_YES; 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) { } else if (strncasecmp(url, "/files/", 7) == 0) {
filename = www_decode_hash(&url[7]); filename = www_decode_hash(&url[7]);
if (filename != NULL) { if (filename != NULL) {

View File

@ -9,6 +9,7 @@
extern struct bbs_config conf; extern struct bbs_config conf;
extern struct user_record *gUser; extern struct user_record *gUser;
extern char * aha(char *input);
void www_expire_old_links() { void www_expire_old_links() {
char buffer[PATH_MAX]; char buffer[PATH_MAX];
@ -228,5 +229,226 @@ char *www_create_link(int dir, int sub, int fid) {
return ret; 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, "<div class=\"content-header\"><h2>Files: %s - %s</h2></div>\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, "<table class=\"fileentry\"><thead><tr><td>Filename</td><td>Size</td><td>Description</td></tr></thead><tbody>\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, "<tr><td class=\"filename\"><a href=\"%sfiles/areas/%d/%d/%s\">%s</a></td>", 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, "<td class=\"filesize\">%d%c</td>", 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<strlen(description);i++) {
if (description[i] == '\n') {
description[i] = '\r';
}
}
snprintf(buffer, 4096, "<td class=\"filedesc\">");
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, "</td></tr>\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, "</tbody></table>\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, "<div class=\"content-header\"><h2>File Directories</h2></div>\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;i<conf.file_directory_count;i++) {
if (conf.file_directories[i]->display_on_web) {
sprintf(buffer, "<div class=\"conference-list-item\">%s</div>\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;j<conf.file_directories[i]->file_sub_count;j++) {
sprintf(buffer, "<div class=\"area-list-item\"><a href=\"%sfiles/areas/%d/%d/\">%s</a></div>\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 #endif

View File

@ -15,7 +15,7 @@ extern struct bbs_config conf;
static char *www_wordwrap(char *content, int cutoff); static char *www_wordwrap(char *content, int cutoff);
static char *www_sanitize(char *inp) { char *www_sanitize(char *inp) {
int i; int i;
char *result; char *result;
int len = 0; int len = 0;