From 486d592a26e1249455e7121f6284d61a9d3970a4 Mon Sep 17 00:00:00 2001 From: Andrew Pamment Date: Mon, 23 Apr 2018 21:35:54 +1000 Subject: [PATCH] filecenter intial --- .gitignore | 1 + utils/filecenter/Makefile | 51 +++++ utils/filecenter/filecenter.h | 21 ++ utils/filecenter/main.c | 415 ++++++++++++++++++++++++++++++++++ 4 files changed, 488 insertions(+) create mode 100644 utils/filecenter/Makefile create mode 100644 utils/filecenter/filecenter.h create mode 100644 utils/filecenter/main.c diff --git a/.gitignore b/.gitignore index b58b14e..7d32642 100644 --- a/.gitignore +++ b/.gitignore @@ -81,3 +81,4 @@ docs/site utils/reset_pass/reset_pass .vscode last10v2.dat +utils/filecenter/filecenter diff --git a/utils/filecenter/Makefile b/utils/filecenter/Makefile new file mode 100644 index 0000000..3d47c84 --- /dev/null +++ b/utils/filecenter/Makefile @@ -0,0 +1,51 @@ +OS := $(shell uname -s) + +ifeq ($(OS), FreeBSD) + CC=cc + CFLAGS=-I/usr/local/include + LDFLAGS=-L/usr/local/lib -lsqlite3 -lncurses +endif +ifeq ($(OS), DragonFly) + CC=cc + CFLAGS=-I/usr/local/include -I/usr/local/include/ncurses + LDFLAGS=-L/usr/local/lib -lsqlite3 -lncurses +endif +ifeq ($(OS), NetBSD) + CC=cc + CFLAGS=-I/usr/pkg/include + LDFLAGS=-R/usr/pkg/lib -L/usr/pkg/lib -lsqlite3 -lncurses +endif +ifeq ($(OS), OpenBSD) + CC=cc + CFLAGS=-I/usr/local/include + LDFLAGS=-L/usr/local/lib -lsqlite3 -lncurses +endif +ifeq ($(OS), Linux) + CC=gcc + CFLAGS= + LDFLAGS=-lsqlite3 -lncurses +endif +ifeq ($(OS), Darwin) + CC=cc + CFLAGS= + LDFLAGS=-lsqlite3 -lncurses +endif +ifeq ($(OS), SunOS) + CC=gcc + CFLAGS= + LDFLAGS=-lsqlite3 -lcurses +endif + +DEPS = main.c + +OBJ = main.o +%.o: %.c $(DEPS) + $(CC) -c -o $@ $< $(CFLAGS) -I../../deps/cdk-5.0-20161210/include/ + +filecenter: $(OBJ) + $(CC) -o $@ $^ ../../deps/cdk-5.0-20161210/libcdk.a ../../src/inih/ini.o $(CFLAGS) $(LDFLAGS) + +.PHONY: clean + +clean: + rm -f $(OBJ) filecenter diff --git a/utils/filecenter/filecenter.h b/utils/filecenter/filecenter.h new file mode 100644 index 0000000..bdf088a --- /dev/null +++ b/utils/filecenter/filecenter.h @@ -0,0 +1,21 @@ +#ifndef __FILECENTER_H__ +#define __FILECENTER_H__ + +struct file_sub { + char *name; + char *database; + char *upload_path; + int upload_sec_level; + int download_sec_level; +}; + +struct file_directory { + char *name; + char *path; + int sec_level; + int display_on_web; + int file_sub_count; + struct file_sub **file_subs; +}; + +#endif diff --git a/utils/filecenter/main.c b/utils/filecenter/main.c new file mode 100644 index 0000000..565890e --- /dev/null +++ b/utils/filecenter/main.c @@ -0,0 +1,415 @@ +#include +#include +#include +#include +#include +#include +#include +#include "../../src/inih/ini.h" +#include "filecenter.h" + +struct files { + char *name; + char *description; + int approved; +}; + +struct file_directory **file_directories; +int file_directory_count = 0; +CDKSCREEN *cdkscreen = 0; +char *configpath; + +int current_dir; +int current_sub; + +struct files **f; +int fcount = 0; +char **filenames; + +static int bbs_cfg_handler(void *user, const char* section, const char* name, const char *value) +{ + if (strcasecmp(section, "paths") == 0) { + if (strcasecmp(name, "bbs path") == 0) { + configpath = strdup(value); + } + } + if (strcasecmp(section, "file directories") == 0) { + if (file_directory_count == 0) { + file_directories = (struct file_directory **)malloc(sizeof(struct file_directory *)); + } else { + file_directories = (struct file_directory **)realloc(file_directories, sizeof(struct file_directory *) * (file_directory_count + 1)); + } + + file_directories[file_directory_count] = (struct file_directory *)malloc(sizeof(struct file_directory)); + file_directories[file_directory_count]->name = strdup(name); + file_directories[file_directory_count]->path = strdup(value); + file_directories[file_directory_count]->file_sub_count = 0; + file_directories[file_directory_count]->display_on_web = 0; + file_directory_count++; + } + return 1; +} + +static int file_sub_handler(void* user, const char* section, const char* name, + const char* value) +{ + struct file_directory *fd = (struct file_directory *)user; + int i; + + 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 + for (i=0;ifile_sub_count;i++) { + if (strcasecmp(fd->file_subs[i]->name, section) == 0) { + if (strcasecmp(name, "upload sec level") == 0) { + fd->file_subs[i]->upload_sec_level = atoi(value); + } else if (strcasecmp(name, "download sec level") == 0) { + fd->file_subs[i]->download_sec_level = atoi(value); + } else if (strcasecmp(name, "database") == 0) { + fd->file_subs[i]->database = strdup(value); + } else if (strcasecmp(name, "upload path") == 0) { + fd->file_subs[i]->upload_path = strdup(value); + } + return 1; + } + } + if (fd->file_sub_count == 0) { + fd->file_subs = (struct file_sub **)malloc(sizeof(struct file_sub *)); + } else { + fd->file_subs = (struct file_sub **)realloc(fd->file_subs, sizeof(struct file_sub *) * (fd->file_sub_count + 1)); + } + + fd->file_subs[fd->file_sub_count] = (struct file_sub *)malloc(sizeof(struct file_sub)); + + fd->file_subs[fd->file_sub_count]->name = strdup(section); + if (strcasecmp(name, "upload sec level") == 0) { + fd->file_subs[fd->file_sub_count]->upload_sec_level = atoi(value); + } else if (strcasecmp(name, "download sec level") == 0) { + fd->file_subs[fd->file_sub_count]->download_sec_level = atoi(value); + } else if (strcasecmp(name, "database") == 0) { + fd->file_subs[fd->file_sub_count]->database = strdup(value); + } else if (strcasecmp(name, "upload path") == 0) { + fd->file_subs[fd->file_sub_count]->upload_path = strdup(value); + } + fd->file_sub_count++; + } + return 1; +} + +static void doApprove(int index) { + char sql_approve[] = "UPDATE files SET approved=1 WHERE filename LIKE ?"; + sqlite3_stmt *res; + int rc; + struct stat st; + sqlite3 *db; + char database[PATH_MAX]; + + snprintf(database, PATH_MAX, "%s/%s.sq3", configpath, file_directories[current_dir]->file_subs[current_sub]->database); + + // populate scroll list + rc = sqlite3_open(database, &db); + + if (rc != SQLITE_OK) { + return; + } + sqlite3_busy_timeout(db, 5000); + + + if (stat(f[index]->name, &st) == 0) { + f[index]->approved = 1; + sprintf(filenames[index], "%s (approved)", basename(f[index]->name)); + rc = sqlite3_prepare_v2(db, sql_approve, -1, &res, 0); + if (rc != SQLITE_OK) { + sqlite3_close(db); + return; + } + sqlite3_bind_text(res, 1, f[index]->name, -1, 0); + + sqlite3_step(res); + + sqlite3_finalize(res); + } + sqlite3_close(db); +} + +static void doDisapprove(int index) { + char sql_approve[] = "UPDATE files SET approved=0 WHERE filename LIKE ?"; + sqlite3 *db; + sqlite3_stmt *res; + int rc; + struct stat s; + char database[PATH_MAX]; + + snprintf(database, PATH_MAX, "%s/%s.sq3", configpath, file_directories[current_dir]->file_subs[current_sub]->database); + + // populate scroll list + rc = sqlite3_open(database, &db); + + if (rc != SQLITE_OK) { + return; + } + sqlite3_busy_timeout(db, 5000); + + f[index]->approved = 0; + if (stat(f[index]->name, &s) != 0) { + sprintf(filenames[index], "%s (missing)", basename(f[index]->name)); + } else { + sprintf(filenames[index], "%s (unapproved)", basename(f[index]->name)); + } + rc = sqlite3_prepare_v2(db, sql_approve, -1, &res, 0); + if (rc != SQLITE_OK) { + sqlite3_close(db); + return; + } + sqlite3_bind_text(res, 1, f[index]->name, -1, 0); + + sqlite3_step(res); + + sqlite3_finalize(res); + sqlite3_close(db); +} + +static int approveFile(EObjectType cdktype, void *object, void *clientData, chtype input) { + CDKSCROLL *s = (CDKSCROLL *)object; + + + int index = getCDKScrollCurrent(s); + if (index >= fcount) { + return FALSE; + } + if (f[index]->approved == 1) { + doDisapprove(index); + } else { + doApprove(index); + } + setCDKScrollItems(s, filenames, fcount, FALSE); + refreshCDKScreen(cdkscreen); + return FALSE; +} + +void list_files(int dir, int sub) { + CDKSCROLL *scrollList = 0; + int selection; + int i; + char title[42]; + sqlite3 *db; + sqlite3_stmt *res; + int rc; + struct stat s; + char sql_read[] = "SELECT filename, description, approved FROM files"; + char create_sql[] = "CREATE TABLE IF NOT EXISTS files (" + "Id INTEGER PRIMARY KEY," + "filename TEXT," + "description TEXT," + "size INTEGER," + "dlcount INTEGER," + "uploaddate INTEGER," + "approved INTEGER);"; + char database[PATH_MAX]; + char *err_msg; + + + current_dir = dir; + current_sub = sub; + + + snprintf(title, 42, "%s", file_directories[dir]->file_subs[sub]->name); + snprintf(database, PATH_MAX, "%s/%s.sq3", configpath, file_directories[dir]->file_subs[sub]->database); + + // populate scroll list + rc = sqlite3_open(database, &db); + + + if (rc != SQLITE_OK) { + return; + } + sqlite3_busy_timeout(db, 5000); + rc = sqlite3_exec(db, create_sql, 0, 0, &err_msg); + if (rc != SQLITE_OK ) { + sqlite3_free(err_msg); + sqlite3_close(db); + return; + } + rc = sqlite3_prepare_v2(db, sql_read, -1, &res, 0); + + f = NULL; + filenames = NULL; + + while(sqlite3_step(res) == SQLITE_ROW) { + if (fcount == 0) { + f = (struct files **)malloc(sizeof(struct files *)); + filenames = (char **)malloc(sizeof(char *)); + } else { + f = (struct files **)realloc(f, sizeof(struct files *) * (fcount + 1)); + filenames = (char **)realloc(filenames, sizeof(char *) * (fcount + 1)); + } + + f[fcount] = (struct files *)malloc(sizeof(struct files)); + f[fcount]->name = strdup((char *)sqlite3_column_text(res, 0)); + f[fcount]->description = strdup((char *)sqlite3_column_text(res, 1)); + f[fcount]->approved = sqlite3_column_int(res, 2); + + filenames[fcount] = (char *)malloc(strlen(basename(f[fcount]->name)) + 30); + if (stat(f[fcount]->name, &s) != 0) { + sprintf(filenames[fcount], "%s (missing)", basename(f[fcount]->name)); + if (f[fcount]->approved == 1) { + // unapprove missing file + //doDisapprove(fcount); + } + } else if (f[fcount]->approved) { + sprintf(filenames[fcount], "%s (approved)", basename(f[fcount]->name)); + } else { + sprintf(filenames[fcount], "%s (unapproved)", basename(f[fcount]->name)); + } + fcount++; + } + + sqlite3_finalize(res); + sqlite3_close(db); + + if (fcount == 0) { + return; + } + + scrollList = newCDKScroll(cdkscreen, 6, 4, 1, 36, 32, title, NULL, 0, FALSE, A_REVERSE, TRUE, TRUE); + if (!scrollList) { + for (i=0;iname); + free(f[i]->description); + free(f[i]); + free(filenames[i]); + } + + free(f); + free(filenames); + fcount = 0; + return; + } + + setCDKScrollItems(scrollList, filenames, fcount, FALSE); + + bindCDKObject (vSCROLL, scrollList, 'a', approveFile, NULL); +// bindCDKObject (vSCROLL, scrollList, 'd', deleteFile, NULL); + + while(1) { + selection = activateCDKScroll(scrollList, 0); + if (scrollList->exitType == vESCAPE_HIT) { + break; + } + } + for (i=0;iname); + free(f[i]->description); + free(f[i]); + free(filenames[i]); + } + + free(f); + free(filenames); + fcount = 0; + destroyCDKScroll(scrollList); +} + +void list_subdirs(int selected) { + CDKSCROLL *scrollList = 0; + int selection; + int i; + char title[42]; + + char **filesubs = (char **)malloc(sizeof(char *) * file_directories[selected]->file_sub_count); + + snprintf(title, 42, "%s", file_directories[selected]->name); + + for (i=0;ifile_sub_count;i++) { + filesubs[i] = strdup(file_directories[selected]->file_subs[i]->name); + } + + scrollList = newCDKScroll(cdkscreen, 4, 3, 1, 36, 34, title, NULL, 0, FALSE, A_REVERSE, TRUE, TRUE); + if (!scrollList) { + fprintf(stderr, "Unable to make scrolllist!"); + destroyCDKScreen(cdkscreen); + endCDK(); + exit(-1); + } + setCDKScrollItems(scrollList, filesubs, file_directories[selected]->file_sub_count, FALSE); + while(1) { + selection = activateCDKScroll(scrollList, 0); + if (scrollList->exitType == vESCAPE_HIT) { + break; + } else if (scrollList->exitType == vNORMAL) { + list_files(selected, selection); + } + } + + destroyCDKScroll(scrollList); + for (i=0;ifile_sub_count;i++) { + free(filesubs[i]); + } + + free(filesubs); +} + +int main(int argc, char **argv) { + int i; + CDK_PARAMS params; + WINDOW *cursesWin = 0; + CDKSCROLL *scrollList = 0; + int selection; + char **filedirs; + char buffer[PATH_MAX]; + + CDKparseParams(argc, argv, ¶ms, "c:" CDK_CLI_PARAMS); + + if (ini_parse(CDKparamString (¶ms, 'c'), bbs_cfg_handler, NULL) <0) { + fprintf(stderr, "Unable to load configuration ini (%s)!\n", argv[1]); + exit(-1); + } + + for (i=0;ipath); + if (ini_parse(buffer, file_sub_handler, file_directories[i])) { + fprintf(stderr, "Unable to load %s\n", buffer); + exit(-1); + } + } + cursesWin = initscr(); + cdkscreen = initCDKScreen(cursesWin); + + scrollList = newCDKScroll(cdkscreen, 2, 1, 1, 36, 36, "File Directories", NULL, 0, FALSE, A_REVERSE, TRUE, TRUE); + if (!scrollList) { + fprintf(stderr, "Unable to make scrolllist!"); + destroyCDKScreen(cdkscreen); + endCDK(); + exit(-1); + } + + filedirs = (char **)malloc(sizeof(char *) * file_directory_count); + + for (i=0;iname); + } + + setCDKScrollItems(scrollList, filedirs, file_directory_count, FALSE); + + while(1) { + selection = activateCDKScroll(scrollList, 0); + if (scrollList->exitType == vESCAPE_HIT) { + break; + } else if (scrollList->exitType == vNORMAL) { + list_subdirs(selection); + } + } + + destroyCDKScroll(scrollList); + destroyCDKScreen(cdkscreen); + endCDK(); +} \ No newline at end of file