Merge branch 'master' of git.magickabbs.com:/home/andrew/repositories/MagickaBBS
This commit is contained in:
commit
e32addbe59
377
src/www_files.c
377
src/www_files.c
@ -11,59 +11,64 @@ extern struct bbs_config conf;
|
||||
extern struct user_record *gUser;
|
||||
extern char *aha(char *input);
|
||||
|
||||
static int digit2nibble(int digit) {
|
||||
static const char *const hex = "0123456789abcdef";
|
||||
static const char *const Hex = "0123456789ABCDEF";
|
||||
|
||||
char *p;
|
||||
p = strchr(hex, digit);
|
||||
if (p != NULL)
|
||||
return p - hex;
|
||||
p = strchr(Hex, digit);
|
||||
if (p != NULL)
|
||||
return p - Hex;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static char *www_decode(char *clean_url) {
|
||||
char *url = (char *)malloz(strlen(clean_url) + 1);
|
||||
int i;
|
||||
int j = 0;
|
||||
unsigned char c;
|
||||
if (clean_url == NULL) {
|
||||
free(url);
|
||||
stralloc url = EMPTY_STRALLOC;
|
||||
|
||||
assert(clean_url != NULL);
|
||||
for (char *s = clean_url; *s != '\0'; ++s) {
|
||||
if (*s == '+')
|
||||
stralloc_append1(&url, ' ');
|
||||
else if (*s != '%')
|
||||
stralloc_append1(&url, *s);
|
||||
else {
|
||||
int hn = 0, ln = 0, ch = 0;
|
||||
if (s[1] == '\0' || (hn = digit2nibble(s[1])) < 0) {
|
||||
free(url.s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < strlen(clean_url); i++) {
|
||||
if (clean_url[i] == '%') {
|
||||
c = clean_url[i + 1] * 16 + clean_url[i + 2];
|
||||
url[j++] = (char)c;
|
||||
url[j] = '\0';
|
||||
i += 2;
|
||||
} else {
|
||||
url[j++] = clean_url[i];
|
||||
url[j] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
static char *www_encode(char *url) {
|
||||
char *clean_url = (char *)malloz(strlen(url) * 3 + 1);
|
||||
int i;
|
||||
int j;
|
||||
|
||||
if (url == NULL) {
|
||||
free(clean_url);
|
||||
if (s[2] == '\0' || (ln = digit2nibble(s[2])) < 0) {
|
||||
free(url.s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
j = 0;
|
||||
memset(clean_url, 0, strlen(url) * 3);
|
||||
|
||||
for (i = 0; i < strlen(url); i++) {
|
||||
if (isalnum(url[i]) || url[i] == '~' || url[i] == '.' || url[i] == '_') {
|
||||
sprintf(&clean_url[j], "%c", url[i]);
|
||||
j++;
|
||||
} else {
|
||||
sprintf(&clean_url[j], "%%%02X", url[i]);
|
||||
j += 3;
|
||||
stralloc_append1(&url, hn * 16 + ln);
|
||||
}
|
||||
}
|
||||
stralloc_0(&url);
|
||||
|
||||
return clean_url;
|
||||
return url.s;
|
||||
}
|
||||
|
||||
static void www_encode(stralloc *clean, char *url) {
|
||||
assert(clean != NULL);
|
||||
assert(url != NULL);
|
||||
for (char *s = url; *s != '\0'; ++s) {
|
||||
if (isalnum(*s) || *s == '~' || *s == '.' || *s == '_')
|
||||
stralloc_append1(clean, *s);
|
||||
else if (*s == ' ')
|
||||
stralloc_append1(clean, '+');
|
||||
else {
|
||||
stralloc_append1(clean, '%');
|
||||
stralloc_cat_Byte(clean, *s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void www_expire_old_links() {
|
||||
char buffer[PATH_MAX];
|
||||
char pathbuf[PATH_MAX];
|
||||
sqlite3 *db;
|
||||
sqlite3_stmt *res;
|
||||
int rc;
|
||||
@ -71,9 +76,9 @@ void www_expire_old_links() {
|
||||
char *ret;
|
||||
time_t now = time(NULL);
|
||||
|
||||
snprintf(buffer, PATH_MAX, "%s/www_file_hashes.sq3", conf.bbs_path);
|
||||
snprintf(pathbuf, PATH_MAX, "%s/www_file_hashes.sq3", conf.bbs_path);
|
||||
|
||||
rc = sqlite3_open(buffer, &db);
|
||||
rc = sqlite3_open(pathbuf, &db);
|
||||
if (rc != SQLITE_OK) {
|
||||
dolog("Cannot open database: %s", sqlite3_errmsg(db));
|
||||
return;
|
||||
@ -91,14 +96,14 @@ void www_expire_old_links() {
|
||||
}
|
||||
|
||||
int www_check_hash_expired(char *hash) {
|
||||
char buffer[PATH_MAX];
|
||||
char pathbuf[PATH_MAX];
|
||||
sqlite3 *db;
|
||||
sqlite3_stmt *res;
|
||||
int rc;
|
||||
time_t now = time(NULL);
|
||||
char sql[] = "select id from wwwhash where hash = ? and expiry > ?";
|
||||
snprintf(buffer, PATH_MAX, "%s/www_file_hashes.sq3", conf.bbs_path);
|
||||
rc = sqlite3_open(buffer, &db);
|
||||
snprintf(pathbuf, PATH_MAX, "%s/www_file_hashes.sq3", conf.bbs_path);
|
||||
rc = sqlite3_open(pathbuf, &db);
|
||||
if (rc != SQLITE_OK) {
|
||||
return 1;
|
||||
}
|
||||
@ -123,7 +128,7 @@ int www_check_hash_expired(char *hash) {
|
||||
}
|
||||
|
||||
void www_add_hash_to_db(char *hash, time_t expiry) {
|
||||
char buffer[PATH_MAX];
|
||||
char pathbuf[PATH_MAX];
|
||||
sqlite3 *db;
|
||||
sqlite3_stmt *res;
|
||||
int rc;
|
||||
@ -135,9 +140,9 @@ void www_add_hash_to_db(char *hash, time_t expiry) {
|
||||
char *ret;
|
||||
char *err_msg = 0;
|
||||
|
||||
snprintf(buffer, PATH_MAX, "%s/www_file_hashes.sq3", conf.bbs_path);
|
||||
snprintf(pathbuf, PATH_MAX, "%s/www_file_hashes.sq3", conf.bbs_path);
|
||||
|
||||
rc = sqlite3_open(buffer, &db);
|
||||
rc = sqlite3_open(pathbuf, &db);
|
||||
if (rc != SQLITE_OK) {
|
||||
return;
|
||||
}
|
||||
@ -195,7 +200,7 @@ char *www_decode_hash(char *hash) {
|
||||
unsigned long long numbers[4];
|
||||
int dir, sub, fid, uid;
|
||||
hashids_t *hashids = hashids_init(conf.bbs_name);
|
||||
char buffer[PATH_MAX];
|
||||
char pathbuf[PATH_MAX];
|
||||
sqlite3 *db;
|
||||
sqlite3_stmt *res;
|
||||
int rc;
|
||||
@ -222,8 +227,8 @@ char *www_decode_hash(char *hash) {
|
||||
}
|
||||
|
||||
// get filename from database
|
||||
snprintf(buffer, PATH_MAX, "%s/%s.sq3", conf.bbs_path, conf.file_directories[dir]->file_subs[sub]->database);
|
||||
rc = sqlite3_open(buffer, &db);
|
||||
snprintf(pathbuf, PATH_MAX, "%s/%s.sq3", conf.bbs_path, conf.file_directories[dir]->file_subs[sub]->database);
|
||||
rc = sqlite3_open(pathbuf, &db);
|
||||
if (rc != SQLITE_OK) {
|
||||
return NULL;
|
||||
}
|
||||
@ -280,10 +285,8 @@ 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];
|
||||
stralloc page = EMPTY_STRALLOC;
|
||||
char pathbuf[PATH_MAX];
|
||||
char *sql = "select id, filename, description, size, dlcount, uploaddate from files where approved=1 ORDER BY filename";
|
||||
char *filename;
|
||||
char c;
|
||||
@ -296,178 +299,118 @@ char *www_files_display_listing(int dir, int sub) {
|
||||
int i;
|
||||
char *clean_url;
|
||||
|
||||
page = (char *)malloz(4096);
|
||||
max_len = 4096;
|
||||
len = 0;
|
||||
stralloc_copys(&page, "<div class=\"content-header\"><h2>Files: ");
|
||||
stralloc_cats(&page, conf.file_directories[dir]->name);
|
||||
stralloc_cats(&page, " - ");
|
||||
stralloc_cats(&page, conf.file_directories[dir]->file_subs[sub]->name);
|
||||
stralloc_cats(&page, "</h2></div>\n");
|
||||
|
||||
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);
|
||||
snprintf(pathbuf, sizeof pathbuf, "%s/%s.sq3",
|
||||
conf.bbs_path, conf.file_directories[dir]->file_subs[sub]->database);
|
||||
rc = sqlite3_open(pathbuf, &db);
|
||||
if (rc != SQLITE_OK) {
|
||||
free(page);
|
||||
free(page.s);
|
||||
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);
|
||||
free(page.s);
|
||||
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);
|
||||
|
||||
stralloc_cats(&page, "<table class=\"fileentry\"><thead><tr><td>Filename</td><td>Size</td><td>Description</td></tr></thead><tbody>\n");
|
||||
while (sqlite3_step(res) == SQLITE_ROW) {
|
||||
filename = strdup(sqlite3_column_text(res, 1));
|
||||
clean_url = www_encode(basename(filename));
|
||||
snprintf(buffer, 4096, "<tr><td class=\"filename\"><a href=\"%sfiles/areas/%d/%d/%s\">%s</a></td>", conf.www_url, dir, sub, basename(clean_url), basename(filename));
|
||||
free(clean_url);
|
||||
free(filename);
|
||||
if (len + strlen(buffer) > max_len - 1) {
|
||||
max_len += 4096;
|
||||
page = (char *)realloc(page, max_len);
|
||||
}
|
||||
strcat(page, buffer);
|
||||
len += strlen(buffer);
|
||||
filename = strdup((char *)sqlite3_column_text(res, 1));
|
||||
char *base_filename = basename(filename);
|
||||
stralloc_cats(&page, "<tr><td class=\"filename\"><a href=\"");
|
||||
stralloc_cats(&page, conf.www_url);
|
||||
stralloc_cats(&page, "files/areas/");
|
||||
stralloc_cat_long(&page, dir);
|
||||
stralloc_append1(&page, '/');
|
||||
stralloc_cat_long(&page, sub);
|
||||
stralloc_append1(&page, '/');
|
||||
www_encode(&page, base_filename);
|
||||
stralloc_cats(&page, "\">");
|
||||
stralloc_cats(&page, base_filename);
|
||||
stralloc_cats(&page, "</a></td>");
|
||||
|
||||
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;
|
||||
stralloc_cats(&page, "<td class=\"filesize\">");
|
||||
int c = 'b';
|
||||
if (size > 1024) {
|
||||
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);
|
||||
if (size > 1024) {
|
||||
size /= 1024;
|
||||
c = 'M';
|
||||
}
|
||||
strcat(page, buffer);
|
||||
len += strlen(buffer);
|
||||
if (size > 1024) {
|
||||
size /= 1024;
|
||||
c = 'G';
|
||||
}
|
||||
stralloc_cat_long(&page, size);
|
||||
stralloc_append1(&page, c);
|
||||
stralloc_cats(&page, "</td>");
|
||||
|
||||
stralloc_cats(&page, "<td class=\"filedesc\">");
|
||||
description = strdup((char *)sqlite3_column_text(res, 2));
|
||||
|
||||
for (i = 0; i < strlen(description); i++) {
|
||||
if (description[i] == '\n') {
|
||||
description[i] = '\r';
|
||||
for (char *p = description; *p != '\0'; ++p) {
|
||||
if (*p == '\n')
|
||||
*p = '\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);
|
||||
|
||||
stralloc_cats(&page, aha_out);
|
||||
free(aha_out);
|
||||
free(description);
|
||||
free(filename);
|
||||
|
||||
snprintf(buffer, 4096, "</td></tr>\n");
|
||||
if (len + strlen(buffer) > max_len - 1) {
|
||||
max_len += 4096;
|
||||
page = (char *)realloc(page, max_len);
|
||||
stralloc_cats(&page, "</td></tr>\n");
|
||||
}
|
||||
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);
|
||||
stralloc_cats(&page, "</tbody></table>\n");
|
||||
stralloc_0(&page);
|
||||
|
||||
sqlite3_finalize(res);
|
||||
sqlite3_close(db);
|
||||
|
||||
return page;
|
||||
return page.s;
|
||||
}
|
||||
|
||||
char *www_files_areas() {
|
||||
char *page;
|
||||
int max_len;
|
||||
int len;
|
||||
char buffer[4096];
|
||||
int i;
|
||||
int j;
|
||||
stralloc page = EMPTY_STRALLOC;
|
||||
|
||||
page = (char *)malloz(4096);
|
||||
max_len = 4096;
|
||||
len = 0;
|
||||
stralloc_copys(&page, "<div class=\"content-header\"><h2>File Directories</h2></div>\n");
|
||||
for (int i = 0; i < conf.file_directory_count; i++) {
|
||||
if (!conf.file_directories[i]->display_on_web)
|
||||
continue;
|
||||
stralloc_cats(&page, "<div class=\"conference-list-item\">");
|
||||
stralloc_cats(&page, conf.file_directories[i]->name);
|
||||
stralloc_cats(&page, "</div>\n");
|
||||
for (int j = 0; j < conf.file_directories[i]->file_sub_count; j++) {
|
||||
stralloc_cats(&page, "<div class=\"area-list-item\"><a href=\"");
|
||||
stralloc_cats(&page, conf.www_url);
|
||||
stralloc_cats(&page, "files/areas/");
|
||||
stralloc_cat_long(&page, i);
|
||||
stralloc_append1(&page, '/');
|
||||
stralloc_cat_long(&page, j);
|
||||
stralloc_cats(&page, "/\">");
|
||||
stralloc_cats(&page, conf.file_directories[i]->file_subs[j]->name);
|
||||
stralloc_cats(&page, "</a></div>\n");
|
||||
}
|
||||
}
|
||||
stralloc_0(&page);
|
||||
|
||||
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;
|
||||
return page.s;
|
||||
}
|
||||
|
||||
char *www_files_get_from_area(int dir, int sub, char *clean_file) {
|
||||
char *sql = "SELECT filename FROM files WHERE approved=1 AND filename LIKE ? ESCAPE \"^\"";
|
||||
char *filenamelike;
|
||||
stralloc filenamelike = EMPTY_STRALLOC;
|
||||
sqlite3 *db;
|
||||
sqlite3_stmt *res;
|
||||
int rc;
|
||||
char buffer[PATH_MAX];
|
||||
char pathbuf[PATH_MAX];
|
||||
char *ret = NULL;
|
||||
int i;
|
||||
int extra = 0;
|
||||
@ -475,67 +418,35 @@ char *www_files_get_from_area(int dir, int sub, char *clean_file) {
|
||||
char *file;
|
||||
|
||||
file = www_decode(clean_file);
|
||||
|
||||
for (i = 0; i < strlen(file); i++) {
|
||||
if (file[i] == '^' || file[i] == '%' || file[i] == '_') {
|
||||
extra++;
|
||||
stralloc_copys(&filenamelike, "%");
|
||||
for (char *p = file; *p != '\0'; ++p) {
|
||||
if (*p == '^' || *p == '_' || *p == '%')
|
||||
stralloc_append1(&filenamelike, '^');
|
||||
stralloc_append1(&filenamelike, *p);
|
||||
}
|
||||
}
|
||||
|
||||
filenamelike = (char *)malloz(strlen(file) + 3 + extra);
|
||||
|
||||
i = 0;
|
||||
filenamelike[i++] = '%';
|
||||
filenamelike[i] = '\0';
|
||||
|
||||
for (j = 0; j < strlen(file); j++) {
|
||||
switch (file[j]) {
|
||||
case '^':
|
||||
filenamelike[i++] = '^';
|
||||
filenamelike[i++] = '^';
|
||||
filenamelike[i] = '\0';
|
||||
break;
|
||||
case '_':
|
||||
filenamelike[i++] = '^';
|
||||
filenamelike[i++] = '_';
|
||||
filenamelike[i] = '\0';
|
||||
break;
|
||||
case '%':
|
||||
filenamelike[i++] = '^';
|
||||
filenamelike[i++] = '%';
|
||||
filenamelike[i] = '\0';
|
||||
break;
|
||||
default:
|
||||
filenamelike[i++] = file[j];
|
||||
filenamelike[i] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// sprintf(filenamelike, "%%/%s", file);
|
||||
|
||||
stralloc_0(&filenamelike);
|
||||
free(file);
|
||||
|
||||
snprintf(buffer, PATH_MAX, "%s/%s.sq3", conf.bbs_path, conf.file_directories[dir]->file_subs[sub]->database);
|
||||
|
||||
rc = sqlite3_open(buffer, &db);
|
||||
snprintf(pathbuf, PATH_MAX, "%s/%s.sq3", conf.bbs_path, conf.file_directories[dir]->file_subs[sub]->database);
|
||||
rc = sqlite3_open(pathbuf, &db);
|
||||
if (rc != SQLITE_OK) {
|
||||
free(filenamelike.s);
|
||||
return NULL;
|
||||
}
|
||||
sqlite3_busy_timeout(db, 5000);
|
||||
rc = sqlite3_prepare_v2(db, sql, -1, &res, 0);
|
||||
if (rc != SQLITE_OK) {
|
||||
sqlite3_close(db);
|
||||
free(filenamelike.s);
|
||||
return NULL;
|
||||
}
|
||||
sqlite3_bind_text(res, 1, filenamelike, -1, 0);
|
||||
|
||||
sqlite3_bind_text(res, 1, filenamelike.s, -1, 0);
|
||||
rc = sqlite3_step(res);
|
||||
if (rc == SQLITE_ROW) {
|
||||
ret = strdup(sqlite3_column_text(res, 0));
|
||||
}
|
||||
|
||||
free(filenamelike);
|
||||
free(filenamelike.s);
|
||||
sqlite3_finalize(res);
|
||||
sqlite3_close(db);
|
||||
return ret;
|
||||
|
Reference in New Issue
Block a user