From 8f685dea00c7c7f397bee049da7cc8ad19328aba Mon Sep 17 00:00:00 2001 From: Andrew Pamment Date: Thu, 8 Dec 2016 14:08:04 +1000 Subject: [PATCH] Added multiple archivers --- bbs.h | 15 +++++- bluewave.c | 24 ++++----- config_default/archivers.ini | 5 ++ config_default/bbs.ini | 1 + files.c | 37 ++++++++++--- main.c | 56 ++++++++++++++++++-- users.c | 21 +++++--- utils/sql_update/users_sql_update.pl | 78 ++++++++++++++++++++++++++++ 8 files changed, 206 insertions(+), 31 deletions(-) create mode 100644 config_default/archivers.ini create mode 100755 utils/sql_update/users_sql_update.pl diff --git a/bbs.h b/bbs.h index 464cfb8..6a5d945 100644 --- a/bbs.h +++ b/bbs.h @@ -86,6 +86,13 @@ struct file_directory { struct file_sub **file_subs; }; +struct archiver { + char *name; + char *extension; + char *unpack; + char *pack; +}; + struct bbs_config { char *bbs_name; char *bwave_name; @@ -110,8 +117,6 @@ struct bbs_config { char *irc_server; int irc_port; char *irc_channel; - char *zip_cmd; - char *unzip_cmd; int bwave_max_msgs; struct fido_addr *main_aka; @@ -130,6 +135,10 @@ struct bbs_config { struct file_directory **file_directories; int text_file_count; struct text_file **text_files; + + char *archiver_path; + int archiver_count; + struct archiver **archivers; }; struct sec_level_t { @@ -155,6 +164,8 @@ struct user_record { int cur_file_sub; int timeson; int bwavepktno; + int defarchiver; + int defprotocol; }; struct jam_msg { diff --git a/bluewave.c b/bluewave.c index 21a4ae7..4f272c8 100644 --- a/bluewave.c +++ b/bluewave.c @@ -336,21 +336,21 @@ void bwave_create_packet() { bpos = 0; snprintf(archive, 1024, "%s/node%d/%s.%03d", conf.bbs_path, mynode, conf.bwave_name, gUser->bwavepktno); - for (i=0;idefarchiver-1]->pack);i++) { + if (conf.archivers[gUser->defarchiver-1]->pack[i] == '*') { i++; - if (conf.zip_cmd[i] == 'a') { + if (conf.archivers[gUser->defarchiver-1]->pack[i] == 'a') { sprintf(&buffer[bpos], "%s", archive); bpos = strlen(buffer); - } else if (conf.zip_cmd[i] == 'f') { + } else if (conf.archivers[gUser->defarchiver-1]->pack[i] == 'f') { sprintf(&buffer[bpos], "%s/node%d/bwave/%s.INF %s/node%d/bwave/%s.MIX %s/node%d/bwave/%s.FTI %s/node%d/bwave/%s.DAT", conf.bbs_path, mynode, conf.bwave_name, conf.bbs_path, mynode, conf.bwave_name, conf.bbs_path, mynode, conf.bwave_name, conf.bbs_path, mynode, conf.bwave_name); bpos = strlen(buffer); - } else if (conf.zip_cmd[i] == '*') { + } else if (conf.archivers[gUser->defarchiver-1]->pack[i] == '*') { buffer[bpos++] = '*'; buffer[bpos] = '\0'; } } else { - buffer[bpos++] = conf.zip_cmd[i]; + buffer[bpos++] = conf.archivers[gUser->defarchiver-1]->pack[i]; buffer[bpos] = '\0'; } } @@ -579,21 +579,21 @@ void bwave_upload_reply() { upload_zmodem(gUser, buffer); bpos = 0; - for (i=0;idefarchiver-1]->unpack);i++) { + if (conf.archivers[gUser->defarchiver-1]->unpack[i] == '*') { i++; - if (conf.unzip_cmd[i] == 'a') { + if (conf.archivers[gUser->defarchiver-1]->unpack[i] == 'a') { sprintf(&buffer[bpos], "%s", upload_filename); bpos = strlen(buffer); - } else if (conf.unzip_cmd[i] == 'd') { + } else if (conf.archivers[gUser->defarchiver-1]->unpack[i] == 'd') { sprintf(&buffer[bpos], "%s/node%d/bwave/", conf.bbs_path, mynode); bpos = strlen(buffer); - } else if (conf.unzip_cmd[i] == '*') { + } else if (conf.archivers[gUser->defarchiver-1]->unpack[i] == '*') { buffer[bpos++] = '*'; buffer[bpos] = '\0'; } } else { - buffer[bpos++] = conf.unzip_cmd[i]; + buffer[bpos++] = conf.archivers[gUser->defarchiver-1]->unpack[i]; buffer[bpos] = '\0'; } } diff --git a/config_default/archivers.ini b/config_default/archivers.ini new file mode 100644 index 0000000..b9e89c5 --- /dev/null +++ b/config_default/archivers.ini @@ -0,0 +1,5 @@ +[ZIP] +Pack = zip -j *a *f +Unpack = unzip -j -o *a -d *d +Extension = zip + diff --git a/config_default/bbs.ini b/config_default/bbs.ini index 09dc0c6..775c1da 100644 --- a/config_default/bbs.ini +++ b/config_default/bbs.ini @@ -23,6 +23,7 @@ QWK Name = MAGICKA QWK Max Messages = 5000 ZIP Command = zip -j *a *f UNZIP Command = unzip -j -o *a -d *d +Archivers = config/archivers.ini [paths] WWW Path = /home/andrew/MagickaBBS/www diff --git a/files.c b/files.c index b493b27..5ab1840 100644 --- a/files.c +++ b/files.c @@ -226,8 +226,31 @@ char *get_file_id_diz(char *filename) { int i; FILE *fptr; int len; + int ext; + int arch; - if (tolower(filename[strlen(filename) - 1]) != 'p' || tolower(filename[strlen(filename) - 2]) != 'i' || tolower(filename[strlen(filename) - 3]) != 'z') { + ext = 0; + arch = -1; + + for (i=strlen(filename)-1;i>=0;i--) { + if (filename[i] == '.') { + ext = i + 1; + break; + } + } + + if (ext == 0) { + return NULL; + } + + for (i=0;iextension) == 0) { + arch = i; + break; + } + } + + if (arch == -1) { return NULL; } @@ -247,21 +270,21 @@ char *get_file_id_diz(char *filename) { mkdir(buffer, 0755); bpos = 0; - for (i=0;iunpack);i++) { + if (conf.archivers[arch]->unpack[i] == '*') { i++; - if (conf.unzip_cmd[i] == 'a') { + if (conf.archivers[arch]->unpack[i] == 'a') { sprintf(&buffer[bpos], "%s", filename); bpos = strlen(buffer); - } else if (conf.unzip_cmd[i] == 'd') { + } else if (conf.archivers[arch]->unpack[i] == 'd') { sprintf(&buffer[bpos], "%s/node%d/temp/", conf.bbs_path, mynode); bpos = strlen(buffer); - } else if (conf.unzip_cmd[i] == '*') { + } else if (conf.archivers[arch]->unpack[i] == '*') { buffer[bpos++] = '*'; buffer[bpos] = '\0'; } } else { - buffer[bpos++] = conf.unzip_cmd[i]; + buffer[bpos++] = conf.archivers[arch]->unpack[i]; buffer[bpos] = '\0'; } } diff --git a/main.c b/main.c index eff1a12..6a3b296 100644 --- a/main.c +++ b/main.c @@ -67,6 +67,47 @@ void sigchld_handler(int s) errno = saved_errno; } +static int archiver_config_handler(void* user, const char* section, const char* name, + const char* value) +{ + struct bbs_config *conf = (struct bbs_config *)user; + int i; + + for (i=0;iarchiver_count;i++) { + if (strcasecmp(conf->archivers[i]->name, section) == 0) { + // found it + if (strcasecmp(name, "extension") == 0) { + conf->archivers[i]->extension = strdup(value); + } else if (strcasecmp(name, "unpack") == 0) { + conf->archivers[i]->unpack = strdup(value); + } else if (strcasecmp(name, "pack") == 0) { + conf->archivers[i]->pack = strdup(value); + } + return 1; + } + } + + if (conf->archiver_count == 0) { + conf->archivers = (struct archiver **)malloc(sizeof(struct archiver *)); + } else { + conf->archivers = (struct archiver **)realloc(conf->archivers, sizeof(struct archiver *) * (conf->archiver_count + 1)); + } + + conf->archivers[conf->archiver_count] = (struct archiver *)malloc(sizeof(struct archiver)); + + conf->archivers[conf->archiver_count]->name = strdup(section); + + if (strcasecmp(name, "extension") == 0) { + conf->archivers[conf->archiver_count]->extension = strdup(value); + } else if (strcasecmp(name, "unpack") == 0) { + conf->archivers[conf->archiver_count]->unpack = strdup(value); + } else if (strcasecmp(name, "pack") == 0) { + conf->archivers[conf->archiver_count]->pack = strdup(value); + } + conf->archiver_count++; + + return 1; +} static int door_config_handler(void* user, const char* section, const char* name, const char* value) @@ -336,10 +377,8 @@ static int handler(void* user, const char* section, const char* name, conf->main_aka = parse_fido_addr(value); } else if (strcasecmp(name, "qwk max messages") == 0) { conf->bwave_max_msgs = atoi(value); - } else if (strcasecmp(name, "zip command") == 0) { - conf->zip_cmd = strdup(value); - } else if (strcasecmp(name, "unzip command") == 0) { - conf->unzip_cmd = strdup(value); + } else if (strcasecmp(name, "archivers") == 0) { + conf->archiver_path = strdup(value); } } else if (strcasecmp(section, "paths") == 0){ if (strcasecmp(name, "ansi path") == 0) { @@ -801,6 +840,8 @@ int main(int argc, char **argv) { conf.telnet_port = 0; conf.string_file = NULL; conf.www_path = NULL; + conf.archiver_path = NULL; + conf.archiver_count = 0; // Load BBS data if (ini_parse(argv[1], handler, &conf) <0) { @@ -827,6 +868,13 @@ int main(int argc, char **argv) { exit(-1); } + if (conf.archiver_path != NULL) { + if (ini_parse(conf.archiver_path, archiver_config_handler, &conf) <0) { + fprintf(stderr, "Unable to load configuration ini %s\n", conf.archiver_path); + exit(-1); + } + } + load_strings(); if (conf.fork) { diff --git a/users.c b/users.c index 676384e..8265969 100644 --- a/users.c +++ b/users.c @@ -81,7 +81,7 @@ int save_user(struct user_record *user) { int rc; char *update_sql = "UPDATE users SET password=?, salt=?, firstname=?," - "lastname=?, email=?, location=?, sec_level=?, last_on=?, time_left=?, cur_mail_conf=?, cur_mail_area=?, cur_file_dir=?, cur_file_sub=?, times_on=?, bwavepktno=? where loginname LIKE ?"; + "lastname=?, email=?, location=?, sec_level=?, last_on=?, time_left=?, cur_mail_conf=?, cur_mail_area=?, cur_file_dir=?, cur_file_sub=?, times_on=?, bwavepktno=?, archiver=?, protocol=? where loginname LIKE ?"; sprintf(buffer, "%s/users.sq3", conf.bbs_path); @@ -112,7 +112,9 @@ int save_user(struct user_record *user) { sqlite3_bind_int(res, 13, user->cur_file_sub); sqlite3_bind_int(res, 14, user->timeson); sqlite3_bind_int(res, 15, user->bwavepktno); - sqlite3_bind_text(res, 16, user->loginname, -1, 0); + sqlite3_bind_int(res, 16, user->defarchiver); + sqlite3_bind_int(res, 17, user->defprotocol); + sqlite3_bind_text(res, 18, user->loginname, -1, 0); } else { dolog("Failed to execute statement: %s", sqlite3_errmsg(db)); } @@ -153,10 +155,12 @@ int inst_user(struct user_record *user) { "cur_file_sub INTEGER," "cur_file_dir INTEGER," "times_on INTEGER," - "bwavepktno INTEGER);"; + "bwavepktno INTEGER," + "archiver INTEGER," + "protocol INTEGER);"; char *insert_sql = "INSERT INTO users (loginname, password, salt, firstname," - "lastname, email, location, sec_level, last_on, time_left, cur_mail_conf, cur_mail_area, cur_file_dir, cur_file_sub, times_on, bwavepktno) VALUES(?,?, ?,?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + "lastname, email, location, sec_level, last_on, time_left, cur_mail_conf, cur_mail_area, cur_file_dir, cur_file_sub, times_on, bwavepktno, archiver, protocol) VALUES(?,?, ?,?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; char *err_msg = 0; sprintf(buffer, "%s/users.sq3", conf.bbs_path); @@ -200,6 +204,8 @@ int inst_user(struct user_record *user) { sqlite3_bind_int(res, 14, user->cur_file_sub); sqlite3_bind_int(res, 15, user->timeson); sqlite3_bind_int(res, 16, user->bwavepktno); + sqlite3_bind_int(res, 17, user->defarchiver); + sqlite3_bind_int(res, 18, user->defprotocol); } else { dolog("Failed to execute statement: %s", sqlite3_errmsg(db)); } @@ -227,7 +233,7 @@ struct user_record *check_user_pass(char *loginname, char *password) { sqlite3_stmt *res; int rc; char *sql = "SELECT Id, loginname, password, salt, firstname," - "lastname, email, location, sec_level, last_on, time_left, cur_mail_conf, cur_mail_area, cur_file_dir, cur_file_sub, times_on, bwavepktno FROM users WHERE loginname LIKE ?"; + "lastname, email, location, sec_level, last_on, time_left, cur_mail_conf, cur_mail_area, cur_file_dir, cur_file_sub, times_on, bwavepktno, archiver, protocol FROM users WHERE loginname LIKE ?"; char *pass_hash; sprintf(buffer, "%s/users.sq3", conf.bbs_path); @@ -271,7 +277,8 @@ struct user_record *check_user_pass(char *loginname, char *password) { user->cur_file_sub = sqlite3_column_int(res, 14); user->timeson = sqlite3_column_int(res, 15); user->bwavepktno = sqlite3_column_int(res, 16); - + user->defarchiver = sqlite3_column_int(res, 17); + user->defprotocol = sqlite3_column_int(res, 18); pass_hash = hash_sha256(password, user->salt); if (strcmp(pass_hash, user->password) != 0) { @@ -543,6 +550,8 @@ struct user_record *new_user() { user->cur_mail_area = 0; user->cur_mail_conf = 0; user->timeson = 0; + user->defprotocol = 1; + user->defarchiver = 1; inst_user(user); return user; diff --git a/utils/sql_update/users_sql_update.pl b/utils/sql_update/users_sql_update.pl new file mode 100755 index 0000000..2dabe48 --- /dev/null +++ b/utils/sql_update/users_sql_update.pl @@ -0,0 +1,78 @@ +#!/usr/bin/env perl + +use DBI; + +if (@ARGV < 1) { + print "Usage: ./user_sql_update dbfile.sq3\n"; + exit(0); +} +my $dbfile = $ARGV[0]; + +sub check_exists { + my ($needed) = @_; + + my $dsn = "dbi:SQLite:dbname=$dbfile"; + my $user = ""; + my $password = ""; + my $dbh = DBI->connect($dsn, $user, $password, { + PrintError => 0, + RaiseError => 1, + AutoCommit => 1, + FetchHashKeyName => 'NAME_lc', + }); + + my $sql = "PRAGMA table_info(users)"; + my $sth = $dbh->prepare($sql); + + my $gotneeded; + + $sth->execute(); + while (my @row = $sth->fetchrow_array) { + if ($row[1] eq $needed) { + $gotneeded = 1; + } + } + + $dbh->disconnect; + return $gotneeded; +} + +if (check_exists("protocol") == 0) { + print "Column \"protocol\" doesn't exist... adding..\n"; + + my ($needed) = @_; + + my $dsn = "dbi:SQLite:dbname=$dbfile"; + my $user = ""; + my $password = ""; + my $dbh = DBI->connect($dsn, $user, $password, { + PrintError => 0, + RaiseError => 1, + AutoCommit => 1, + FetchHashKeyName => 'NAME_lc', + }); + + my $sql = "ALTER TABLE users ADD COLUMN protocol INTEGER DEFAULT 1"; + $dbh->do($sql); + $dbh->disconnect; +} + +if (check_exists("archiver") == 0) { + print "Column \"archiver\" doesn't exist... adding..\n"; + + my ($needed) = @_; + + my $dsn = "dbi:SQLite:dbname=$dbfile"; + my $user = ""; + my $password = ""; + my $dbh = DBI->connect($dsn, $user, $password, { + PrintError => 0, + RaiseError => 1, + AutoCommit => 1, + FetchHashKeyName => 'NAME_lc', + }); + + my $sql = "ALTER TABLE users ADD COLUMN archiver INTEGER DEFAULT 1"; + $dbh->do($sql); + $dbh->disconnect; +}