view release on metacpan or search on metacpan
```bash
sudo mysql -u root --skip-password < sql/database_setup.sql
```
You can use the default menu files or change them to your own taste. See the manual for details.
## DESCRIPTION
A 100% Perl BBS server. It supports ASCII, ANSI, ATASCII and PETSCII text formats.
* NOTE: This is still a work in progress. The ASCII and ANSI features work fine. ATASCII and PETSCII have not yet been refined and tested. Also, file upload/download has not been tested.
## CONFIGURATION
The system requires a very minimal static configuration file to give access to the database. The rest of the configuration is stored in the database.
The file **conf/bbs.rc** :
```
# Minimum Configuration for BBS Universal. Only Database info goes here.
# The rest resides in the Database. Comments and empty lines are ignored
files/sysop/manual-sysop-commands.ANSI view on Meta::CPAN
[% BOLD %][% B_YELLOW %][% BLACK %] SYSOP EDIT CONFIGURATION [% RESET %][% YELLOW %]ð¬[% RESET %]
Edit the system configuration
[% BOLD %][% B_YELLOW %][% BLACK %] SYSOP EDIT FILE CATEGORIES [% RESET %][% YELLOW %]ð¬[% RESET %]
Edit file system categories
[% BOLD %][% B_YELLOW %][% BLACK %] SYSOP EDIT NEW USERS [% RESET %][% YELLOW %]ð¬[% RESET %]
[% JUSTIFIED %]All users default to "USER" access level. This is a read-only access level. This command lists each new ueser and allows you to raise their access level to "VETERAN". Veterans are allowed to post and download/upload files.[% ENDJUST...
[% BOLD %][% B_YELLOW %][% BLACK %] SYSOP EDIT USER [% RESET %][% YELLOW %]ð¬[% RESET %]
This allows you to edit any arbitrary user and their attributes.
[% HORIZONTAL RULE BLUE %][% BOLD %][% B_BLUE %][% BRIGHT YELLOW %] SYSOP LIST COMMANDS[% RESET %]
This lists the SysOp commands.
[% BOLD %][% B_YELLOW %][% BLACK %] SYSOP LIST FILES [% RESET %][% YELLOW %]ð¬[% RESET %]
lib/BBS/Universal.pm view on Meta::CPAN
my $self = shift;
return ($self->load_menu('files/main/files_menu'));
},
'LIST FILES SUMMARY' => sub {
my $self = shift;
$self->files_list_summary(FALSE);
return ($self->load_menu('files/main/files_menu'));
},
'UPLOAD FILE' => sub {
my $self = shift;
$self->files_upload_choices();
return ($self->load_menu('files/main/files_menu'));
},
'LIST FILES DETAILED' => sub {
my $self = shift;
$self->files_list_detailed(FALSE);
return ($self->load_menu('files/main/files_menu'));
},
'SEARCH FILES SUMMARY' => sub {
my $self = shift;
$self->files_list_summary(TRUE);
lib/BBS/Universal.pm view on Meta::CPAN
sub files_list_summary {
my ($self, $search) = @_;
$self->{'debug'}->DEBUG(['Start Files List Summary']);
my $sth;
my $filter;
if ($search) {
$self->prompt('Search for (blank for all)');
$filter = $self->get_line({ 'type' => STRING, 'max' => 255, 'default' => '' });
$sth = $self->{'dbh'}->prepare('SELECT * FROM files_view WHERE (filename LIKE ? OR title LIKE ?) AND category_id=? ORDER BY uploaded DESC');
$sth->execute('%' . $filter . '%', '%' . $filter . '%', $self->{'USER'}->{'file_category'});
} else {
$sth = $self->{'dbh'}->prepare('SELECT * FROM files_view WHERE category_id=? ORDER BY uploaded DESC');
$sth->execute($self->{'USER'}->{'file_category'});
}
my @files;
my $max_filename = 10;
my $max_title = 20;
if ($sth->rows > 0) {
while (my $row = $sth->fetchrow_hashref()) {
push(@files, $row);
$max_filename = max(length($row->{'filename'}), $max_filename);
$max_title = max(length($row->{'title'}), $max_title);
lib/BBS/Universal.pm view on Meta::CPAN
} elsif ($mapping->{$key}->{'command'} eq 'REMOVE FILE' && $self->check_access_level($mapping->{$key}->{'access_level'})) {
return (TRUE);
} elsif ($mapping->{$key}->{'command'} eq 'NEXT') {
return (TRUE);
} elsif ($mapping->{$key}->{'command'} eq 'BACK') {
return (FALSE);
}
} ## end while ($self->is_connected...)
} ## end sub files_choices
sub files_upload_choices {
my ($self) = @_;
my $ckey;
$self->prompt('File Name? ');
my $file = $self->get_line({ 'type' => FILENAME, 'max' => 255, 'default' => '' });
my $ext = uc($file =~ /\.(.*?)$/);
$self->prompt('Title (Fiendly name)? ');
my $title = $self->get_line({ 'type' => STRING, 'max' => 255, 'default' => '' });
lib/BBS/Universal.pm view on Meta::CPAN
return (FALSE);
}
if ($? == -1) {
$self->{'debug'}->ERROR(["Could not execute rz: $!"]);
} elsif ($? & 127) {
$self->{'debug'}->ERROR(["File Transfer Aborted: $!"]);
} else {
$self->{'debug'}->DEBUG(['File Transfer Successful']);
}
return (TRUE);
} ## end sub files_upload_choices
sub files_list_detailed {
my ($self, $search) = @_;
$self->{'debug'}->DEBUG(['Start Files List Detailed']);
my $sth;
my $filter;
my $columns = $self->{'USER'}->{'max_columns'};
if ($search) {
$self->prompt('Search for');
$filter = $self->get_line({ 'type' => STRING, 'max' => 255, 'default' => '' });
$sth = $self->{'dbh'}->prepare('SELECT * FROM files_view WHERE (filename LIKE ? OR title LIKE ?) AND category_id=? ORDER BY uploaded DESC');
$sth->execute('%' . $filter . '%', '%' . $filter . '%', $self->{'USER'}->{'file_category'});
} else {
$sth = $self->{'dbh'}->prepare('SELECT * FROM files_view WHERE category_id=? ORDER BY uploaded DESC');
$sth->execute($self->{'USER'}->{'file_category'});
}
my @files;
if ($sth->rows > 0) {
$self->{'debug'}->DEBUGMAX(\@files);
my $table;
my $mode = $self->{'USER'}->{'text_mode'};
while (my $row = $sth->fetchrow_hashref()) {
push(@files, $row);
}
lib/BBS/Universal.pm view on Meta::CPAN
$self->output("\n" . '[% HORIZONTAL RULE GREEN %]' . "\n");
$self->output('[% B_BLUE %][% BRIGHT WHITE %] TITLE [% RESET %] ' . $record->{'title'} . "\n");
$self->output('[% B_BLUE %][% BRIGHT WHITE %] FILENAME [% RESET %] ' . $record->{'filename'} . "\n");
$self->output('[% B_BLUE %][% BRIGHT WHITE %] FILE SIZE [% RESET %] ' . format_number($record->{'file_size'}) . "\n");
if ($record->{'prefer_nickname'}) {
$self->output('[% B_BLUE %][% BRIGHT WHITE %] UPLOADER [% RESET %] ' . $record->{'nickname'} . "\n");
} else {
$self->output('[% B_BLUE %][% BRIGHT WHITE %] UPLOADER [% RESET %] ' . $record->{'fullname'} . "\n");
}
$self->output('[% B_BLUE %][% BRIGHT WHITE %] FILE TYPE [% RESET %] ' . $record->{'type'} . "\n");
$self->output('[% B_BLUE %][% BRIGHT WHITE %] UPLOADED [% RESET %] ' . $record->{'uploaded'} . "\n");
$self->output('[% B_BLUE %][% BRIGHT WHITE %] THUMBS [% RESET %] [% THUMBS UP SIGN %] ' . (0 + $record->{'thumbs_up'}) . ' [% THUMBS DOWN SIGN %] ' . (0 + $record->{'tumbs_down'}) . "\n");
$self->output('[% HORIZONTAL RULE GREEN %]' . "\n");
} else {
$self->output("\n TITLE: " . $record->{'title'} . "\n");
$self->output(' FILENAME: ' . $record->{'filename'} . "\n");
$self->output(' FILE SIZE: ' . format_number($record->{'file_size'}) . "\n");
if ($record->{'prefer_nickname'}) {
$self->output(' UPLOADER: ' . $record->{'nickname'} . "\n");
} else {
$self->output(' UPLOADER: ' . $record->{'fullname'} . "\n");
}
$self->output(' FILE TYPE: ' . $record->{'type'} . "\n");
$self->output(' UPLOADED: ' . $record->{'uploaded'} . "\n");
$self->output(' THUMBS UP: ' . (0 + $record->{'thumbs_up'}) . "\n");
$self->output('THUMBS DOWN: ' . (0 + $record->{'thumbs_down'}) . "\n");
} ## end else [ if ($mode eq 'ANSI') ]
last unless ($self->files_choices($record));
} ## end foreach my $record (@files)
} elsif ($search) {
$self->output("\nSorry '$filter' not found");
} else {
$self->output("\nSorry, this file category is empty\n");
}
lib/BBS/Universal.pm view on Meta::CPAN
sub files_receive_file_zmodem {
my ($self, $file) = @_;
$self->{'debug'}->DEBUG(['Start files_receive_file_zmodem (using lrzsz)']);
my $sock = $self->{'cl_socket'};
unless ($sock) {
$self->{'debug'}->ERROR(["No client socket for ZMODEM receive"]);
return 0;
}
$self->output("\nStart Zmodem file upload\n");
# When rz receives files it writes them into the current working directory.
# Use the destination directory from config (same place other uploads are stored).
my $dest_dir = $self->{'CONF'}->{'BBS ROOT'} . '/' . $self->{'CONF'}->{'FILES PATH'} . '/' . $self->{'USER'}->{'file_category_path'};
# ensure directory exists
unless (-d $dest_dir) {
File::Path::mkpath($dest_dir);
if ($@) {
$self->{'debug'}->ERROR(["Failed to create dest dir $dest_dir: $@"]);
return 0;
}
} ## end unless (-d $dest_dir)
# We will chdir in the child before exec so the received file lands in $dest_dir.
# Use rz --binary --quiet. Depending on lrzsz version you may want --overwrite or --keep
my @args = ('--binary', '--overwrite', '--quiet');
my $ok = $self->_run_on_socket('rz', \@args, $dest_dir);
$self->output("\nFile upload complete\n");
$self->{'debug'}->DEBUG(['End files_receive_file_zmodem (using lrzsz)']);
return $ok;
} ## end sub files_receive_file_zmodem
# package BBS::Universal::Messages;
sub messages_initialize {
my $self = shift;
lib/BBS/Universal.pm view on Meta::CPAN
my $bbs_versions = $self->sysop_versions_format($sections, TRUE);
# Visual config
$self->{'sysop_menu_colors'} = [91, 93, 92, 95, 94, 96];
$self->{'sysop_menu_files'} = ['', '', '', '', ''];
# Default user capability flags
$self->{'flags_default'} = {
'prefer_nickname' => 'ON',
'view_files' => 'ON',
'upload_files' => 'OFF',
'download_files' => 'ON',
'remove_files' => 'OFF',
'read_message' => 'ON',
'post_message' => 'ON',
'remove_message' => 'OFF',
'sysop' => 'OFF',
'show_email' => 'OFF',
};
# Tokens (static + dynamic)
lib/BBS/Universal.pm view on Meta::CPAN
date_format
baud_rate
text_mode
max_columns
max_rows
timeout
retro_systems
accomplishments
prefer_nickname
view_files
upload_files
download_files
remove_files
play_fortunes
read_message
post_message
remove_message
sysop
banned
login_time
logout_time
lib/BBS/Universal.pm view on Meta::CPAN
'logout_time' => { 'type' => STRING, 'max' => 10, 'min' => 10 },
'text_mode' => { 'type' => RADIO, 'max' => 7, 'min' => 9, 'choices' => ['ANSI', 'ASCII', 'ATASCII', 'PETSCII'], 'default' => 'ASCII', },
'max_rows' => { 'type' => NUMERIC, 'max' => 3, 'min' => 3, 'default' => 25 },
'max_columns' => { 'type' => NUMERIC, 'max' => 3, 'min' => 3, 'default' => 80 },
'timeout' => { 'type' => NUMERIC, 'max' => 5, 'min' => 5, 'default' => 10 },
'retro_systems' => { 'type' => STRING, 'max' => 120, 'min' => 40 },
'accomplishments' => { 'type' => STRING, 'max' => 120, 'min' => 40 },
'prefer_nickname' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'OFF' },
'view_files' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'ON' },
'banned' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'OFF' },
'upload_files' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'OFF' },
'download_files' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'OFF' },
'remove_files' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'OFF' },
'read_message' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'ON' },
'post_message' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'OFF' },
'remove_message' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'OFF' },
'play_fortunes' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'ON' },
'sysop' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'OFF' },
'password' => { 'type' => STRING, 'max' => 64, 'min' => 32 },
};
lib/BBS/Universal.pm view on Meta::CPAN
my $size = format_number($row->{$name});
$sizes->{$name} = max(length($size), $sizes->{$name});
} else {
$sizes->{$name} = max(length($row->{$name}), $sizes->{$name});
}
} ## end foreach my $name (keys %{$row...})
} ## end while (my $row = $sth->fetchrow_hashref...)
$sth->finish();
my $table;
if ($wsize > 150) {
$table = Text::SimpleTable->new(max(5, $sizes->{'title'}), max(8, $sizes->{'filename'}), max(4, $sizes->{'type'}), max(11, $sizes->{'description'}), max(8, $sizes->{'username'}), max(4, $sizes->{'file_size'}), max(8, $sizes->{'uploaded'}), ma...
$table->row('TITLE', 'FILENAME', 'TYPE', 'DESCRIPTION', 'UPLOADER', 'SIZE', 'UPLOADED', 'THUMBS UP', 'THUMBS DOWN');
} else {
$table = Text::SimpleTable->new(max(5, $sizes->{'filename'}), max(8, $sizes->{'title'}), max(4, $sizes->{'extension'}), max(11, $sizes->{'description'}), max(8, $sizes->{'username'}), max(4, $sizes->{'file_size'}), max(9, $sizes->{'thumbs_up'...
$table->row('TITLE', 'FILENAME', 'TYPE', 'DESCRIPTION', 'UPLOADER', 'SIZE', 'THUMBS UP', 'THUMBS DOWN');
}
$table->hr();
$sth = $self->{'dbh'}->prepare('SELECT * FROM files_view WHERE category_id=?');
$sth->execute($self->{'USER'}->{'file_category'});
my $category;
while (my $row = $sth->fetchrow_hashref()) {
if ($wsize > 150) {
$table->row($row->{'title'}, $row->{'filename'}, $row->{'type'}, $row->{'description'}, $row->{'username'}, format_number($row->{'file_size'}), $row->{'uploaded'}, sprintf('%-06u', $row->{'thumbs_up'}), sprintf('%-06u', $row->{'thumbs_dow...
} else {
$table->row($row->{'title'}, $row->{'filename'}, $row->{'extension'}, $row->{'description'}, $row->{'username'}, format_number($row->{'file_size'}), sprintf('%-06u', $row->{'thumbs_up'}), sprintf('%-06u', $row->{'thumbs_down'}));
}
$category = $row->{'category'};
} ## end while (my $row = $sth->fetchrow_hashref...)
$sth->finish();
$self->sysop_output("\n" . '[% B_ORANGE %][% BLACK %] Current Category [% RESET %] [% BRIGHT YELLOW %][% BLACK RIGHT-POINTING TRIANGLE %][% RESET %] [% BRIGHT WHITE %][% FILE CATEGORY %][% RESET %]');
my $tbl = $table->twin('YELLOW')->draw();
while ($tbl =~ / (TITLE|FILENAME|TYPE|DESCRIPTION|UPLOADER|SIZE|UPLOADED|THUMBS UP|THUMBS DOWN) /) {
my $ch = $1;
lib/BBS/Universal.pm view on Meta::CPAN
$tbl =~ s/$ch/$new/g;
} ## end while ($tbl =~ / (CHOICE|FIELD|VALUE|No|Yes|USER. VETERAN. JUNIOR SYSOP. SYSOP|YEAR.MONTH.DAY, MONTH.DAY.YEAR, DAY.MONTH.YEAR|300. 600. 1200. 2400. 4800. 9600. 19200. FULL|ASCII. ANSI. ATASCII. PETSCII|Minutes) /)
$self->sysop_output('[% CLS %]' . $tbl . "\n");
$self->sysop_show_choices($mapping);
$self->sysop_prompt('Choose');
do {
$key = uc($self->sysop_keypress());
} until ('1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ' =~ /$key/i);
if ($key !~ /$key_exit/i) {
print 'Edit > (', $choice{$key}, ' = ', $user_row->{ $choice{$key} }, ') > ';
if ($choice{$key} =~ /^(play_fortunes|prefer_nickname|view_files|upload_files|download_files|remove_files|read_message|post_message|remove_message|sysop)$/) {
$user_row->{ $choice{$key} } = ($user_row->{ $choice{$key} } == 1) ? 0 : 1;
my $sth = $self->{'dbh'}->prepare('UPDATE permissions SET ' . $choice{$key} . '= !' . $choice{$key} . ' WHERE id=?');
$sth->execute($user_row->{'id'});
$sth->finish();
} elsif($choice{$key} =~ /text_mode/) {
my $new = $self->sysop_get_line($self->{'SYSOP FIELD TYPES'}->{ $choice{$key} }, $user_row->{ $choice{$key} });
$user_row->{ $choice{$key} } = $new;
my $sth = $self->{'dbh'}->prepare('UPDATE users SET ' . $choice{$key} . '=? WHERE id=?');
$sth->execute($new, $self->{'text_modes'}->{$user_row->{'id'}});
$sth->finish();
} else {
my $new = $self->sysop_get_line($self->{'SYSOP FIELD TYPES'}->{ $choice{$key} }, $user_row->{ $choice{$key} });
$user_row->{ $choice{$key} } = $new;
my $sth = $self->{'dbh'}->prepare('UPDATE users SET ' . $choice{$key} . '=? WHERE id=?');
$sth->execute($new, $user_row->{'id'});
$sth->finish();
} ## end else [ if ($choice{$key} =~ /^(prefer_nickname|view_files|upload_files|download_files|remove_files|read_message|post_message|remove_message|sysop)$/)]
} else {
print "BACK\n";
}
} until ($key =~ /$key_exit/i);
} elsif ($search ne '') {
print "User not found!\n\n";
}
$self->{'debug'}->DEBUG(['End SysOp User Edit']);
return (TRUE);
} ## end sub sysop_user_edit
lib/BBS/Universal.pm view on Meta::CPAN
$key = uc($self->sysop_keypress());
} until ('1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ' =~ /$key/i);
if ($key !~ /$key_exit/i) {
print 'Edit > (', $choice{$key}, ' = ', $user_row->{ $choice{$key} }, ') > ';
my $new = $self->sysop_get_line(ECHO, 1 + $self->{'SYSOP FIELD TYPES'}->{ $choice{$key} }->{'max'}, $user_row->{ $choice{$key} });
unless ($new eq '') {
$new =~ s/^(Yes|On)$/1/i;
$new =~ s/^(No|Off)$/0/i;
}
$user_row->{ $choice{$key} } = $new;
if ($key =~ /prefer_nickname|view_files|upload_files|download_files|remove_files|read_message|post_message|remove_message|sysop/) {
my $sth = $self->{'dbh'}->prepare('UPDATE permissions SET ' . choice { $key } . '=? WHERE id=?');
$sth->execute($new, $user_row->{'id'});
$sth->finish();
} else {
my $sth = $self->{'dbh'}->prepare('UPDATE users SET ' . $choice{$key} . '=? WHERE id=?');
$sth->execute($new, $user_row->{'id'});
$sth->finish();
}
} else {
print "BACK\n";
lib/BBS/Universal.pm view on Meta::CPAN
my $results = $sth->fetchrow_hashref();
my $response = FALSE;
if (defined($results)) {
$self->{'USER'} = $results;
delete($self->{'USER'}->{'password'});
foreach my $field ( # For numeric values
qw(
show_email
prefer_nickname
view_files
upload_files
download_files
remove_files
read_message
post_message
remove_message
play_fortunes
banned
sysop
)
) {
lib/BBS/Universal.pm view on Meta::CPAN
}
);
$sth->execute($user_template->{'username'}, $user_template->{'given'}, $user_template->{'family'}, $user_template->{'nickname'}, $user_template->{'email'}, $user_template->{'accomplishments'}, $user_template->{'retro_systems'}, $user_template->{'...
$sth->finish;
$sth = $self->{'dbh'}->prepare(
q{
INSERT INTO permissions (
id,
prefer_nickname,
view_files,
upload_files,
download_files,
remove_files,
read_message,
show_email,
post_message,
remove_message,
sysop,
play_fortunes,
timeout)
VALUES (LAST_INSERT_ID(),?,?,?,?,?,?,?,?,?,?,?,?,?);
}
);
$sth->execute($user_template->{'prefer_nickname'}, $user_template->{'view_files'}, $user_template->{'upload_files'}, $user_template->{'download_files'}, $user_template->{'remove_files'}, $user_template->{'read_message'}, $user_template->{'show_em...
my $response;
if ($self->{'dbh'}->err) {
$self->{'dbh'}->rollback;
$sth->finish();
$response = FALSE;
} else {
$self->{'dbh'}->commit;
$sth->finish();
$response = TRUE;
lib/BBS/Universal.pm view on Meta::CPAN
$table .= sprintf('%-15s=%-25s', 'BIRTHDAY', $self->users_get_date($self->{'USER'}->{'birthday'})) . "\n";
$table .= sprintf('%-15s=%-25s', 'LOCATION', $self->{'USER'}->{'location'}) . "\n";
$table .= sprintf('%-15s=%-25s', 'BAUD RATE', $self->{'USER'}->{'baud_rate'}) . "\n";
$table .= sprintf('%-15s=%-25s', 'LAST LOGIN', $self->{'USER'}->{'login_time'}) . "\n";
$table .= sprintf('%-15s=%-25s', 'LAST LOGOUT', $self->{'USER'}->{'logout_time'}) . "\n";
$table .= sprintf('%-15s=%-25s', 'TEXT MODE', $self->{'USER'}->{'text_mode'}) . "\n";
$table .= sprintf('%-15s=%-25s', 'IDLE TIMEOUT', $self->{'USER'}->{'timeout'}) . "\n";
$table .= sprintf('%-15s=%-25s', 'SHOW EMAIL', $self->yes_no($self->{'USER'}->{'show_email'}, FALSE)) . "\n";
$table .= sprintf('%-15s=%-25s', 'PREFER NICKNAME', $self->yes_no($self->{'USER'}->{'prefer_nickname'}, FALSE)) . "\n";
$table .= sprintf('%-15s=%-25s', 'VIEW FILES', $self->yes_no($self->{'USER'}->{'view_files'}, FALSE)) . "\n";
$table .= sprintf('%-15s=%-25s', 'UPLOAD FILES', $self->yes_no($self->{'USER'}->{'upload_files'}, FALSE)) . "\n";
$table .= sprintf('%-15s=%-25s', 'DOWNLOAD FILES', $self->yes_no($self->{'USER'}->{'download_files'}, FALSE)) . "\n";
$table .= sprintf('%-15s=%-25s', 'REMOVE FILES', $self->yes_no($self->{'USER'}->{'remove_files'}, FALSE)) . "\n";
$table .= sprintf('%-15s=%-25s', 'READ MESSAGES', $self->yes_no($self->{'USER'}->{'read_message'}, FALSE)) . "\n";
$table .= sprintf('%-15s=%-25s', 'POST MESSAGES', $self->yes_no($self->{'USER'}->{'post_message'}, FALSE)) . "\n";
$table .= sprintf('%-15s=%-25s', 'REMOVE MESSAGES', $self->yes_no($self->{'USER'}->{'remove_message'}, FALSE)) . "\n";
$table .= sprintf('%-15s=%-25s', 'PLAY FORTUNES', $self->yes_no($self->{'USER'}->{'play_fortunes'}, FALSE)) . "\n";
$table .= sprintf('%-15s=%-25s', 'ACCESS LEVEL', $self->{'USER'}->{'access_level'}) . "\n";
$table .= sprintf('%-15s=%-25s', 'RETRO SYSTEMS', $self->{'USER'}->{'retro_systems'}) . "\n";
$table .= sprintf('%-15s=%-25s', 'ACCOMPLISHMENTS', $self->{'USER'}->{'accomplishments'}) . "\n";
} elsif ((($width + 22) * 2) <= $columns) {
lib/BBS/Universal.pm view on Meta::CPAN
$table->row('FIELD', 'VALUE', 'FIELD', 'VALUE');
$table->hr();
$table->row('ACCOUNT NUMBER', $self->{'USER'}->{'id'}, 'USERNAME', $self->{'USER'}->{'username'});
$table->row('FULLNAME', $self->{'USER'}->{'fullname'}, 'NICKNAME', $self->{'USER'}->{'nickname'});
$table->row('EMAIL', $self->{'USER'}->{'email'}, 'SCREEN', $self->{'USER'}->{'max_columns'} . 'x' . $self->{'USER'}->{'max_rows'});
$table->row('BIRTHDAY', $self->users_get_date($self->{'USER'}->{'birthday'}), 'LOCATION', $self->{'USER'}->{'location'});
$table->row('BAUD RATE', $self->{'USER'}->{'baud_rate'}, 'LAST LOGIN', $self->users_get_date($self->{'USER'}->{'login_time'}));
$table->row('DATE FORMAT', $self->{'USER'}->{'date_format'}, 'LAST LOGOUT', $self->users_get_date($self->{'USER'}->{'logout_time'}));
$table->row('IDLE TIMEOUT', $self->{'USER'}->{'timeout'}, 'TEXT MODE', $self->{'USER'}->{'text_mode'});
$table->row('PREFER NICKNAME', $self->yes_no($self->{'USER'}->{'prefer_nickname'}, FALSE), 'VIEW FILES', $self->yes_no($self->{'USER'}->{'view_files'}, FALSE));
$table->row('UPLOAD FILES', $self->yes_no($self->{'USER'}->{'upload_files'}, FALSE), 'DOWNLOAD FILES', $self->yes_no($self->{'USER'}->{'download_files'}, FALSE));
$table->row('REMOVE FILES', $self->yes_no($self->{'USER'}->{'remove_files'}, FALSE), 'READ MESSAGES', $self->yes_no($self->{'USER'}->{'read_message'}, FALSE));
$table->row('POST MESSAGES', $self->yes_no($self->{'USER'}->{'post_message'}, FALSE), 'REMOVE MESSAGES', $self->yes_no($self->{'USER'}->{'remove_message'}, FALSE));
$table->row('SHOW EMAIL', $self->yes_no($self->{'USER'}->{'show_email'}, FALSE), 'ACCESS LEVEL', $self->{'USER'}->{'access_level'});
$table->row('PLAY FORTUNES', $self->yes_no($self->{'USER'}->{'play_fortunes'}, FALSE), 'ACCOMPLISHMENTS', $self->{'USER'}->{'accomplishments'});
$table->row('RETRO SYSTEMS', $self->{'USER'}->{'retro_systems'},'','');
} else {
$width = min($width + 7, $self->{'USER'}->{'max_columns'} - 7);
$table = Text::SimpleTable->new(15, $width);
$table->row('FIELD', 'VALUE');
$table->hr();
lib/BBS/Universal.pm view on Meta::CPAN
$table->row('BIRTHDAY', $self->users_get_date($self->{'USER'}->{'birthday'}));
$table->row('LOCATION', $self->{'USER'}->{'location'});
$table->row('BAUD RATE', $self->{'USER'}->{'baud_rate'});
$table->row('LAST LOGIN', $self->{'USER'}->{'login_time'});
$table->row('LAST LOGOUT', $self->{'USER'}->{'logout_time'});
$table->row('TEXT MODE', $self->{'USER'}->{'text_mode'});
$table->row('IDLE TIMEOUT', $self->{'USER'}->{'timeout'});
$table->row('SHOW EMAIL', $self->yes_no($self->{'USER'}->{'show_email'}, FALSE));
$table->row('PREFER NICKNAME', $self->yes_no($self->{'USER'}->{'prefer_nickname'}, FALSE));
$table->row('VIEW FILES', $self->yes_no($self->{'USER'}->{'view_files'}, FALSE));
$table->row('UPLOAD FILES', $self->yes_no($self->{'USER'}->{'upload_files'}, FALSE));
$table->row('DOWNLOAD FILES', $self->yes_no($self->{'USER'}->{'download_files'}, FALSE));
$table->row('REMOVE FILES', $self->yes_no($self->{'USER'}->{'remove_files'}, FALSE));
$table->row('READ MESSAGES', $self->yes_no($self->{'USER'}->{'read_message'}, FALSE));
$table->row('POST MESSAGES', $self->yes_no($self->{'USER'}->{'post_message'}, FALSE));
$table->row('REMOVE MESSAGES', $self->yes_no($self->{'USER'}->{'remove_message'}, FALSE));
$table->row('PLAY FORTUNES', $self->yes_no($self->{'USER'}->{'play_fortunes'}, FALSE));
$table->row('ACCESS LEVEL', $self->{'USER'}->{'access_level'});
$table->row('RETRO SYSTEMS', $self->{'USER'}->{'retro_systems'});
$table->row('ACCOMPLISHMENTS', $self->{'USER'}->{'accomplishments'});
} ## end else [ if ($columns <= 40) ]
lib/BBS/Universal/Commands.pm view on Meta::CPAN
my $self = shift;
return ($self->load_menu('files/main/files_menu'));
},
'LIST FILES SUMMARY' => sub {
my $self = shift;
$self->files_list_summary(FALSE);
return ($self->load_menu('files/main/files_menu'));
},
'UPLOAD FILE' => sub {
my $self = shift;
$self->files_upload_choices();
return ($self->load_menu('files/main/files_menu'));
},
'LIST FILES DETAILED' => sub {
my $self = shift;
$self->files_list_detailed(FALSE);
return ($self->load_menu('files/main/files_menu'));
},
'SEARCH FILES SUMMARY' => sub {
my $self = shift;
$self->files_list_summary(TRUE);
lib/BBS/Universal/FileTransfer.pm view on Meta::CPAN
sub files_list_summary {
my ($self, $search) = @_;
$self->{'debug'}->DEBUG(['Start Files List Summary']);
my $sth;
my $filter;
if ($search) {
$self->prompt('Search for (blank for all)');
$filter = $self->get_line({ 'type' => STRING, 'max' => 255, 'default' => '' });
$sth = $self->{'dbh'}->prepare('SELECT * FROM files_view WHERE (filename LIKE ? OR title LIKE ?) AND category_id=? ORDER BY uploaded DESC');
$sth->execute('%' . $filter . '%', '%' . $filter . '%', $self->{'USER'}->{'file_category'});
} else {
$sth = $self->{'dbh'}->prepare('SELECT * FROM files_view WHERE category_id=? ORDER BY uploaded DESC');
$sth->execute($self->{'USER'}->{'file_category'});
}
my @files;
my $max_filename = 10;
my $max_title = 20;
if ($sth->rows > 0) {
while (my $row = $sth->fetchrow_hashref()) {
push(@files, $row);
$max_filename = max(length($row->{'filename'}), $max_filename);
$max_title = max(length($row->{'title'}), $max_title);
lib/BBS/Universal/FileTransfer.pm view on Meta::CPAN
} elsif ($mapping->{$key}->{'command'} eq 'REMOVE FILE' && $self->check_access_level($mapping->{$key}->{'access_level'})) {
return (TRUE);
} elsif ($mapping->{$key}->{'command'} eq 'NEXT') {
return (TRUE);
} elsif ($mapping->{$key}->{'command'} eq 'BACK') {
return (FALSE);
}
} ## end while ($self->is_connected...)
} ## end sub files_choices
sub files_upload_choices {
my ($self) = @_;
my $ckey;
$self->prompt('File Name? ');
my $file = $self->get_line({ 'type' => FILENAME, 'max' => 255, 'default' => '' });
my $ext = uc($file =~ /\.(.*?)$/);
$self->prompt('Title (Fiendly name)? ');
my $title = $self->get_line({ 'type' => STRING, 'max' => 255, 'default' => '' });
lib/BBS/Universal/FileTransfer.pm view on Meta::CPAN
return (FALSE);
}
if ($? == -1) {
$self->{'debug'}->ERROR(["Could not execute rz: $!"]);
} elsif ($? & 127) {
$self->{'debug'}->ERROR(["File Transfer Aborted: $!"]);
} else {
$self->{'debug'}->DEBUG(['File Transfer Successful']);
}
return (TRUE);
} ## end sub files_upload_choices
sub files_list_detailed {
my ($self, $search) = @_;
$self->{'debug'}->DEBUG(['Start Files List Detailed']);
my $sth;
my $filter;
my $columns = $self->{'USER'}->{'max_columns'};
if ($search) {
$self->prompt('Search for');
$filter = $self->get_line({ 'type' => STRING, 'max' => 255, 'default' => '' });
$sth = $self->{'dbh'}->prepare('SELECT * FROM files_view WHERE (filename LIKE ? OR title LIKE ?) AND category_id=? ORDER BY uploaded DESC');
$sth->execute('%' . $filter . '%', '%' . $filter . '%', $self->{'USER'}->{'file_category'});
} else {
$sth = $self->{'dbh'}->prepare('SELECT * FROM files_view WHERE category_id=? ORDER BY uploaded DESC');
$sth->execute($self->{'USER'}->{'file_category'});
}
my @files;
if ($sth->rows > 0) {
$self->{'debug'}->DEBUGMAX(\@files);
my $table;
my $mode = $self->{'USER'}->{'text_mode'};
while (my $row = $sth->fetchrow_hashref()) {
push(@files, $row);
}
lib/BBS/Universal/FileTransfer.pm view on Meta::CPAN
$self->output("\n" . '[% HORIZONTAL RULE GREEN %]' . "\n");
$self->output('[% B_BLUE %][% BRIGHT WHITE %] TITLE [% RESET %] ' . $record->{'title'} . "\n");
$self->output('[% B_BLUE %][% BRIGHT WHITE %] FILENAME [% RESET %] ' . $record->{'filename'} . "\n");
$self->output('[% B_BLUE %][% BRIGHT WHITE %] FILE SIZE [% RESET %] ' . format_number($record->{'file_size'}) . "\n");
if ($record->{'prefer_nickname'}) {
$self->output('[% B_BLUE %][% BRIGHT WHITE %] UPLOADER [% RESET %] ' . $record->{'nickname'} . "\n");
} else {
$self->output('[% B_BLUE %][% BRIGHT WHITE %] UPLOADER [% RESET %] ' . $record->{'fullname'} . "\n");
}
$self->output('[% B_BLUE %][% BRIGHT WHITE %] FILE TYPE [% RESET %] ' . $record->{'type'} . "\n");
$self->output('[% B_BLUE %][% BRIGHT WHITE %] UPLOADED [% RESET %] ' . $record->{'uploaded'} . "\n");
$self->output('[% B_BLUE %][% BRIGHT WHITE %] THUMBS [% RESET %] [% THUMBS UP SIGN %] ' . (0 + $record->{'thumbs_up'}) . ' [% THUMBS DOWN SIGN %] ' . (0 + $record->{'tumbs_down'}) . "\n");
$self->output('[% HORIZONTAL RULE GREEN %]' . "\n");
} else {
$self->output("\n TITLE: " . $record->{'title'} . "\n");
$self->output(' FILENAME: ' . $record->{'filename'} . "\n");
$self->output(' FILE SIZE: ' . format_number($record->{'file_size'}) . "\n");
if ($record->{'prefer_nickname'}) {
$self->output(' UPLOADER: ' . $record->{'nickname'} . "\n");
} else {
$self->output(' UPLOADER: ' . $record->{'fullname'} . "\n");
}
$self->output(' FILE TYPE: ' . $record->{'type'} . "\n");
$self->output(' UPLOADED: ' . $record->{'uploaded'} . "\n");
$self->output(' THUMBS UP: ' . (0 + $record->{'thumbs_up'}) . "\n");
$self->output('THUMBS DOWN: ' . (0 + $record->{'thumbs_down'}) . "\n");
} ## end else [ if ($mode eq 'ANSI') ]
last unless ($self->files_choices($record));
} ## end foreach my $record (@files)
} elsif ($search) {
$self->output("\nSorry '$filter' not found");
} else {
$self->output("\nSorry, this file category is empty\n");
}
lib/BBS/Universal/FileTransfer.pm view on Meta::CPAN
sub files_receive_file_zmodem {
my ($self, $file) = @_;
$self->{'debug'}->DEBUG(['Start files_receive_file_zmodem (using lrzsz)']);
my $sock = $self->{'cl_socket'};
unless ($sock) {
$self->{'debug'}->ERROR(["No client socket for ZMODEM receive"]);
return 0;
}
$self->output("\nStart Zmodem file upload\n");
# When rz receives files it writes them into the current working directory.
# Use the destination directory from config (same place other uploads are stored).
my $dest_dir = $self->{'CONF'}->{'BBS ROOT'} . '/' . $self->{'CONF'}->{'FILES PATH'} . '/' . $self->{'USER'}->{'file_category_path'};
# ensure directory exists
unless (-d $dest_dir) {
File::Path::mkpath($dest_dir);
if ($@) {
$self->{'debug'}->ERROR(["Failed to create dest dir $dest_dir: $@"]);
return 0;
}
} ## end unless (-d $dest_dir)
# We will chdir in the child before exec so the received file lands in $dest_dir.
# Use rz --binary --quiet. Depending on lrzsz version you may want --overwrite or --keep
my @args = ('--binary', '--overwrite', '--quiet');
my $ok = $self->_run_on_socket('rz', \@args, $dest_dir);
$self->output("\nFile upload complete\n");
$self->{'debug'}->DEBUG(['End files_receive_file_zmodem (using lrzsz)']);
return $ok;
} ## end sub files_receive_file_zmodem
1;
lib/BBS/Universal/SysOp.pm view on Meta::CPAN
my $bbs_versions = $self->sysop_versions_format($sections, TRUE);
# Visual config
$self->{'sysop_menu_colors'} = [91, 93, 92, 95, 94, 96];
$self->{'sysop_menu_files'} = ['', '', '', '', ''];
# Default user capability flags
$self->{'flags_default'} = {
'prefer_nickname' => 'ON',
'view_files' => 'ON',
'upload_files' => 'OFF',
'download_files' => 'ON',
'remove_files' => 'OFF',
'read_message' => 'ON',
'post_message' => 'ON',
'remove_message' => 'OFF',
'sysop' => 'OFF',
'show_email' => 'OFF',
};
# Tokens (static + dynamic)
lib/BBS/Universal/SysOp.pm view on Meta::CPAN
date_format
baud_rate
text_mode
max_columns
max_rows
timeout
retro_systems
accomplishments
prefer_nickname
view_files
upload_files
download_files
remove_files
play_fortunes
read_message
post_message
remove_message
sysop
banned
login_time
logout_time
lib/BBS/Universal/SysOp.pm view on Meta::CPAN
'logout_time' => { 'type' => STRING, 'max' => 10, 'min' => 10 },
'text_mode' => { 'type' => RADIO, 'max' => 7, 'min' => 9, 'choices' => ['ANSI', 'ASCII', 'ATASCII', 'PETSCII'], 'default' => 'ASCII', },
'max_rows' => { 'type' => NUMERIC, 'max' => 3, 'min' => 3, 'default' => 25 },
'max_columns' => { 'type' => NUMERIC, 'max' => 3, 'min' => 3, 'default' => 80 },
'timeout' => { 'type' => NUMERIC, 'max' => 5, 'min' => 5, 'default' => 10 },
'retro_systems' => { 'type' => STRING, 'max' => 120, 'min' => 40 },
'accomplishments' => { 'type' => STRING, 'max' => 120, 'min' => 40 },
'prefer_nickname' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'OFF' },
'view_files' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'ON' },
'banned' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'OFF' },
'upload_files' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'OFF' },
'download_files' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'OFF' },
'remove_files' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'OFF' },
'read_message' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'ON' },
'post_message' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'OFF' },
'remove_message' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'OFF' },
'play_fortunes' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'ON' },
'sysop' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'OFF' },
'password' => { 'type' => STRING, 'max' => 64, 'min' => 32 },
};
lib/BBS/Universal/SysOp.pm view on Meta::CPAN
my $size = format_number($row->{$name});
$sizes->{$name} = max(length($size), $sizes->{$name});
} else {
$sizes->{$name} = max(length($row->{$name}), $sizes->{$name});
}
} ## end foreach my $name (keys %{$row...})
} ## end while (my $row = $sth->fetchrow_hashref...)
$sth->finish();
my $table;
if ($wsize > 150) {
$table = Text::SimpleTable->new(max(5, $sizes->{'title'}), max(8, $sizes->{'filename'}), max(4, $sizes->{'type'}), max(11, $sizes->{'description'}), max(8, $sizes->{'username'}), max(4, $sizes->{'file_size'}), max(8, $sizes->{'uploaded'}), ma...
$table->row('TITLE', 'FILENAME', 'TYPE', 'DESCRIPTION', 'UPLOADER', 'SIZE', 'UPLOADED', 'THUMBS UP', 'THUMBS DOWN');
} else {
$table = Text::SimpleTable->new(max(5, $sizes->{'filename'}), max(8, $sizes->{'title'}), max(4, $sizes->{'extension'}), max(11, $sizes->{'description'}), max(8, $sizes->{'username'}), max(4, $sizes->{'file_size'}), max(9, $sizes->{'thumbs_up'...
$table->row('TITLE', 'FILENAME', 'TYPE', 'DESCRIPTION', 'UPLOADER', 'SIZE', 'THUMBS UP', 'THUMBS DOWN');
}
$table->hr();
$sth = $self->{'dbh'}->prepare('SELECT * FROM files_view WHERE category_id=?');
$sth->execute($self->{'USER'}->{'file_category'});
my $category;
while (my $row = $sth->fetchrow_hashref()) {
if ($wsize > 150) {
$table->row($row->{'title'}, $row->{'filename'}, $row->{'type'}, $row->{'description'}, $row->{'username'}, format_number($row->{'file_size'}), $row->{'uploaded'}, sprintf('%-06u', $row->{'thumbs_up'}), sprintf('%-06u', $row->{'thumbs_dow...
} else {
$table->row($row->{'title'}, $row->{'filename'}, $row->{'extension'}, $row->{'description'}, $row->{'username'}, format_number($row->{'file_size'}), sprintf('%-06u', $row->{'thumbs_up'}), sprintf('%-06u', $row->{'thumbs_down'}));
}
$category = $row->{'category'};
} ## end while (my $row = $sth->fetchrow_hashref...)
$sth->finish();
$self->sysop_output("\n" . '[% B_ORANGE %][% BLACK %] Current Category [% RESET %] [% BRIGHT YELLOW %][% BLACK RIGHT-POINTING TRIANGLE %][% RESET %] [% BRIGHT WHITE %][% FILE CATEGORY %][% RESET %]');
my $tbl = $table->twin('YELLOW')->draw();
while ($tbl =~ / (TITLE|FILENAME|TYPE|DESCRIPTION|UPLOADER|SIZE|UPLOADED|THUMBS UP|THUMBS DOWN) /) {
my $ch = $1;
lib/BBS/Universal/SysOp.pm view on Meta::CPAN
$tbl =~ s/$ch/$new/g;
} ## end while ($tbl =~ / (CHOICE|FIELD|VALUE|No|Yes|USER. VETERAN. JUNIOR SYSOP. SYSOP|YEAR.MONTH.DAY, MONTH.DAY.YEAR, DAY.MONTH.YEAR|300. 600. 1200. 2400. 4800. 9600. 19200. FULL|ASCII. ANSI. ATASCII. PETSCII|Minutes) /)
$self->sysop_output('[% CLS %]' . $tbl . "\n");
$self->sysop_show_choices($mapping);
$self->sysop_prompt('Choose');
do {
$key = uc($self->sysop_keypress());
} until ('1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ' =~ /$key/i);
if ($key !~ /$key_exit/i) {
print 'Edit > (', $choice{$key}, ' = ', $user_row->{ $choice{$key} }, ') > ';
if ($choice{$key} =~ /^(play_fortunes|prefer_nickname|view_files|upload_files|download_files|remove_files|read_message|post_message|remove_message|sysop)$/) {
$user_row->{ $choice{$key} } = ($user_row->{ $choice{$key} } == 1) ? 0 : 1;
my $sth = $self->{'dbh'}->prepare('UPDATE permissions SET ' . $choice{$key} . '= !' . $choice{$key} . ' WHERE id=?');
$sth->execute($user_row->{'id'});
$sth->finish();
} elsif($choice{$key} =~ /text_mode/) {
my $new = $self->sysop_get_line($self->{'SYSOP FIELD TYPES'}->{ $choice{$key} }, $user_row->{ $choice{$key} });
$user_row->{ $choice{$key} } = $new;
my $sth = $self->{'dbh'}->prepare('UPDATE users SET ' . $choice{$key} . '=? WHERE id=?');
$sth->execute($new, $self->{'text_modes'}->{$user_row->{'id'}});
$sth->finish();
} else {
my $new = $self->sysop_get_line($self->{'SYSOP FIELD TYPES'}->{ $choice{$key} }, $user_row->{ $choice{$key} });
$user_row->{ $choice{$key} } = $new;
my $sth = $self->{'dbh'}->prepare('UPDATE users SET ' . $choice{$key} . '=? WHERE id=?');
$sth->execute($new, $user_row->{'id'});
$sth->finish();
} ## end else [ if ($choice{$key} =~ /^(prefer_nickname|view_files|upload_files|download_files|remove_files|read_message|post_message|remove_message|sysop)$/)]
} else {
print "BACK\n";
}
} until ($key =~ /$key_exit/i);
} elsif ($search ne '') {
print "User not found!\n\n";
}
$self->{'debug'}->DEBUG(['End SysOp User Edit']);
return (TRUE);
} ## end sub sysop_user_edit
lib/BBS/Universal/SysOp.pm view on Meta::CPAN
$key = uc($self->sysop_keypress());
} until ('1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ' =~ /$key/i);
if ($key !~ /$key_exit/i) {
print 'Edit > (', $choice{$key}, ' = ', $user_row->{ $choice{$key} }, ') > ';
my $new = $self->sysop_get_line(ECHO, 1 + $self->{'SYSOP FIELD TYPES'}->{ $choice{$key} }->{'max'}, $user_row->{ $choice{$key} });
unless ($new eq '') {
$new =~ s/^(Yes|On)$/1/i;
$new =~ s/^(No|Off)$/0/i;
}
$user_row->{ $choice{$key} } = $new;
if ($key =~ /prefer_nickname|view_files|upload_files|download_files|remove_files|read_message|post_message|remove_message|sysop/) {
my $sth = $self->{'dbh'}->prepare('UPDATE permissions SET ' . choice { $key } . '=? WHERE id=?');
$sth->execute($new, $user_row->{'id'});
$sth->finish();
} else {
my $sth = $self->{'dbh'}->prepare('UPDATE users SET ' . $choice{$key} . '=? WHERE id=?');
$sth->execute($new, $user_row->{'id'});
$sth->finish();
}
} else {
print "BACK\n";
lib/BBS/Universal/Users.pm view on Meta::CPAN
my $results = $sth->fetchrow_hashref();
my $response = FALSE;
if (defined($results)) {
$self->{'USER'} = $results;
delete($self->{'USER'}->{'password'});
foreach my $field ( # For numeric values
qw(
show_email
prefer_nickname
view_files
upload_files
download_files
remove_files
read_message
post_message
remove_message
play_fortunes
banned
sysop
)
) {
lib/BBS/Universal/Users.pm view on Meta::CPAN
}
);
$sth->execute($user_template->{'username'}, $user_template->{'given'}, $user_template->{'family'}, $user_template->{'nickname'}, $user_template->{'email'}, $user_template->{'accomplishments'}, $user_template->{'retro_systems'}, $user_template->{'...
$sth->finish;
$sth = $self->{'dbh'}->prepare(
q{
INSERT INTO permissions (
id,
prefer_nickname,
view_files,
upload_files,
download_files,
remove_files,
read_message,
show_email,
post_message,
remove_message,
sysop,
play_fortunes,
timeout)
VALUES (LAST_INSERT_ID(),?,?,?,?,?,?,?,?,?,?,?,?,?);
}
);
$sth->execute($user_template->{'prefer_nickname'}, $user_template->{'view_files'}, $user_template->{'upload_files'}, $user_template->{'download_files'}, $user_template->{'remove_files'}, $user_template->{'read_message'}, $user_template->{'show_em...
my $response;
if ($self->{'dbh'}->err) {
$self->{'dbh'}->rollback;
$sth->finish();
$response = FALSE;
} else {
$self->{'dbh'}->commit;
$sth->finish();
$response = TRUE;
lib/BBS/Universal/Users.pm view on Meta::CPAN
$table .= sprintf('%-15s=%-25s', 'BIRTHDAY', $self->users_get_date($self->{'USER'}->{'birthday'})) . "\n";
$table .= sprintf('%-15s=%-25s', 'LOCATION', $self->{'USER'}->{'location'}) . "\n";
$table .= sprintf('%-15s=%-25s', 'BAUD RATE', $self->{'USER'}->{'baud_rate'}) . "\n";
$table .= sprintf('%-15s=%-25s', 'LAST LOGIN', $self->{'USER'}->{'login_time'}) . "\n";
$table .= sprintf('%-15s=%-25s', 'LAST LOGOUT', $self->{'USER'}->{'logout_time'}) . "\n";
$table .= sprintf('%-15s=%-25s', 'TEXT MODE', $self->{'USER'}->{'text_mode'}) . "\n";
$table .= sprintf('%-15s=%-25s', 'IDLE TIMEOUT', $self->{'USER'}->{'timeout'}) . "\n";
$table .= sprintf('%-15s=%-25s', 'SHOW EMAIL', $self->yes_no($self->{'USER'}->{'show_email'}, FALSE)) . "\n";
$table .= sprintf('%-15s=%-25s', 'PREFER NICKNAME', $self->yes_no($self->{'USER'}->{'prefer_nickname'}, FALSE)) . "\n";
$table .= sprintf('%-15s=%-25s', 'VIEW FILES', $self->yes_no($self->{'USER'}->{'view_files'}, FALSE)) . "\n";
$table .= sprintf('%-15s=%-25s', 'UPLOAD FILES', $self->yes_no($self->{'USER'}->{'upload_files'}, FALSE)) . "\n";
$table .= sprintf('%-15s=%-25s', 'DOWNLOAD FILES', $self->yes_no($self->{'USER'}->{'download_files'}, FALSE)) . "\n";
$table .= sprintf('%-15s=%-25s', 'REMOVE FILES', $self->yes_no($self->{'USER'}->{'remove_files'}, FALSE)) . "\n";
$table .= sprintf('%-15s=%-25s', 'READ MESSAGES', $self->yes_no($self->{'USER'}->{'read_message'}, FALSE)) . "\n";
$table .= sprintf('%-15s=%-25s', 'POST MESSAGES', $self->yes_no($self->{'USER'}->{'post_message'}, FALSE)) . "\n";
$table .= sprintf('%-15s=%-25s', 'REMOVE MESSAGES', $self->yes_no($self->{'USER'}->{'remove_message'}, FALSE)) . "\n";
$table .= sprintf('%-15s=%-25s', 'PLAY FORTUNES', $self->yes_no($self->{'USER'}->{'play_fortunes'}, FALSE)) . "\n";
$table .= sprintf('%-15s=%-25s', 'ACCESS LEVEL', $self->{'USER'}->{'access_level'}) . "\n";
$table .= sprintf('%-15s=%-25s', 'RETRO SYSTEMS', $self->{'USER'}->{'retro_systems'}) . "\n";
$table .= sprintf('%-15s=%-25s', 'ACCOMPLISHMENTS', $self->{'USER'}->{'accomplishments'}) . "\n";
} elsif ((($width + 22) * 2) <= $columns) {
lib/BBS/Universal/Users.pm view on Meta::CPAN
$table->row('FIELD', 'VALUE', 'FIELD', 'VALUE');
$table->hr();
$table->row('ACCOUNT NUMBER', $self->{'USER'}->{'id'}, 'USERNAME', $self->{'USER'}->{'username'});
$table->row('FULLNAME', $self->{'USER'}->{'fullname'}, 'NICKNAME', $self->{'USER'}->{'nickname'});
$table->row('EMAIL', $self->{'USER'}->{'email'}, 'SCREEN', $self->{'USER'}->{'max_columns'} . 'x' . $self->{'USER'}->{'max_rows'});
$table->row('BIRTHDAY', $self->users_get_date($self->{'USER'}->{'birthday'}), 'LOCATION', $self->{'USER'}->{'location'});
$table->row('BAUD RATE', $self->{'USER'}->{'baud_rate'}, 'LAST LOGIN', $self->users_get_date($self->{'USER'}->{'login_time'}));
$table->row('DATE FORMAT', $self->{'USER'}->{'date_format'}, 'LAST LOGOUT', $self->users_get_date($self->{'USER'}->{'logout_time'}));
$table->row('IDLE TIMEOUT', $self->{'USER'}->{'timeout'}, 'TEXT MODE', $self->{'USER'}->{'text_mode'});
$table->row('PREFER NICKNAME', $self->yes_no($self->{'USER'}->{'prefer_nickname'}, FALSE), 'VIEW FILES', $self->yes_no($self->{'USER'}->{'view_files'}, FALSE));
$table->row('UPLOAD FILES', $self->yes_no($self->{'USER'}->{'upload_files'}, FALSE), 'DOWNLOAD FILES', $self->yes_no($self->{'USER'}->{'download_files'}, FALSE));
$table->row('REMOVE FILES', $self->yes_no($self->{'USER'}->{'remove_files'}, FALSE), 'READ MESSAGES', $self->yes_no($self->{'USER'}->{'read_message'}, FALSE));
$table->row('POST MESSAGES', $self->yes_no($self->{'USER'}->{'post_message'}, FALSE), 'REMOVE MESSAGES', $self->yes_no($self->{'USER'}->{'remove_message'}, FALSE));
$table->row('SHOW EMAIL', $self->yes_no($self->{'USER'}->{'show_email'}, FALSE), 'ACCESS LEVEL', $self->{'USER'}->{'access_level'});
$table->row('PLAY FORTUNES', $self->yes_no($self->{'USER'}->{'play_fortunes'}, FALSE), 'ACCOMPLISHMENTS', $self->{'USER'}->{'accomplishments'});
$table->row('RETRO SYSTEMS', $self->{'USER'}->{'retro_systems'},'','');
} else {
$width = min($width + 7, $self->{'USER'}->{'max_columns'} - 7);
$table = Text::SimpleTable->new(15, $width);
$table->row('FIELD', 'VALUE');
$table->hr();
lib/BBS/Universal/Users.pm view on Meta::CPAN
$table->row('BIRTHDAY', $self->users_get_date($self->{'USER'}->{'birthday'}));
$table->row('LOCATION', $self->{'USER'}->{'location'});
$table->row('BAUD RATE', $self->{'USER'}->{'baud_rate'});
$table->row('LAST LOGIN', $self->{'USER'}->{'login_time'});
$table->row('LAST LOGOUT', $self->{'USER'}->{'logout_time'});
$table->row('TEXT MODE', $self->{'USER'}->{'text_mode'});
$table->row('IDLE TIMEOUT', $self->{'USER'}->{'timeout'});
$table->row('SHOW EMAIL', $self->yes_no($self->{'USER'}->{'show_email'}, FALSE));
$table->row('PREFER NICKNAME', $self->yes_no($self->{'USER'}->{'prefer_nickname'}, FALSE));
$table->row('VIEW FILES', $self->yes_no($self->{'USER'}->{'view_files'}, FALSE));
$table->row('UPLOAD FILES', $self->yes_no($self->{'USER'}->{'upload_files'}, FALSE));
$table->row('DOWNLOAD FILES', $self->yes_no($self->{'USER'}->{'download_files'}, FALSE));
$table->row('REMOVE FILES', $self->yes_no($self->{'USER'}->{'remove_files'}, FALSE));
$table->row('READ MESSAGES', $self->yes_no($self->{'USER'}->{'read_message'}, FALSE));
$table->row('POST MESSAGES', $self->yes_no($self->{'USER'}->{'post_message'}, FALSE));
$table->row('REMOVE MESSAGES', $self->yes_no($self->{'USER'}->{'remove_message'}, FALSE));
$table->row('PLAY FORTUNES', $self->yes_no($self->{'USER'}->{'play_fortunes'}, FALSE));
$table->row('ACCESS LEVEL', $self->{'USER'}->{'access_level'});
$table->row('RETRO SYSTEMS', $self->{'USER'}->{'retro_systems'});
$table->row('ACCOMPLISHMENTS', $self->{'USER'}->{'accomplishments'});
} ## end else [ if ($columns <= 40) ]
sql/database_setup.sql view on Meta::CPAN
access_level ENUM('USER','VETERAN','JUNIOR SYSOP','SYSOP') NOT NULL DEFAULT 'USER',
login_time TIMESTAMP NOT NULL DEFAULT NOW(),
logout_time TIMESTAMP NOT NULL DEFAULT NOW(),
text_mode TINYINT UNSIGNED NOT NULL
);
CREATE TABLE permissions (
id INT UNSIGNED PRIMARY KEY,
show_email BOOLEAN DEFAULT FALSE,
view_files BOOLEAN DEFAULT FALSE,
upload_files BOOLEAN DEFAULT FALSE,
download_files BOOLEAN DEFAULT FALSE,
remove_files BOOLEAN DEFAULT FALSE,
read_message BOOLEAN DEFAULT FALSE,
post_message BOOLEAN DEFAULT FALSE,
remove_message BOOLEAN DEFAULT FALSE,
sysop BOOLEAN DEFAULT FALSE,
prefer_nickname BOOLEAN DEFAULT FALSE,
play_fortunes BOOLEAN DEFAULT TRUE,
banned BOOLEAN DEFAULT FALSE,
timeout SMALLINT UNSIGNED DEFAULT 10
sql/database_setup.sql view on Meta::CPAN
CREATE TABLE files (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
filename VARCHAR(255) NOT NULL,
title VARCHAR(255) NOT NULL,
user_id INT UNSIGNED NOT NULL DEFAULT 1,
category INT UNSIGNED NOT NULL DEFAULT 1,
file_type SMALLINT NOT NULL,
description TEXT NOT NULL,
file_size BIGINT UNSIGNED NOT NULL,
uploaded TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
thumbs_up INT UNSIGNED DEFAULT 0,
thumbs_down INT UNSIGNED DEFAULT 0
);
CREATE TABLE file_types (
id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
type VARCHAR(255),
extension VARCHAR(5)
);
sql/database_setup.sql view on Meta::CPAN
rss_feed_categories.title AS rss_category_title,
users.email AS email,
users.access_level AS access_level,
text_modes.text_mode AS text_mode,
permissions.timeout AS timeout,
users.retro_systems AS retro_systems,
users.accomplishments AS accomplishments,
permissions.show_email AS show_email,
permissions.prefer_nickname AS prefer_nickname,
permissions.view_files AS view_files,
permissions.upload_files AS upload_files,
permissions.download_files AS download_files,
permissions.remove_files AS remove_files,
permissions.read_message AS read_message,
permissions.post_message AS post_message,
permissions.remove_message AS remove_message,
permissions.sysop AS sysop,
permissions.play_fortunes AS play_fortunes,
permissions.banned AS banned
FROM
users
sql/database_setup.sql view on Meta::CPAN
files.id AS id,
files.filename AS filename,
files.title AS title,
file_categories.title AS category,
file_categories.id AS category_id,
file_categories.path AS category_path,
file_types.type AS type,
file_types.extension AS extension,
files.description AS description,
files.file_size AS file_size,
files.uploaded AS uploaded,
files.thumbs_up AS thumbs_up,
files.thumbs_down AS thumbs_down,
users.username AS username,
users.nickname AS nickname,
permissions.prefer_nickname AS prefer_nickname,
CONCAT(users.given,' ',users.family) AS fullname
FROM
files
INNER JOIN
sql/database_setup.sql view on Meta::CPAN
'System','Operator',
(SELECT text_modes.id FROM text_modes WHERE text_modes.text_mode='ANSI'),
'FULL',
'I manage and maintain this system',
'Stuff',
now(),
'SYSOP',
264,
50
);
INSERT INTO permissions (id,view_files,show_email,upload_files,download_files,remove_files,read_message,post_message,remove_message,sysop,timeout)
VALUES (
LAST_INSERT_ID(),
true,
true,
true,
true,
true,
true,
true,
true,