Basic Experimental Full Screen Editor

This commit is contained in:
Andrew Pamment 2016-12-03 15:08:50 +10:00
parent 8bd085270d
commit f44243d21c
105 changed files with 63667 additions and 0 deletions

6
.gitignore vendored
View File

@ -14,3 +14,9 @@ logs/*
*.a *.a
lua/lua lua/lua
lua/luac lua/luac
netmail.out
echomail.out
utils/magiedit/odoors/libs-*
utils/magiedit/odoors/exe-*
utils/magiedit/odoors/objs-*
utils/magiedit/magiedit

7
utils/magiedit/build.sh Executable file
View File

@ -0,0 +1,7 @@
#!/bin/bash
cd odoors
make
cd ..
gcc -I./odoors -c main.c
gcc -o magiedit main.o odoors/libs-`uname`/libODoors.a

3
utils/magiedit/magiedit.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/sh
cd /home/andrew/MagickaBBS/utils/magiedit
./magiedit -D /home/andrew/MagickaBBS/node$1/dorinfo1.def -MSGTMP /home/andrew/MagickaBBS/node$1

670
utils/magiedit/main.c Normal file
View File

@ -0,0 +1,670 @@
#if WIN32
# define _MSC_VER 1
# define _CRT_SECURE_NO_WARNINGS
# include <Windows.h>
#else
#
#endif
#include <OpenDoor.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <ctype.h>
char **quote_lines;
int quote_line_count;
char *msgfrom;
char *msgto;
char *msgsubj;
char *msgarea;
int msgpriv;
char *message_editor() {
char **body_lines;
int body_line_count;
int position_x;
int position_y;
int done;
char line[81];
char line_cpy[81];
int top_of_screen = 0;
int i, j;
char *return_body;
int body_len;
tODInputEvent ch;
int q_done;
char q_marker;
int q_start;
int q_position;
int *q_lines;
int q_line_count;
int q_unquote;
position_x = 0;
position_y = 0;
body_line_count = 0;
done = 0;
memset(line, 0, 81);
memset(line_cpy, 0, 81);
while (!done) {
od_clr_scr();
od_set_cursor(1, 1);
od_set_color(L_WHITE, D_BLUE);
od_printf(" TO: %-32.32s AREA: %-32.32s", msgto, msgarea);
od_clr_line();
od_set_cursor(2, 1);
od_printf("SUBJ: %s", msgsubj);
od_clr_line();
od_set_cursor(24, 1);
od_printf("Enter /S to save, /Q to quote or /A to abort on a new line.");
od_clr_line();
od_set_cursor(3, 1);
od_set_color(L_WHITE, D_BLACK);
while (1) {
od_get_input(&ch, OD_NO_TIMEOUT, GETIN_NORMAL);
if (ch.EventType == EVENT_EXTENDED_KEY) {
if (ch.chKeyPress == OD_KEY_UP) {
if (position_y > 0) {
strcpy(line_cpy, body_lines[position_y - 1]);
free(body_lines[position_y - 1]);
body_lines[position_y - 1] = strdup(line);
strcpy(line, line_cpy);
position_y--;
if (position_x >= strlen(line)) {
position_x = strlen(line);
}
if (position_y < top_of_screen) {
top_of_screen--;
}
od_set_cursor(3, 1);
for (i=top_of_screen;i<position_y;i++) {
od_set_cursor(i - top_of_screen + 3, 1);
od_printf("%s", body_lines[i]);
od_clr_line();
}
od_set_cursor(i - top_of_screen + 3, 1);
od_printf("%s", line);
od_clr_line();
for (i=position_y;i<body_line_count && i < top_of_screen + 20;i++) {
od_set_cursor(i - top_of_screen + 4, 1);
od_printf("%s", body_lines[i]);
od_clr_line();
}
od_set_cursor(position_y + 3, position_x + 1);
}
} else if (ch.chKeyPress == OD_KEY_DOWN) {
if (position_y < body_line_count) {
strcpy(line_cpy, body_lines[position_y]);
free(body_lines[position_y]);
body_lines[position_y] = strdup(line);
strcpy(line, line_cpy);
position_y++;
if (position_x >= strlen(line)) {
position_x = strlen(line);
}
if (position_y > top_of_screen +20) {
top_of_screen++;
}
od_set_cursor(3, 1);
for (i=top_of_screen;i<position_y;i++) {
od_set_cursor(i - top_of_screen + 3, 1);
od_printf("%s", body_lines[i]);
od_clr_line();
}
od_set_cursor(i - top_of_screen + 3, 1);
od_printf("%s", line);
od_clr_line();
for (i=position_y;i<body_line_count && i < top_of_screen + 20;i++) {
od_set_cursor(i - top_of_screen + 4, 1);
od_printf("%s", body_lines[i]);
od_clr_line();
}
od_set_cursor(position_y - top_of_screen + 3, position_x + 1);
}
} else if (ch.chKeyPress == OD_KEY_LEFT) {
if (position_x > 0) {
position_x--;
od_set_cursor(position_y - top_of_screen + 3, position_x + 1);
}
} else if (ch.chKeyPress == OD_KEY_RIGHT) {
if (position_x < strlen(line)) {
position_x++;
od_set_cursor(position_y - top_of_screen + 3, position_x + 1);
}
}
} else if (ch.EventType == EVENT_CHARACTER) {
if (ch.chKeyPress == '\r' || strlen(line) == 78) {
if (strcasecmp(line, "/S") == 0) {
// save message
body_len = 0;
for (i=0;i<body_line_count;i++) {
body_len = body_len + strlen(body_lines[i]) + 2;
}
body_len++;
return_body = (char *)malloc(body_len);
memset(return_body, 0, body_len);
for (i=0;i<body_line_count;i++) {
strcat(return_body, body_lines[i]);
strcat(return_body, "\r\n");
}
for (i=0;i<body_line_count;i++) {
free(body_lines[i]);
}
free(body_lines);
return return_body;
} else if (strcasecmp(line, "/A") == 0) {
// abort message
for (i=0;i<body_line_count;i++) {
free(body_lines[i]);
}
free(body_lines);
return NULL;
} else if (strcasecmp(line, "/Q") == 0) {
// quote
if (quote_line_count > 0) {
od_clr_scr();
od_set_cursor(1, 1);
od_set_color(L_WHITE, D_BLUE);
od_printf("Quoting Message --");
od_clr_line();
od_set_cursor(2, 1);
od_printf("Press Enter to Select a line, Q to Quote, A to Abort");
od_clr_line();
od_set_cursor(3, 1);
od_set_color(L_WHITE, D_BLACK);
q_start = 0;
q_position = 0;
q_line_count = 0;
q_done = 0;
q_marker = ' ';
while (!q_done) {
for (i=q_start;i<q_start + 20 && i < quote_line_count;i++) {
q_marker = ' ';
for (j=0;j<q_line_count;j++) {
if (q_lines[j] == i) {
q_marker = '+';
break;
}
}
od_set_cursor(i - q_start + 3, 1);
if (i == q_position) {
od_set_color(D_BLACK, D_GREEN);
od_printf("`bright yellow`%c`black green`%s", q_marker, quote_lines[i]);
} else {
od_set_color(L_WHITE, D_BLACK);
od_printf("`bright yellow`%c`bright white`%s", q_marker, quote_lines[i]);
}
}
od_get_input(&ch, OD_NO_TIMEOUT, GETIN_NORMAL);
if (ch.EventType == EVENT_EXTENDED_KEY) {
if (ch.chKeyPress == OD_KEY_UP) {
q_position--;
if (q_position < 0) {
q_position = 0;
}
if (q_position < q_start) {
q_start = q_start - 20;
if (q_start < 0) {
q_start = 0;
}
}
} else if (ch.chKeyPress == OD_KEY_DOWN) {
q_position++;
if (q_position >= quote_line_count) {
q_position = quote_line_count - 1;
}
if (q_position > q_start + 20) {
q_start = q_start + 20;
if (q_start + 20 >= quote_line_count) {
q_start = quote_line_count - 20;
}
}
}
} else if (ch.EventType == EVENT_CHARACTER) {
if (ch.chKeyPress == 13) {
q_unquote = 0;
if (q_line_count > 0) {
for (i=0;i<q_line_count;i++) {
if (q_lines[i] == q_position) {
for (j=i;j<q_line_count-1;j--) {
q_lines[j] = q_lines[j + 1];
}
q_line_count--;
if (q_line_count == 0) {
free(q_lines);
} else {
q_lines = realloc(q_lines, q_line_count * sizeof(int));
}
q_unquote = 1;
break;
}
}
}
if (!q_unquote) {
if (q_line_count == 0) {
q_lines = (int *)malloc(sizeof(int *));
} else {
q_lines = (int *)realloc(q_lines, sizeof(int *) * (q_line_count + 1));
}
q_lines[q_line_count] = q_position;
q_line_count++;
}
} else if (tolower(ch.chKeyPress) == 'q') {
for (i=0;i<q_line_count;i++) {
if (body_line_count == 0) {
body_lines = (char **)malloc(sizeof(char *));
} else {
body_lines = (char **)realloc(body_lines, sizeof(char *) * (body_line_count + 1));
}
body_lines[body_line_count] = strdup(quote_lines[q_lines[i]]);
body_line_count++;
position_y++;
}
if (q_line_count) {
free(q_lines);
}
position_x = 0;
q_done = 1;
} else if (tolower(ch.chKeyPress) == 'a') {
if (q_line_count) {
free(q_lines);
}
q_done = 1;
}
}
}
}
// restore screen
od_clr_scr();
od_set_cursor(1, 1);
od_set_color(L_WHITE, D_BLUE);
od_printf(" TO: %-32.32s AREA: %-32.32s", msgto, msgarea);
od_clr_line();
od_set_cursor(2, 1);
od_printf("SUBJ: %s", msgsubj);
od_clr_line();
od_set_cursor(24, 1);
od_printf("Enter /S to save, /Q to quote or /A to abort on a new line.");
od_clr_line();
od_set_cursor(3, 1);
od_set_color(L_WHITE, D_BLACK);
for (i=top_of_screen;i<top_of_screen + 20;i++) {
od_set_cursor(i - top_of_screen + 3, 1);
if (i < body_line_count) {
od_printf("%s", body_lines[i]);
}
od_clr_line();
}
memset(line, 0, 81);
} else {
if (strlen(line) == 78) {
strncat(line, &ch.chKeyPress, 1);
}
if (position_x < strlen(line)) {
// insert line
if (body_line_count == 0) {
body_lines = (char **)malloc(sizeof(char *));
} else {
body_lines = (char **)realloc(body_lines, sizeof(char *) * (body_line_count + 1));
}
for (i=body_line_count;i>position_y;i--) {
body_lines[i] = body_lines[i-1];
}
body_line_count++;
body_lines[i] = (char *)malloc(sizeof(char) * (position_x + 1));
strncpy(body_lines[i], line, position_x);
body_lines[i][position_x] = '\0';
strcpy(line_cpy, &line[position_x]);
memset(line, 0, 81);
strcpy(line, line_cpy);
memset(line_cpy, 0, 81);
position_y++;
if (position_y - top_of_screen > 20) {
top_of_screen++;
}
} else {
if (body_line_count == 0) {
body_lines = (char **)malloc(sizeof(char *));
} else {
body_lines = (char **)realloc(body_lines, sizeof(char *) * (body_line_count + 1));
}
for (i=body_line_count;i>position_y;i--) {
body_lines[i] = body_lines[i-1];
}
body_line_count++;
body_lines[i] = strdup(line);
position_y++;
if (position_y - top_of_screen > 20) {
top_of_screen++;
}
position_x = 0;
memset(line, 0, 81);
}
od_set_cursor(3, 1);
for (i=top_of_screen;i<position_y;i++) {
od_set_cursor(i - top_of_screen + 3, 1);
od_printf("%s", body_lines[i]);
od_clr_line();
}
od_set_cursor(i - top_of_screen + 3, 1);
od_printf("%s", line);
od_clr_line();
for (i=position_y;i<body_line_count;i++) {
od_set_cursor(i - top_of_screen + 4, 1);
od_printf("%s", body_lines[i]);
od_clr_line();
}
od_set_cursor(position_y - top_of_screen + 3, position_x + 1);
}
} else {
if (ch.chKeyPress == '\b') {
if (position_x == 0) {
// TODO
} else {
if (position_x >= strlen(line)) {
strncpy(line_cpy, line, strlen(line) - 1);
memset(line, 0, 81);
strcpy(line, line_cpy);
memset(line_cpy, 0, 81);
position_x--;
} else {
strncpy(line_cpy, line, position_x -1);
strcpy(line, line_cpy);
memset(line_cpy, 0, 81);
position_x--;
strcat(line_cpy, &line[position_x]);
}
}
} else {
if (position_x >= strlen(line)) {
strncat(line, &ch.chKeyPress, 1);
} else {
strncpy(line_cpy, line, position_x);
strncat(line_cpy, &ch.chKeyPress, 1);
strcat(line_cpy, &line[position_x]);
memset(line, 0, 81);
strcpy(line, line_cpy);
memset(line_cpy, 0, 81);
}
position_x++;
}
if (position_y > 20) {
od_set_cursor(23, 1);
od_clr_line();
} else {
od_set_cursor(position_y + 3, 1);
od_clr_line();
}
for (i = 0; i < position_x; i++) {
od_printf("%c", line[i]);
}
if (position_x < strlen(line) ) {
for (i = position_x; i < strlen(line); i++) {
od_printf("%c", line[i]);
}
}
if (position_y > 22) {
od_set_cursor(23, position_x + 1);
} else {
od_set_cursor(position_y + 3, position_x + 1);
}
}
}
}
}
}
#if _MSC_VER
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
#else
int main(int argc, char **argv)
{
#endif
char *msgtmp;
char *msginf;
char path_sep;
char *msgpath;
int noquote;
char buffer[256];
FILE *fptr;
char *body;
int i;
#if _MSC_VER
int j;
for (i=0;i<strlen(lpszCmdLine);i++) {
if (strncmp(&lpszCmdLine[i], "-MSGTMP ", 8) == 0 || strncmp(&lpszCmdLine[i], "/MSGTMP ", 8) == 0) {
msgpath = strdup(&lpszCmdLine[i + 8]);
for (j=0;j<strlen(msgtmp);j++) {
if (msgpath[j] == ' ') {
msgpath[j] = '\0';
break;
}
}
}
}
od_parse_cmd_line(lpszCmdLine);
path_sep = '\';'
#else
for (i=0;i<argc;i++) {
if (strcmp(argv[i], "-MSGTMP") == 0 || strcmp(argv[i], "/MSGTMP") == 0) {
msgpath = strdup(argv[i+1]);
}
}
od_parse_cmd_line(argc, argv);
path_sep = '/';
#endif
od_init();
msgtmp = (char *)malloc(strlen(msgpath) + 8);
if (!msgtmp) {
od_printf("Out of Memory!\r\n");
od_exit(-1, FALSE);
}
msginf = (char *)malloc(strlen(msgpath) + 8);
if (!msginf) {
od_printf("Out of Memory!\r\n");
od_exit(-1, FALSE);
}
sprintf(msgtmp, "%s%cMSGTMP", msgpath, path_sep);
sprintf(msginf, "%s%cMSGINF", msgpath, path_sep);
fptr = fopen(msginf, "r");
if (!fptr) {
sprintf(msginf, "%s%cmsginf", msgpath, path_sep);
fptr = fopen(msginf, "r");
if (!fptr) {
od_printf("Unable to open MSGINF!\r\n");
od_exit(-1, FALSE);
return -1;
}
}
fgets(buffer, 256, fptr);
for (i=strlen(buffer) - 1; i > 0; i--) {
if (buffer[i] != '\r' && buffer[i] != '\n') {
break;
} else {
buffer[i] = '\0';
}
}
msgfrom = strdup(buffer);
fgets(buffer, 256, fptr);
for (i=strlen(buffer) - 1; i > 0; i--) {
if (buffer[i] != '\r' && buffer[i] != '\n') {
break;
} else {
buffer[i] = '\0';
}
}
msgto = strdup(buffer);
fgets(buffer, 256, fptr);
for (i=strlen(buffer) - 1; i > 0; i--) {
if (buffer[i] != '\r' && buffer[i] != '\n') {
break;
} else {
buffer[i] = '\0';
}
}
msgsubj = strdup(buffer);
fgets(buffer, 256, fptr); // msg no, we don't care
fgets(buffer, 256, fptr);
for (i=strlen(buffer) - 1; i > 0; i--) {
if (buffer[i] != '\r' && buffer[i] != '\n') {
break;
} else {
buffer[i] = '\0';
}
}
msgarea = strdup(buffer);
fgets(buffer, 256, fptr);
for (i=strlen(buffer) - 1; i > 0; i--) {
if (buffer[i] != '\r' && buffer[i] != '\n') {
break;
} else {
buffer[i] = '\0';
}
}
if (strcasecmp(buffer, "YES") == 0) {
msgpriv = 1;
} else {
msgpriv = 0;
}
fclose(fptr);
noquote = 0;
fptr = fopen(msgtmp, "r");
if (!fptr) {
sprintf(msgtmp, "%s%cmsgtmp", msgpath, path_sep);
fptr = fopen(msgtmp, "r");
if (!fptr) {
noquote = 1;
}
}
quote_line_count = 0;
if (!noquote) {
fgets(buffer, 74, fptr);
while (!feof(fptr)) {
for (i=strlen(buffer) - 1; i > 0; i--) {
if (buffer[i] != '\r' && buffer[i] != '\n') {
break;
} else {
buffer[i] = '\0';
}
}
if (quote_line_count == 0) {
quote_lines = (char **)malloc(sizeof(char *));
} else {
quote_lines = (char **)realloc(quote_lines, sizeof(char *) * (quote_line_count + 1));
}
quote_lines[quote_line_count] = (char *)malloc(strlen(buffer) + 5);
sprintf(quote_lines[quote_line_count], " %c> %s", msgto[0], buffer);
quote_line_count++;
fgets(buffer, 74, fptr);
}
fclose(fptr);
unlink(msgtmp);
}
body = message_editor();
if (body == NULL) {
od_printf("Message Aborted!\r\n");
od_exit(0, FALSE);
return 0;
}
for (i=0;i<quote_line_count;i++) {
free(quote_lines[i]);
}
free(quote_lines);
fptr = fopen(msgtmp, "w");
if (!fptr) {
od_printf("Error saving message!\r\n");
od_exit(-1, FALSE);
return -1;
}
fwrite(body, 1, strlen(body), fptr);
fclose(fptr);
od_exit(0, FALSE);
return 0;
}

View File

@ -0,0 +1,341 @@
; DOOR.CFG - Sample OpenDoors door configuration file
;
; This configuration file can be used by the sysop to customize an OpenDoors
; door for use on their own system. The information in this file is NOT usually
; needed, and the file can be left as is, or even erased, without effecting the
; door's performance. OpenDoors is designed to run on almost any BBS system
; automatically, without requiring anything but to the door's .EXE file.
; However, there are many cases where the sysop may wish to customize a door's
; operation using this configuration file. The configuration file system is
; provided to allow the customization of options such as paging hours, maximum
; time permitted within the door, etc., and to allow OpenDoors doors to be run
; under even the most non-typical BBS setups.
;
; Any text following a semi-colon (;), and blank lines, are ignored.
;
;------------------------------------------------------------------------------
;
; BBS system directory. Indicates where the door information file (drop file)
; can be found. Remove the semi-colon (;) to activate this option.
;
;BBSDir C:\BBS
;
;------------------------------------------------------------------------------
;
; The door's working directory. This is where the door's system files are
; located. Remove the semi-colon (;) to activate this option.
;
;DoorDir C:\BBS\MYDOOR
;
;------------------------------------------------------------------------------
;
; Local mode override. Forces door to always operate in local test mode.
; Remove the semi-colon (;) to activate this option. When this mode is
; activated, no door information file is required and default settings are
; used for the user's name, location, etc.
;
;LocalMode
;
;------------------------------------------------------------------------------
;
; Door personality setting. This setting selects one of a number of sysop
; interface personalities. Each personality setting emulates the status line
; format and sysop function keys of a particular BBS package. Valid
; personality settings are:
;
; Standard (OpenDoors style, simplified from RA)
; PCBoard
; RemoteAccess
; Wildcat
;
Personality Standard
;
;------------------------------------------------------------------------------
;
; Log File options. "LogFileName" specifies filename (path optional) where the
; door should record log information. To disable the log file altogether,
; remove the semi-colon (;) from the "DisableLogging" line.
;
;LogFileName DOOR.LOG
;DisableLogging
;
;------------------------------------------------------------------------------
;
; BBS node number that door is running on. Only used if OpenDoors is unable
; to determine the node number by some other means.
;
Node 1
;
;------------------------------------------------------------------------------
;
; Sysop paging hours. Sysop paging will be permitted beginning at the start
; time, up until, but not including, the end time. Times should be in 24-hour
; format. To disable paging on a particular day, set the paging start and end
; times to the same time. To make paging always available, set the start time
; to 0:00 and the end time to 23:59.
;
; Start Time End Time
SundayPagingHours 9:00 22:00
MondayPagingHours 8:30 22:00
TuesdayPagingHours 8:30 22:00
WednesdayPagingHours 8:30 22:00
ThursdayPagingHours 8:30 22:00
FridayPagingHours 8:30 22:00
SaturdayPagingHours 9:00 22:00
;
;------------------------------------------------------------------------------
;
; Duration of sysop page. Value indicates the number of beeps that compose the
; sysop page alarm, with one beep sounded per second.
;
PageDuration 10
;
;------------------------------------------------------------------------------
;
; Maximum length of time a user is permitted to access the door. If the user's
; total remaining time on the BBS is less than this value, the user will only
; be permitted to access the door for this shorter length of time. This option
; may be disabled by placing a semi-colon (;) at the beginning of the line.
; When this option is disabled, the user will be permitted to use the full
; of their remaining time on the BBS within the door.
;
;MaximumDoorTime 15
;
;------------------------------------------------------------------------------
;
; Inactivity timeout. Specifies the maximum number of seconds that may elapse
; without the user pressing any key, before the user will be automatically
; disconnected. A value of 0 disables inactivity timeouts.
;
InactivityTimeout 200
;
;------------------------------------------------------------------------------
;
; Name of the sysop. OpenDoors can usually determine the sysop's name from the
; information passed to the door by the BBS. However, some BBS software does
; not supply this information to doors. In such cases, if the sysop's name is
; required by the door, it may be supplied here. Remove the semi-colon (;) to
; activate this option.
;
;SysopName The Sysop
;
;------------------------------------------------------------------------------
;
; Name of the BBS. OpenDoors can usually determine the name of the BBS from
; the information passed to the door by the BBS. However, some BBS software
; does not supply this information to door programs. In such cases, if the
; name of the BBS is needed by the door, it may be supplied here. Remove the
; semi-colon (;) to activate this option.
;
;SystemName Unnamed BBS
;
;------------------------------------------------------------------------------
;
; Door colour options. These options specify the various text colours that
; will be used by the door if ANSI or AVATAR graphics modes are available.
; Colours are specified in the format:
;
; {Bright} {Flashing} [Foreground Colour] on [Background Colour]
;
; Where foreground and background colours are one of:
;
; Black
; Blue
; Green
; Cyan
; Red
; Magenta
; Yellow / Brown
; White / Grey
;
; Note that some of these options (such as those that pertain to files
; listings) are not used for all doors.
;
ChatUserColour Bright white on black
ChatSysopColour Bright red on black
FileListTitleColour Bright yellow on black
FileListNameColour Bright yellow on black
FileListSizeColour Bright magenta on black
FileListDescriptionColour Cyan on black
FileListOfflineColour Bright red on black
PagePromptColour Bright white on black
PopupMenuTitleColour Bright white on grey
PopupMenuBorderColour Black on grey
PopupMenuTextColour Black on grey
PopupMenuKeyColour Red on grey
PopupMenuHighlightColour Grey on black
PopupMenuHighKeyColour Red on black
;
;------------------------------------------------------------------------------
;
; Memory swapping options. These options are generally not needed, but can be
; used to customize OpenDoor's swapping behaviour. "SwappingDir" can be used
; to specify which directory or directories should be used for swapping.
; Multiple directory paths can be seperated using a semi-colon.
; "SwappingNoEMS" can be used to prevent any swapping from being done to EMS
; memory, and "SwappingDisable" can be used to disable memory swapping
; altogether. Remove the semi-colon (;) to activate any of these options.
;
;SwappingDir C:\
;SwappingNoEMS
;SwappingDisable
;
;------------------------------------------------------------------------------
;
; Serial port options. These options are generally not needed, as these
; settings can usually be determined from the BBS door information file.
; "LockedBPS" specifies the the BPS rate at which the door should communicate
; with the modem. "SerialPort" specifies the port port number that the modem
; is connected to. Unless you have reassigned the port numbers through your
; FOSSIL drive, port 0 corresponds to COM1, port 1 corresponds to COM2, and
; so on. Remove the semi-colon (;) to activate either of these options.
;
;LockedBPS 38400
;SerialPort 0
;
;
; Under DOS, a FOSSIL driver is normally used for serial I/O if one is
; available. If a FOSSIL driver has not been loaded, the door communicates
; directly with the modem. Removing the semi-colon (;) from the "NoFossil"
; option causes the door to always communicate directly with the modem,
; bypassing any FOSSIL driver.
;
;NoFossil
;
;------------------------------------------------------------------------------
;
; The following options only apply for the MS-DOS version of this program,
; and only if a FOSSIL driver is NOT being used for serial communications.
; If a FOSSIL driver IS being used, these options are normally set on the
; FOSSIL driver command line. Under Windows, these options are set in the
; control panel.
;
; Hexidecimal address of the serial port. This address can usually be
; determined automatically for ports COM1, COM2, COM3, and COM4, and is
; normally only required for ports COM5 and higher. Remove the semi-colon
; (;) to activate this option.
;
;PortAddress 2F8
;
;
; Interrupt request line that the serial port is using. May be any IRQ line
; from 1 to 15. By default, IRQ line 4 is used for ports COM1: and COM3:,
; while IRQ line 3 is used for all other ports. Remove the semi-colon (;)
; to activate this option.
;
;PortIRQ 4
;
;
; Serial I/O buffer sizes. "ReceiveBuffer" specifies the number of bytes in
; the serial I/O receive buffer. You may want to increase this buffer size
; if you find that characters being sent from the user's modem are being lost.
; "TransmitBuffer" specifies the number of bytes in the serial I/O transmit
; buffer. You may want to increase this buffer size for improved performance
; in some multitasking environments. A transmit buffer size smaller than 3072
; bytes is not recommended.
;
ReceiveBuffer 256
TransmitBuffer 3072
;
;
; UART FIFO buffers. Normally, OpenDoors will use 16550A UART FIFO buffers
; if they are available. You can prevent OpenDoors from using the FIFO
; buffers, even if they are available, by removing the semi-colon before
; the "NoFIFO" keyword. The "FIFOTriggerSize" specifies how many characters
; may be placed in the FIFO buffers before an serial I/O interrupt is
; envoked. Valid values are 1, 4, 8 and 14 bytes. The default value is 4
; bytes.
;
;NoFIFO
FIFOTriggerSize 4
;
;------------------------------------------------------------------------------
;
; The following options control if and how the Windows version of this program
; disables DTR response by the modem prior to exiting. Normally, the sequence
; of modem commands specified by DisableDTR is sent before exiting, to prevent
; the modem from hanging up. To disable this feature, remove the semi-colon
; (;) at the beginning of the NoDTRDisable line.
;
; DisableDTR specifies a series of commands to be sent to the modem, and
; responses to be received by the modem. Each command and response is
; separated by a space. A tilde (~) character denotes a one second pause, and
; a pipe (|) denotes a CR.
;
;NoDTRDisable
DisableDTR ~+++ OK AT&D0| OK ATO|
;
;------------------------------------------------------------------------------
;
; Custom door information file support. OpenDoors automatically recognizes
; most door information file (drop file) formats, including DORINFO?.DEF,
; EXITINFO.BBS, DOOR.SYS, SFDOORS.DAT, CALLINFO.BBS and CHAIN.TXT. However,
; to permit OpenDoors doors to operate on BBS systems that produce a different
; format file, you may define a custom door information file format. A custom
; door information file format is defined using the "CustomFileName" command,
; followed by one or more lines beginning with the "CustomFileLine" command.
;
; The "CustomFileName" option specifies the filename used to distinguish this
; file format from other file formats. This filename should not include a
; path. To specify the path where the door information file is located, use
; the BBSDir setting, near the beginning of this file. If the filename of the
; custom format is the same as that of one of the built-in formats, the custom
; format will override the built-in format.
;
; The actual format of the custom file is specified using a number of lines
; that begin with the keyword "CustomFileLine". Each of these lines will
; correspond to a single line in the door information file, with the option
; following the "CustomFileLine" keyword specifying the information that can
; be found on that line. This can be one of the following keywords:
;
; Ignore - Causes the next line in the door information
; file to be ignored. Use on lines for which none
; of the options below apply.
; ComPort - COM? port the modem is connected to
; (0 indicates local mode)
; FossilPort - Fossil port number the modem is connected to
; ModemBPS - BPS rate at which to communicate with modem
; (0 or non-numerical value indicates local mode)
; LocalMode - 1, T or Y if door is operating in local mode
; UserName - Full name of the user
; UserFirstName - First name(s) of the user
; UserLastName - Last name of the user
; Alias - The user's psuedonym / handle
; HoursLeft - Hours user has left online
; MinutesLeft - Minutes user has left online, or time left online
; in format hh:mm
; SecondsLeft - Seconds user has left online, or time left online
; in format hh:mm:ss or format mm:ss
; (If more than one of the above time options are
; used, the user time left is taken to be the total
; of all of these values.)
; ANSI - 1, T, Y or G for ANSI graphics mode
; AVATAR - 1, T or Y for AVATAR graphics mode
; RIP - 1, T or Y for RIP graphics mode
; PagePausing - 1, T or Y if user wishes a pause at end of screen
; ScreenLength - Number of lines on user's screen
; ScreenClearing - 1, T or Y if screen clearing mode is on
; Security - The user's security level / access level
; City - City the user is calling from
; Node - Node number user is connected to
; SysopName - Full name of the sysop
; SysopFirstName - The sysop's first name(s)
; SysopLastName - The sysop's last name
; SystemName - Name of the BBS
;
;
CustomFileName EXAMPLE.DEF ; Same format as DORINFO?.DEF
CustomFileLine SystemName
CustomFileLine SysopFirstName
CustomFileLine SysopLastName
CustomFileLine ComPort
CustomFileLine ModemBPS
CustomFileLine Ignore
CustomFileLine UserFirstName
CustomFileLine UserLastName
CustomFileLine City
CustomFileLine ANSI
CustomFileLine Security
CustomFileLine MinutesLeft
;
;------------------------------------------------------------------------------

View File

@ -0,0 +1,12 @@
TEST BBS
THE
SYSOP
COM0
0 BAUD,N,8,1
0
TEST
USER
UNKNOWN LOCATION
1
10
60

View File

@ -0,0 +1,422 @@
# OpenDoors 6.10
# (C) Copyright 1991 - 1997 by Brian Pirie. All Rights Reserved.
#
#
# File: DOS.mak
#
# Description: Makefile used to build the MS-DOS OpenDoors libraries from
# the sources. Usage is described below.
#
# Revisions: Date Ver Who Change
# ---------------------------------------------------------------
# Oct 13, 1994 6.00 BP New file header format.
# Oct 13, 1994 6.00 BP Made directories configurable.
# Oct 13, 1994 6.00 BP Erase tlib-created backup file.
# Oct 14, 1994 6.00 BP Added ODGen.h dependencies.
# Oct 14, 1994 6.00 BP Added ODPlat.c module.
# Oct 31, 1994 6.00 BP Added headers dependency constant.
# Nov 01, 1994 6.00 BP Added ODUtil.c module.
# Dec 31, 1994 6.00 BP Added -B option for Borland Cs.
# Jan 01, 1995 6.00 BP Added ODKrnl.c, ODKrnl.h.
# Jan 29, 1995 6.00 BP Added ODCmdLn.c.
# Nov 16, 1995 6.00 BP Added ODInQue.c, and new headers.
# Nov 21, 1995 6.00 BP Created ODInit1.c, ODInit2.c.
# Dec 02, 1995 6.00 BP Added ODRes.h
# Dec 02, 1995 6.00 BP Added ODFrame.c, ODFrame.h.
# Dec 02, 1995 6.00 BP Added ODStat.h, ODSwap.h.
# Dec 04, 1995 6.00 BP Changes for building Win32 version.
# Dec 05, 1995 6.00 BP Split into makefiles for each platform
# Dec 07, 1995 6.00 BP Added ODEdit.c.
# Jan 04, 1996 6.00 BP Added ODGetIn.c.
# Feb 09, 1996 6.00 BP Renamed ODInit?.* to ODInEx?.*
# Feb 19, 1996 6.00 BP Changed version number to 6.00.
# Mar 03, 1996 6.10 BP Begin version 6.10.
#
###############################################################################
#
# USAGE INFORMATION
#
###############################################################################
#
# Command Line: make -fDOS.mak -DTARGET=?
# or
# nmake -fDOS.mak "TARGET=?"
#
# Where: "TARGET=?" - Specifies which version of the library should be
# built. TARGET can be set to:
#
# t - MS-DOS version, tiny memory model
# s - MS-DOS version, small memory model
# c - MS-DOS version, compact memory model
# m - MS-DOS version, medium memory model
# l - MS-DOS version, large memory model
# h - MS-DOS version, huge memory model
#
# Setting must be in lower case for Borland compilers,
# uppercase for Microsoft compilers.
#
###############################################################################
#
# CONFIGURATION
#
# Customize this section of the makefile to provide the relevant information
# for your compiler, assembler (if any) and build environment.
#
###############################################################################
# Compiler executable file name. Use:
#
# tcc - For Borland Turbo C and Turbo C++
# bcc - For Borland C++
# cl - For Microsoft compilers
#
CC=tcc
#
#------------------------------------------------------------------------------
#
# Assembler executable file name. Use:
#
# tasm - For Turbo Assembler
# masm - For Microsoft Macro Assembler
#
AS=tasm
#
#------------------------------------------------------------------------------
#
# Library managment utility. Use:
#
# tlib - For Borland compilers
# lib - For Microsoft compilers
#
LIB=tlib
#
#------------------------------------------------------------------------------
#
# MS-DOS compiler command-line flags. Use:
#
# -m$(TARGET) -c -O -G -Z -d -B - For Borland compilers including Turbo C
# /a$(TARGET) /c /nologo - For Microsoft compilers
#
CFLAGS=-m$(TARGET) -c -O -G -Z -d -Ic:\progra~1\tc\include
#
#------------------------------------------------------------------------------
#
# Assembler command-line flags.
#
AFLAGS=/mx
ADEFLCODE=/dLCODE
ADEFLDATA=/dLDATA
#
#------------------------------------------------------------------------------
#
# Output directories. customize for your own preferences. Note that trailing
# backslash (\) characters are required.
#
SOURCEDIR=.\ # Comments required
ODHEADERDIR=.\ # in order to
OBJDIR=..\obj\ # avoid line
LIBDIR=..\lib\ # concatentation
#
###############################################################################
#
# DEPENDENCIES
#
# You won't normally have to change anything after this point in this makefile.
#
###############################################################################
#
# Define primary target.
#
all: $(LIBDIR)ODoor$(TARGET).lib
#
#------------------------------------------------------------------------------
#
# Name of all headers.
#
HEADERS= $(HEADERDIR)ODCom.h\
$(HEADERDIR)ODCore.h\
$(HEADERDIR)ODFrame.h\
$(HEADERDIR)ODGen.h\
$(HEADERDIR)ODInEx.h\
$(HEADERDIR)ODInQue.h\
$(HEADERDIR)ODKrnl.h\
$(HEADERDIR)ODPlat.h\
$(HEADERDIR)ODRes.h\
$(HEADERDIR)ODScrn.h\
$(HEADERDIR)ODStat.h\
$(HEADERDIR)ODSwap.h\
$(HEADERDIR)ODTypes.h\
$(HEADERDIR)ODUtil.h\
$(HEADERDIR)OpenDoor.h
#
#------------------------------------------------------------------------------
#
# Build from C sources.
#
$(OBJDIR)odauto$(TARGET).obj : $(SOURCEDIR)odauto.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odauto.c
command /c erase $(OBJDIR)odauto$(TARGET).obj
move odauto.obj $(OBJDIR)odauto$(TARGET).obj
$(OBJDIR)odblock$(TARGET).obj : $(SOURCEDIR)odblock.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odblock.c
command /c erase $(OBJDIR)odblock$(TARGET).obj
move odblock.obj $(OBJDIR)odblock$(TARGET).obj
$(OBJDIR)odcfile$(TARGET).obj : $(SOURCEDIR)odcfile.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odcfile.c
command /c erase $(OBJDIR)odcfile$(TARGET).obj
move odcfile.obj $(OBJDIR)odcfile$(TARGET).obj
$(OBJDIR)odcmdln$(TARGET).obj : $(SOURCEDIR)odcmdln.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odcmdln.c
command /c erase $(OBJDIR)odcmdln$(TARGET).obj
move odcmdln.obj $(OBJDIR)odcmdln$(TARGET).obj
$(OBJDIR)odcom$(TARGET).obj : $(SOURCEDIR)odcom.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odcom.c
command /c erase $(OBJDIR)odcom$(TARGET).obj
move odcom.obj $(OBJDIR)odcom$(TARGET).obj
$(OBJDIR)odcore$(TARGET).obj : $(SOURCEDIR)odcore.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odcore.c
command /c erase $(OBJDIR)odcore$(TARGET).obj
move odcore.obj $(OBJDIR)odcore$(TARGET).obj
$(OBJDIR)oddrbox$(TARGET).obj : $(SOURCEDIR)oddrbox.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)oddrbox.c
command /c erase $(OBJDIR)oddrbox$(TARGET).obj
move oddrbox.obj $(OBJDIR)oddrbox$(TARGET).obj
$(OBJDIR)odedit$(TARGET).obj : $(SOURCEDIR)odedit.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odedit.c
command /c erase $(OBJDIR)odedit$(TARGET).obj
move odedit.obj $(OBJDIR)odedit$(TARGET).obj
$(OBJDIR)odedstr$(TARGET).obj : $(SOURCEDIR)odedstr.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odedstr.c
command /c erase $(OBJDIR)odedstr$(TARGET).obj
move odedstr.obj $(OBJDIR)odedstr$(TARGET).obj
$(OBJDIR)odemu$(TARGET).obj : $(SOURCEDIR)odemu.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odemu.c
command /c erase $(OBJDIR)odemu$(TARGET).obj
move odemu.obj $(OBJDIR)odemu$(TARGET).obj
$(OBJDIR)odgetin$(TARGET).obj : $(SOURCEDIR)odgetin.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odgetin.c
command /c erase $(OBJDIR)odgetin$(TARGET).obj
move odgetin.obj $(OBJDIR)odgetin$(TARGET).obj
$(OBJDIR)odgraph$(TARGET).obj : $(SOURCEDIR)odgraph.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odgraph.c
command /c erase $(OBJDIR)odgraph$(TARGET).obj
move odgraph.obj $(OBJDIR)odgraph$(TARGET).obj
$(OBJDIR)odinex1$(TARGET).obj : $(SOURCEDIR)odinex1.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odinex1.c
command /c erase $(OBJDIR)odinex1$(TARGET).obj
move odinex1.obj $(OBJDIR)odinex1$(TARGET).obj
$(OBJDIR)odinex2$(TARGET).obj : $(SOURCEDIR)odinex2.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odinex2.c
command /c erase $(OBJDIR)odinex2$(TARGET).obj
move odinex2.obj $(OBJDIR)odinex2$(TARGET).obj
$(OBJDIR)odinque$(TARGET).obj : $(SOURCEDIR)odinque.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odinque.c
command /c erase $(OBJDIR)odinque$(TARGET).obj
move odinque.obj $(OBJDIR)odinque$(TARGET).obj
$(OBJDIR)odkrnl$(TARGET).obj : $(SOURCEDIR)odkrnl.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odkrnl.c
command /c erase $(OBJDIR)odkrnl$(TARGET).obj
move odkrnl.obj $(OBJDIR)odkrnl$(TARGET).obj
$(OBJDIR)odlist$(TARGET).obj : $(SOURCEDIR)odlist.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odlist.c
command /c erase $(OBJDIR)odlist$(TARGET).obj
move odlist.obj $(OBJDIR)odlist$(TARGET).obj
$(OBJDIR)odlog$(TARGET).obj : $(SOURCEDIR)odlog.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odlog.c
command /c erase $(OBJDIR)odlog$(TARGET).obj
move odlog.obj $(OBJDIR)odlog$(TARGET).obj
$(OBJDIR)odmulti$(TARGET).obj : $(SOURCEDIR)odmulti.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odmulti.c
command /c erase $(OBJDIR)odmulti$(TARGET).obj
move odmulti.obj $(OBJDIR)odmulti$(TARGET).obj
$(OBJDIR)odplat$(TARGET).obj : $(SOURCEDIR)odplat.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odplat.c
command /c erase $(OBJDIR)odplat$(TARGET).obj
move odplat.obj $(OBJDIR)odplat$(TARGET).obj
$(OBJDIR)odpcb$(TARGET).obj : $(SOURCEDIR)odpcb.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odpcb.c
command /c erase $(OBJDIR)odpcb$(TARGET).obj
move odpcb.obj $(OBJDIR)odpcb$(TARGET).obj
$(OBJDIR)odpopup$(TARGET).obj : $(SOURCEDIR)odpopup.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odpopup.c
command /c erase $(OBJDIR)odpopup$(TARGET).obj
move odpopup.obj $(OBJDIR)odpopup$(TARGET).obj
$(OBJDIR)odprntf$(TARGET).obj : $(SOURCEDIR)odprntf.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odprntf.c
command /c erase $(OBJDIR)odprntf$(TARGET).obj
move odprntf.obj $(OBJDIR)odprntf$(TARGET).obj
$(OBJDIR)odra$(TARGET).obj : $(SOURCEDIR)odra.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odra.c
command /c erase $(OBJDIR)odra$(TARGET).obj
move odra.obj $(OBJDIR)odra$(TARGET).obj
$(OBJDIR)odscrn$(TARGET).obj : $(SOURCEDIR)odscrn.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odscrn.c
command /c erase $(OBJDIR)odscrn$(TARGET).obj
move odscrn.obj $(OBJDIR)odscrn$(TARGET).obj
$(OBJDIR)odspawn$(TARGET).obj : $(SOURCEDIR)odspawn.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odspawn.c
command /c erase $(OBJDIR)odspawn$(TARGET).obj
move odspawn.obj $(OBJDIR)odspawn$(TARGET).obj
$(OBJDIR)odstand$(TARGET).obj : $(SOURCEDIR)odstand.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odstand.c
command /c erase $(OBJDIR)odstand$(TARGET).obj
move odstand.obj $(OBJDIR)odstand$(TARGET).obj
$(OBJDIR)odstat$(TARGET).obj : $(SOURCEDIR)odstat.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odstat.c
command /c erase $(OBJDIR)odstat$(TARGET).obj
move odstat.obj $(OBJDIR)odstat$(TARGET).obj
$(OBJDIR)odsys$(TARGET).obj : $(SOURCEDIR)odsys.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odsys.c
command /c erase $(OBJDIR)odsys$(TARGET).obj
move odsys.obj $(OBJDIR)odsys$(TARGET).obj
$(OBJDIR)odutil$(TARGET).obj : $(SOURCEDIR)odutil.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odutil.c
command /c erase $(OBJDIR)odutil$(TARGET).obj
move odutil.obj $(OBJDIR)odutil$(TARGET).obj
$(OBJDIR)odwcat$(TARGET).obj : $(SOURCEDIR)odwcat.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odwcat.c
command /c erase $(OBJDIR)odwcat$(TARGET).obj
move odwcat.obj $(OBJDIR)odwcat$(TARGET).obj
$(OBJDIR)odwin$(TARGET).obj : $(SOURCEDIR)odwin.c $(HEADERS)
$(CC) $(CFLAGS) $(SOURCEDIR)odwin.c
command /c erase $(OBJDIR)odwin$(TARGET).obj
move odwin.obj $(OBJDIR)odwin$(TARGET).obj
#
#------------------------------------------------------------------------------
#
# Build from assembly sources.
#
$(OBJDIR)odswapt.obj : $(SOURCEDIR)odswap.asm
$(AS) $(AFLAGS) $(SOURCEDIR)odswap.asm
command /c erase $(OBJDIR)odswapt.obj
move odswap.obj $(OBJDIR)odswapt.obj
$(OBJDIR)odswaps.obj : $(SOURCEDIR)odswap.asm
$(AS) $(AFLAGS) $(SOURCEDIR)odswap.asm
command /c erase $(OBJDIR)odswaps.obj
move odswap.obj $(OBJDIR)odswaps.obj
$(OBJDIR)odswapc.obj : $(SOURCEDIR)odswap.asm
$(AS) $(AFLAGS) $(ADEFLDATA) $(SOURCEDIR)odswap.asm
command /c erase $(OBJDIR)odswapc.obj
move odswap.obj $(OBJDIR)odswapc.obj
$(OBJDIR)odswapm.obj : $(SOURCEDIR)odswap.asm
$(AS) $(AFLAGS) $(ADEFLCODE) $(SOURCEDIR)odswap.asm
command /c erase $(OBJDIR)odswapm.obj
move odswap.obj $(OBJDIR)odswapm.obj
$(OBJDIR)odswapl.obj : $(SOURCEDIR)odswap.asm
$(AS) $(AFLAGS) $(ADEFLDATA) $(ADEFLCODE) $(SOURCEDIR)odswap.asm
command /c erase $(OBJDIR)odswapl.obj
move odswap.obj $(OBJDIR)odswapl.obj
$(OBJDIR)odswaph.obj : $(SOURCEDIR)odswap.asm
$(AS) $(AFLAGS) $(ADEFLDATA) $(ADEFLCODE) $(SOURCEDIR)odswap.asm
command /c erase $(OBJDIR)odswaph.obj
move odswap.obj $(OBJDIR)odswaph.obj
#
#------------------------------------------------------------------------------
#
# Build library from objects.
#
OBJECTS= $(OBJDIR)odauto$(TARGET).obj\
$(OBJDIR)odblock$(TARGET).obj\
$(OBJDIR)odcfile$(TARGET).obj\
$(OBJDIR)odcmdln$(TARGET).obj\
$(OBJDIR)odcom$(TARGET).obj\
$(OBJDIR)odcore$(TARGET).obj\
$(OBJDIR)oddrbox$(TARGET).obj\
$(OBJDIR)odedit$(TARGET).obj\
$(OBJDIR)odedstr$(TARGET).obj\
$(OBJDIR)odemu$(TARGET).obj\
$(OBJDIR)odgetin$(TARGET).obj\
$(OBJDIR)odgraph$(TARGET).obj\
$(OBJDIR)odinex1$(TARGET).obj\
$(OBJDIR)odinex2$(TARGET).obj\
$(OBJDIR)odinque$(TARGET).obj\
$(OBJDIR)odkrnl$(TARGET).obj\
$(OBJDIR)odlist$(TARGET).obj\
$(OBJDIR)odlog$(TARGET).obj\
$(OBJDIR)odmulti$(TARGET).obj\
$(OBJDIR)odplat$(TARGET).obj\
$(OBJDIR)odpcb$(TARGET).obj\
$(OBJDIR)odpopup$(TARGET).obj\
$(OBJDIR)odprntf$(TARGET).obj\
$(OBJDIR)odra$(TARGET).obj\
$(OBJDIR)odscrn$(TARGET).obj\
$(OBJDIR)odspawn$(TARGET).obj\
$(OBJDIR)odstand$(TARGET).obj\
$(OBJDIR)odstat$(TARGET).obj\
$(OBJDIR)odswap$(TARGET).obj\
$(OBJDIR)odsys$(TARGET).obj\
$(OBJDIR)odutil$(TARGET).obj\
$(OBJDIR)odwcat$(TARGET).obj\
$(OBJDIR)odwin$(TARGET).obj
$(LIBDIR)odoor$(TARGET).lib : $(OBJECTS)
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odauto$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odblock$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odcfile$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odcmdln$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odcom$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odcore$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)oddrbox$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odedit$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odedstr$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odemu$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odgetin$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odgraph$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odinex1$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odinex2$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odinque$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odkrnl$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odlist$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odlog$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odmulti$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odplat$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odpcb$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odpopup$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odprntf$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odra$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odscrn$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odspawn$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odstand$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odstat$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odswap$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odsys$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odutil$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odwcat$(TARGET).obj
$(LIB) $(LIBDIR)odoor$(TARGET).lib -+$(OBJDIR)odwin$(TARGET).obj
erase $(LIBDIR)odoor$(TARGET).bak
#
#------------------------------------------------------------------------------

View File

@ -0,0 +1,196 @@
# OpenDoors 6.23
# (C} Copyright 1991 - 1997 by Brian Pirie. All Rights Reserved.
#
# Oct-2001 door32.sys/socket modifications by Rob Swindell (www.synchro.net}
#
#
# File: Win32.mak
#
# Description: Makefile used to build the Win32 OpenDoors libraries from
# the sources. Usage is described below.
#
# Revisions: Date Ver Who Change
# ---------------------------------------------------------------
# Aug 09, 2003 6.23 SH *nix port
#
###############################################################################
#
# USAGE INFORMATION
#
###############################################################################
#
# Command Line: make -fWin32.mak
# or
# nmake /f Win32.mak
#
###############################################################################
#
# CONFIGURATION
#
# Customize this section of the makefile to provide the relevant information
# for your compiler, assembler (if any} and build environment.
#
###############################################################################
# Compiler executable file name. Use:
#
# tcc - For Borland Turbo C and Turbo C++
# bcc - For Borland C++
# cl - For Microsoft compilers
#
CC := gcc
#
#------------------------------------------------------------------------------
#
# Linker executable file name. Use:
#
# tlink - For Borland compilers
# link - For Microsoft compilers
#
# Get OS name
OS := $(shell uname)
os := $(shell echo $(OS) | tr '[A-Z]' '[a-z]' | tr ' ' '_')
OBJDIR := objs-$(OS)/
LIBDIR := libs-$(OS)/
EXEDIR := exe-$(OS)/
LD := gcc
ifdef DEBUG
CFLAGS += -g -DOD_DEBUG
BUILDTYPE := debug
else
BUILDTYPE := release
endif
#
#------------------------------------------------------------------------------
#
# Compiler command-line flags.
#
CFLAGS += -fPIC
LDFLAGS += -fPIC
CFLAGS += -O2 -L${LIBDIR} -I../xpdev -Wall
ifeq ($(OS),Darwin)
CFLAGS += -D__unix__
LDFLAGS += $(CFLAGS) -dynamiclib -single_module
else
LDFLAGS += $(CFLAGS) -shared
endif
ifeq ($(shell if [ -f /usr/include/inttypes.h ] ; then echo YES ; fi),YES)
CFLAGS += -DHAS_INTTYPES_H
endif
# /MTd /Zi - for debug
#
#------------------------------------------------------------------------------
#
# Link flags.
#
LDFLAGS += -L../xpdev/$(LD).$(os).lib.$(BUILDTYPE)
#
#------------------------------------------------------------------------------
#
# Output directories. customize for your own preferences. Note that trailing
# backslash (\} characters are required.
#
SHLIB := .so
STATICLIB := .a
OBJFILE := .o
ifdef PROFILE
CFLAGS += -pg
SHLIB := _p${SHLIB}
STATICLIB := _p.a
endif
#
###############################################################################
#
# DEPENDENCIES
#
# You won't normally have to change anything after this point in this makefile.
#
###############################################################################
#
# Define primary target.
#
all: ${OBJDIR} ${LIBDIR} $(EXEDIR) ${LIBDIR}libODoors${SHLIB} \
${LIBDIR}libODoors${STATICLIB}
#
#------------------------------------------------------------------------------
#
# Name of all headers.
#
HEADERS= ${HEADERDIR}ODCom.h\
${HEADERDIR}ODCore.h\
${HEADERDIR}ODGen.h\
${HEADERDIR}ODInEx.h\
${HEADERDIR}ODInQue.h\
${HEADERDIR}ODKrnl.h\
${HEADERDIR}ODPlat.h\
${HEADERDIR}ODRes.h\
${HEADERDIR}ODScrn.h\
${HEADERDIR}ODStat.h\
${HEADERDIR}ODSwap.h\
${HEADERDIR}ODTypes.h\
${HEADERDIR}ODUtil.h\
${HEADERDIR}OpenDoor.h
#
#------------------------------------------------------------------------------
#
# Build DLL from objects.
#
OBJECTS := ${OBJDIR}ODAuto${OBJFILE}\
${OBJDIR}ODBlock${OBJFILE}\
${OBJDIR}ODCFile${OBJFILE}\
${OBJDIR}ODCmdLn${OBJFILE}\
${OBJDIR}ODCom${OBJFILE}\
${OBJDIR}ODCore${OBJFILE}\
${OBJDIR}ODDrBox${OBJFILE}\
${OBJDIR}ODEdit${OBJFILE}\
${OBJDIR}ODEdStr${OBJFILE}\
${OBJDIR}ODEmu${OBJFILE}\
${OBJDIR}ODGetIn${OBJFILE}\
${OBJDIR}ODGraph${OBJFILE}\
${OBJDIR}ODInEx1${OBJFILE}\
${OBJDIR}ODInEx2${OBJFILE}\
${OBJDIR}ODInQue${OBJFILE}\
${OBJDIR}ODKrnl${OBJFILE}\
${OBJDIR}ODList${OBJFILE}\
${OBJDIR}ODLog${OBJFILE}\
${OBJDIR}ODMulti${OBJFILE}\
${OBJDIR}ODPlat${OBJFILE}\
${OBJDIR}ODPCB${OBJFILE}\
${OBJDIR}ODPopup${OBJFILE}\
${OBJDIR}ODPrntf${OBJFILE}\
${OBJDIR}ODRA${OBJFILE}\
${OBJDIR}ODScrn${OBJFILE}\
${OBJDIR}ODSpawn${OBJFILE}\
${OBJDIR}ODStand${OBJFILE}\
${OBJDIR}ODStat${OBJFILE}\
${OBJDIR}ODStr${OBJFILE}\
${OBJDIR}ODUtil${OBJFILE}\
${OBJDIR}ODWCat${OBJFILE}\
${OBJDIR}ODWin${OBJFILE}
# ${OBJDIR}ODoor.res
# ${OBJDIR}odsys${OBJFILE}\ this file is missing
${OBJDIR}:
mkdir ${OBJDIR}
${LIBDIR}:
mkdir ${LIBDIR}
${EXEDIR}:
mkdir ${EXEDIR}
$(OBJDIR)%$(OBJFILE) : %.c
$(CC) $(CFLAGS) -o $@ -c $<
${LIBDIR}libODoors${SHLIB} : ${OBJECTS}
$(LD) $(LDFLAGS) -o ${LIBDIR}libODoors${SHLIB}.6.2 ${OBJECTS}
ln -fs libODoors${SHLIB}.6.2 ${LIBDIR}libODoors${SHLIB}
${LIBDIR}libODoors${STATICLIB} : ${OBJECTS}
ar -r ${LIBDIR}libODoors${STATICLIB} ${OBJECTS}
ranlib ${LIBDIR}libODoors${STATICLIB}
#
#------------------------------------------------------------------------------

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,214 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODAuto.c
*
* Description: Implements od_autodetect() for automatic detection of
* terminal emulation supported by remote system.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Oct 13, 1994 6.00 BP New file header format.
* Oct 14, 1994 6.00 BP Standardized coding style.
* Dec 31, 1994 6.00 BP Use new millisecond timer functions.
* Nov 12, 1995 6.00 BP 32-bit portability.
* Nov 13, 1995 6.00 BP Fixed non-functioning RIP autodetect.
* Nov 16, 1995 6.00 BP Removed oddoor.h, added odcore.h.
* Dec 12, 1995 6.00 BP Added entry, exit and kernel macros.
* Dec 30, 1995 6.00 BP Added ODCALL for calling convention.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
* Aug 10, 2003 6.23 SH *nix support
*/
#define BUILDING_OPENDOORS
#include <string.h>
#include <ctype.h>
#include "OpenDoor.h"
#include "ODStr.h"
#include "ODTypes.h"
#include "ODGen.h"
#include "ODPlat.h"
#include "ODCore.h"
#include "ODKrnl.h"
/* Private function prototypes. */
static char ODWaitNoCase(char *pszWaitFor, tODMilliSec WaitTime);
/* Number of attempts and timeout values for testing each terminal emulation */
/* protocol. */
#define ANSI_TRIES 1
#define ANSI_WAIT 660 /* Time in milliseconds. */
#define RIP_TRIES 1
#define RIP_WAIT 660 /* Time in milliseconds. */
/* Strings to use for autodetection. */
#define ANSI_QUERY "\x1b[6n\r \r"
#define ANSI_RESPONSE "\x1b["
#define RIP_QUERY "\r\x1b[!\r \r"
#define RIP_RESPONSE "RIP"
/* Maximum number of characters to match with _waitnocase(). */
#define MATCH_LEN 3
/* ----------------------------------------------------------------------------
* od_autodetect()
*
* Determines the terminal emulation capabilities of the remote communications
* software, when possible. Turns on ANSI and/or RIP modes if they are
* supported by the remote system.
*
* Parameters: nFlags - Currently unused.
*
* Return: void
*/
ODAPIDEF void ODCALL od_autodetect(INT nFlags)
{
INT nCount;
/* Log function entry if running in trace mode. */
TRACE(TRACE_API, "od_autodetect()");
/* Initialize OpenDoors if it hasn't aready been done. */
if(!bODInitialized) od_init();
OD_API_ENTRY();
/* Temporary code that will be optimized out, which prevents a compiler */
/* warning from being generated for the currently unused flags parameter. */
(void)nFlags;
/* If operating in local mode, turn on ANSI mode, but not RIP. */
if(od_control.baud == 0)
{
od_control.user_ansi = TRUE;
OD_API_EXIT();
return;
}
/* If user_ansi is not set, attempt to determine ANSI capabilities. */
if(!od_control.user_ansi)
{
/* Clear inbound keyboard buffer. */
od_clear_keybuffer();
/* Try twice to test ANSI capabilities. */
for(nCount = 0; nCount < ANSI_TRIES; ++nCount)
{
/* Send a string that an ANSI capable terminal will usually */
/* respond to. */
od_disp(ANSI_QUERY, strlen(ANSI_QUERY), FALSE);
/* Wait for response expected from an ANSI terminal, for up to */
/* 12/18.2 second. */
if(ODWaitNoCase(ANSI_RESPONSE, ANSI_WAIT))
{
/* If expected sequence was received, turn on ANSI mode and */
/* exit the loop. */
od_control.user_ansi = TRUE;
break;
}
}
od_clear_keybuffer();
}
/* If user_rip is not set, attempt to determine RIP capabilities. */
if(!od_control.user_rip)
{
/* Clear inbound keyboard buffer. */
od_clear_keybuffer();
/* Try twice to test RIP capabilities. */
for(nCount = 0; nCount < RIP_TRIES; ++nCount)
{
/* Send a string that a RIP capable terminal will usually */
/* respond to. */
od_disp(RIP_QUERY, strlen(RIP_QUERY), FALSE);
/* Wait for response expected from a RIP terminal. */
if(ODWaitNoCase(RIP_RESPONSE, RIP_WAIT))
{
/* If expected sequence was received, turn on RIP mode and */
/* exit the loop. */
od_control.user_rip = TRUE;
break;
}
}
od_clear_keybuffer();
}
OD_API_EXIT();
}
/* ----------------------------------------------------------------------------
* ODWaitNoCase() *** PRIVATE FUNCTION ***
*
* Waits up to the specified maximum time for a specified string to be sent
* from the remote system. String matching is not case sensitive.
*
* Parameters: pszWaitFor - String to wait for.
*
* WaitTime - Maximum time, in milliseconds, to wait.
*
* Return: TRUE on success, FALSE on failure.
*/
static char ODWaitNoCase(char *pszWaitFor, tODMilliSec WaitTime)
{
tODTimer Timer;
char szReceived[MATCH_LEN + 1];
int nCount;
char chReceived;
int nMatchChars = MIN(MATCH_LEN, strlen(pszWaitFor));
ASSERT(pszWaitFor != NULL);
ASSERT(strlen(pszWaitFor) != 0);
ASSERT(WaitTime >= 0);
ODTimerStart(&Timer, WaitTime);
for(nCount = 0; nCount <= MATCH_LEN; ++nCount)
{
szReceived[nCount] = '\0';
}
do
{
if((chReceived = od_get_key(FALSE)) != 0)
{
for(nCount = 0; nCount < MATCH_LEN - 1; ++ nCount)
{
szReceived[nCount] = szReceived[nCount + 1];
}
szReceived[MATCH_LEN - 1] = chReceived;
if(strnicmp(szReceived + (MATCH_LEN - nMatchChars), pszWaitFor,
nMatchChars) == 0)
{
return(TRUE);
}
}
} while(!ODTimerElapsed(&Timer));
return(FALSE);
}

View File

@ -0,0 +1,832 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODBlock.c
*
* Description: Implements the text block manipulation functions.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Oct 13, 1994 6.00 BP New file header format.
* Dec 09, 1994 6.00 BP Standardized coding style.
* Aug 19, 1995 6.00 BP 32-bit portability.
* Nov 11, 1995 6.00 BP Removed register keyword.
* Nov 14, 1995 6.00 BP Added include of odscrn.h.
* Nov 16, 1995 6.00 BP Removed oddoor.h, added odcore.h.
* Dec 12, 1995 6.00 BP Added entry, exit and kernel macros.
* Dec 30, 1995 6.00 BP Added ODCALL for calling convention.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
* Aug 10, 2003 6.23 SH *nix support
*/
#define BUILDING_OPENDOORS
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "OpenDoor.h"
#include "ODCore.h"
#include "ODGen.h"
#include "ODScrn.h"
#include "ODKrnl.h"
/* Set to TRUE when od_puttext() should leave the cursor in its original */
/* position */
static BOOL bScrollAction = TRUE;
/* ----------------------------------------------------------------------------
* od_puttext()
*
* Displays the contents of the buffer passed in block. Leaves cursor in
* original position, unless bScrollAction is FALSE. Leaves colour at
* original value.
*
* Parameters: nLeft - Column number of left edge of block of text to
* transfer, where 1 is the leftmost column of the
* screen.
*
* nTop - Row number of the top edge of block of text to
* to transfer, where 1 is the top row of the screen.
*
* nRight - Column number of the right edge of block.
*
* nBottom - Row number of bottom edge of block.
*
* pBlock - Pointer to buffer that has been filled in the format
* used by od_gettext().
*
* Return: TRUE on success, FALSE on failure.
*/
ODAPIDEF BOOL ODCALL od_puttext(INT nLeft, INT nTop, INT nRight, INT nBottom,
void *pBlock)
{
INT nRowLength = nRight - nLeft +1;
INT nRowBytes = nRowLength * 2;
char *pchTest;
char *pchMemory;
char *pBuffer=NULL;
char *pchScreenBlock;
INT nBlockRow = 0;
INT nOutRow;
INT nOutColour = 999;
INT nOutColumn, nCheckColumn;
char *pchMemBlock;
INT nMoveCost = od_control.user_avatar ? 4 : 7;
BYTE btMaxRight, btMaxBottom;
/* Log function entry if running in trace mode. */
TRACE(TRACE_API, "od_puttext()");
/* Ensure that OpenDoors is initialized before proceeding. */
if(!bODInitialized) od_init();
OD_API_ENTRY();
/* Get current display setting profile. */
ODScrnGetTextInfo(&ODTextInfo);
/* Calculate the maximum values for bottom and right of block. */
btMaxRight=ODTextInfo.winright-ODTextInfo.winleft+1;
btMaxBottom=ODTextInfo.winbottom-ODTextInfo.wintop+1;
/* Check that parameters seem reasonable. */
if(nLeft<1 || nTop<1 || nRight>btMaxRight || nBottom>btMaxBottom
|| nTop > nBottom || nLeft > nRight || pBlock==NULL)
{
od_control.od_error = ERR_PARAMETER;
OD_API_EXIT();
return(FALSE);
}
/* Ensure that ANSI and/or AVATAR mode is available. */
if(!od_control.user_ansi && !od_control.user_avatar)
{
od_control.od_error = ERR_NOGRAPHICS;
OD_API_EXIT();
return(FALSE);
}
/* If OpenDoors is operating in remote mode. */
if(od_control.baud != 0)
{
/* Allocate temporary buffer to store original screen contents while */
/* buffer paste is being performed. */
if((pBuffer=malloc(nRowBytes*(nBottom-nTop+1)))==NULL)
{
od_control.od_error = ERR_MEMORY;
OD_API_EXIT();
return(FALSE);
}
/* Get current screen contents of area to be pasted into, storing */
/* into the temporary buffer. */
if(!ODScrnGetText((BYTE)nLeft, (BYTE)nTop, (BYTE)nRight, (BYTE)nBottom,
pBuffer))
{
od_control.od_error = ERR_PARAMETER;
free(pBuffer);
OD_API_EXIT();
return(FALSE);
}
}
/* Display the block to be pasted on the local screen. */
if(!ODScrnPutText((BYTE)nLeft, (BYTE)nTop, (BYTE)nRight, (BYTE)nBottom,
pBlock))
{
od_control.od_error = ERR_PARAMETER;
if(pBuffer)
free(pBuffer);
OD_API_EXIT();
return(FALSE);
}
/* If operating in remote mode. */
if(od_control.baud != 0)
{
/* Loop for each line in the buffer to be pasted */
for(nOutRow=nTop;nOutRow<=nBottom;++nOutRow,++nBlockRow)
{
/* Setup pointer to beginning of line of original screen contents. */
pchScreenBlock=(char *)pBuffer+(nRowBytes*nBlockRow);
/* Setup pointer to beginning of line of block to be displayed. */
pchMemBlock=(char *)pBlock+(nRowBytes*nBlockRow);
/* Loop for each column on this line. */
for(nOutColumn=0;nOutColumn<nRowLength;)
{
/* Loop from this character onwards, counting number of */
/* characters that don't need to be changed. */
nCheckColumn=nOutColumn;
pchMemory=((char *)pchMemBlock)+(nCheckColumn<<1);
pchTest=((char *)pchScreenBlock)+(nCheckColumn<<1);
for(;nCheckColumn<nRowLength;++nCheckColumn)
{
if(od_control.od_full_put) break;
/* If both buffers have space characters. */
if((*pchMemory==' ' || *pchMemory==0) && (*pchTest==' ' || *pchTest=='\0'))
{
/* If background colours differ, then stop comparison loop. */
if((pchTest[1]&0x70) != (pchMemory[1]&0x70))
{
break;
}
}
/* If both have different character and colour attributes. */
else if(*((WORD *)pchTest) != *((WORD *)pchMemory))
{
/* Then stop comparison loop now. */
break;
}
/* Increment source and background pointers by two bytes. */
pchTest+=2;
pchMemory+=2;
}
/* If no futher text to change on this line. */
if(nCheckColumn==nRowLength)
{
/* Move to the next line. */
goto next_line;
}
/* If this is the first text to be displayed on this line. */
if(nOutColumn == 0)
{
/* Move the cursor to the first text to be changed on line. */
nOutColumn = nCheckColumn;
/* If AVATAR mode is available. */
if(od_control.user_avatar)
{
/* Send the avatar cursor positioning command. */
szODWorkString[0]=22;
szODWorkString[1]=8;
szODWorkString[2]=nOutRow;
szODWorkString[3]=nLeft+nOutColumn;
od_disp(szODWorkString,4,FALSE);
}
else
{
/* Otherwise, send the ANSI cursor positioning command. */
sprintf(szODWorkString,"x[%d;%dH",nOutRow,nLeft + nOutColumn);
szODWorkString[0]=27;
od_disp(szODWorkString, strlen(szODWorkString), FALSE);
}
}
/* If the number of characters after current cursor position */
/* which must be changed, is greater than the number of */
/* characters required to reposition the cursor on this line, */
/* then move the cursor to skip unchanged characters. */
else if((nCheckColumn-nOutColumn)>nMoveCost)
{
nOutColumn=nCheckColumn;
/* If AVATAR mode is available. */
if(od_control.user_avatar)
{
/* Advance cursor appropriate number of characters */
/* using the AVATAR cursor position command. */
szODWorkString[0]=22;
szODWorkString[1]=8;
szODWorkString[2]=nOutRow;
szODWorkString[3]=nLeft+nOutColumn;
od_disp(szODWorkString,4,FALSE);
}
else
{
/* Otherwise, advance cursor appropriate number of */
/* characters using the ANSI cursor position command. */
sprintf(szODWorkString,"x[%d;%dH",nOutRow,nLeft + nOutColumn);
szODWorkString[0]=27;
od_disp(szODWorkString,strlen(szODWorkString),FALSE);
}
}
/* Output text for the number of characters found to be */
/* different. */
pchTest=(char *)&pchMemBlock[nOutColumn*2];
for(;nOutColumn<=nCheckColumn;++nOutColumn)
{
if(pchTest[1] != nOutColour)
{
od_set_attrib(nOutColour=pchTest[1]);
}
od_disp(pchTest,1,FALSE);
pchTest++;
pchTest++;
}
}
next_line:
;
}
/* If not disabled, update cursor position. */
if(bScrollAction)
{
od_set_cursor(ODTextInfo.cury,ODTextInfo.curx);
}
/* Deallocate temporary buffer. */
free(pBuffer);
}
/* Restore the original display attribute. */
od_set_attrib(ODTextInfo.attribute);
/* Return with success. */
OD_API_EXIT();
return(TRUE);
}
/* ----------------------------------------------------------------------------
* od_gettext()
*
* Retrieves text from the screen (based on what is current displayed on the
* local display), storing it in the buffer provided by the caller.
*
* Parameters: nLeft - Column number of left edge of block of text to
* transfer, where 1 is the leftmost column of the
* screen.
*
* nTop - Row number of the top edge of block of text to
* to transfer, where 1 is the top row of the screen.
*
* nRight - Column number of the right edge of block.
*
* nBottom - Row number of bottom edge of block.
*
* pBlock - Pointer to buffer large enough to hold two bytes
* for each character in the block.
*
* Return: TRUE on success, FALSE on failure.
*/
ODAPIDEF BOOL ODCALL od_gettext(INT nLeft, INT nTop, INT nRight, INT nBottom,
void *pBlock)
{
BYTE btMaxRight, btMaxBottom;
/* Log function entry if running in trace mode. */
TRACE(TRACE_API, "od_gettext()");
/* Initialize OpenDoors if not already done. */
if(!bODInitialized) od_init();
OD_API_ENTRY();
ODScrnGetTextInfo(&ODTextInfo);
btMaxRight=ODTextInfo.winright-ODTextInfo.winleft+1;
btMaxBottom=ODTextInfo.winbottom-ODTextInfo.wintop+1;
if(nLeft<1 || nTop<1 || nRight>btMaxRight || nBottom>btMaxBottom || !pBlock)
{
od_control.od_error = ERR_PARAMETER;
OD_API_EXIT();
return(FALSE);
}
if(!od_control.user_ansi && !od_control.user_avatar)
{
od_control.od_error = ERR_NOGRAPHICS;
OD_API_EXIT();
return(FALSE);
}
OD_API_EXIT();
return(ODScrnGetText((BYTE)nLeft, (BYTE)nTop, (BYTE)nRight, (BYTE)nBottom,
pBlock));
}
/* ----------------------------------------------------------------------------
* od_scroll()
*
* Scrolls the specified area of the screen by the specified number of
* lines, in either the up or down directions. The cursor is left at its
* original locaiton, and the display attribute is left at its original
* setting. New lines are created in the current display colour.
*
* Parameters: nLeft - Column number of left edge of area to scroll, where
* 1 is the leftmost column of the screen.
*
* nTop - Row number of the top edge of the area to scroll,
* where 1 is the top row of the screen.
*
* nRight - Column number of the right edge of area to scroll.
*
* nBottom - Row number of bottom edge of area to scroll.
*
* nDistance - Number of lines to scroll the text. A value of 0
* has no effect on the specified area, a positive
* value moves the text upwards (leaving blank lines
* at the bottom of the specified area), while a
* negative value moves the text upwards. If the
* distance is equal to the number of lines in the
* area, then the entire area is cleared.
*
* nFlags - Bitwise-or (|) of SCROLL_* flags. SCROLL_NORMAL
* is the default. SCROLL_NO_CLEAR does not clear
* the new area at the top/bottom of the scroll
* region if doing so would be slower.
*
* Return: TRUE on success, FALSE on failure.
*/
ODAPIDEF BOOL ODCALL od_scroll(INT nLeft, INT nTop, INT nRight, INT nBottom,
INT nDistance, WORD nFlags)
{
BYTE btWidth, btHeight;
BYTE btCount;
BYTE btFirst, btLast;
char szAVTSeq[7];
void *pBlock;
char szBlank[81];
BYTE btKeepHeight;
BYTE btMaxRight;
BYTE btMaxBottom;
tODScrnTextInfo TextState;
/* Log function entry if running in trace mode. */
TRACE(TRACE_API, "od_scroll()");
/* Ensure that OpenDoors has been initialized before proceeding. */
if(!bODInitialized) od_init();
OD_API_ENTRY();
/* Get current display setting information. */
ODScrnGetTextInfo(&TextState);
/* Determine the height and width of the area to be scrolled. */
btWidth=nRight-nLeft+1;
btHeight=nBottom-nTop+1;
/* Determine the number of lines currently in the area that will still */
/* be visible after scrolling. */
btKeepHeight=btHeight-((nDistance>=0) ? nDistance : -nDistance);
/* Determine the maximum bottom and left coordinates of an area to be */
/* scrolled. */
btMaxRight=TextState.winright-TextState.winleft+1;
btMaxBottom=TextState.winbottom-TextState.wintop+1;
/* Check that parameters are valid. */
if(nLeft<1 || nTop<1 || nRight>btMaxRight || nBottom>btMaxBottom ||
nLeft > nRight || nTop > nBottom)
{
od_control.od_error = ERR_PARAMETER;
OD_API_EXIT();
return(FALSE);
}
/* Check that ANSI or AVATAR graphics mode is available. */
if(!od_control.user_ansi && !od_control.user_avatar)
{
od_control.od_error = ERR_NOGRAPHICS;
OD_API_EXIT();
return(FALSE);
}
/* If distance to be scrolled is 0, then we are finished already and */
/* can return immediately. */
if(nDistance == 0)
{
OD_API_EXIT();
return(TRUE);
}
/* If distance is positive, then we are moving text upwards. */
if(nDistance>0)
{
/* Ensure that distance is not greater than size of scrolled area. */
if(nDistance>btHeight)
{
nDistance=btHeight;
}
/* Calculate first and last line to be moved. */
btFirst=nBottom-(nDistance-1);
btLast=nBottom;
}
/* If distance is negative, then we are moving text downwards. */
else /* if(nDistance<0) */
{
/* Ensure that distance is not greater than size of scrolled area. */
if(nDistance<-btHeight)
{
nDistance=-btHeight;
}
/* Calculate first and last line to be moved. */
btFirst=nTop;
btLast=nTop-nDistance-1;
}
/* If AVATAR mode is available */
if(od_control.user_avatar)
{
/* Generate AVATAR sequence which causes the remote terminal to */
/* scroll an area of its screen. */
szAVTSeq[0]=22;
/* If scrolling text upwards. */
if(nDistance>0)
{
/* Specify control sequence for scrolling upwards. */
szAVTSeq[1]=10;
szAVTSeq[2]=nDistance;
/* Move text appropriate direction on local screen. */
ODScrnCopyText((BYTE)nLeft, (BYTE)(nTop + nDistance), (BYTE)nRight,
(BYTE)nBottom, (BYTE)nLeft, (BYTE)nTop);
}
/* If scrolling text downwards. */
else /* if(disatnce<0) */
{
/* Specify control sequence for scrolling downwards. */
szAVTSeq[1]=11;
szAVTSeq[2]=-nDistance;
/* Move text appropriate direction on local screen. */
ODScrnCopyText((BYTE)nLeft, (BYTE)nTop, (BYTE)nRight,
(BYTE)(nBottom + nDistance), (BYTE)nLeft, (BYTE)(nTop - nDistance));
}
/* Specify area to be scrolled to the AVATAR terminal. */
szAVTSeq[3]=nTop;
szAVTSeq[4]=nLeft;
szAVTSeq[5]=nBottom;
szAVTSeq[6]=nRight;
/* Send the control sequence to the AVATAR terminal. */
od_disp(szAVTSeq,7,FALSE);
/* Generate string containing a blank line of text. */
for(btCount=0;btCount<btWidth;++btCount) szBlank[btCount]=' ';
szBlank[btCount]='\0';
/* Blank-out lines that will no longer be visiable. */
for(;btFirst<=btLast;++btFirst)
{
ODScrnSetCursorPos((BYTE)nLeft, btFirst);
ODScrnDisplayString(szBlank);
}
/* Reset cursor position on local display. */
ODScrnSetCursorPos(TextState.curx,TextState.cury);
}
/* Otherwise, we are using ANSI mode. */
else /* if(od_control.user_ansi) */
{
/* If any of the original text will still be available after */
/* scrolling. */
if(btKeepHeight>0)
{
/* Allocate some temporary memory to hold text to be "got". */
if((pBlock=malloc(btKeepHeight*btWidth*2))==NULL)
{
/* If memory allocation failed, then scrolling fails. */
od_control.od_error = ERR_MEMORY;
OD_API_EXIT();
return(FALSE);
}
/* If we are scrolling text upwards. */
if(nDistance > 0)
{
/* Move text that will still be visible, using od_gettext() */
/* and od_puttext(). */
od_gettext(nLeft,nTop+nDistance,nRight,nBottom,pBlock);
bScrollAction=FALSE;
od_puttext(nLeft,nTop,nRight,nBottom-nDistance,pBlock);
bScrollAction=TRUE;
}
/* If we are scrolling text downwards. */
else /* if(nDistance < 0) */
{
/* Move text that will still be visible, using od_gettext() */
/* and od_puttext(). */
od_gettext(nLeft,nTop,nRight,nBottom+nDistance,pBlock);
bScrollAction=FALSE;
od_puttext(nLeft,nTop-nDistance,nRight,nBottom,pBlock);
bScrollAction=TRUE;
}
/* Deallocate temporary memory block. */
free(pBlock);
}
/* If new area clearing has not been disabled. */
if(!(nFlags&SCROLL_NO_CLEAR))
{
/* Loop for lines that should be blank. */
for(;btFirst<=btLast;++btFirst)
{
/* Move cursor to the beginning of this line. */
od_set_cursor(btFirst,nLeft);
/* If right boarder of area to be scrolled is the edge of the */
/* screen, then we can use a quick control sequence to clear */
/* the rest of the line. Call od_clr_line() to do this. */
if(nRight == 80)
{
od_clr_line();
}
/* If right boarder of area to be scrolled is not at the edge */
/* of the screen, then each line must be manually erased, by */
/* sending the appropriate number of blanks (spaces). */
else /* if(right != 80) */
{
od_repeat(' ',btWidth);
}
}
}
/* Reset the cursor to its original position. */
od_set_cursor(TextState.cury,TextState.curx);
}
/* Return with success */
OD_API_EXIT();
return(TRUE);
}
/* ----------------------------------------------------------------------------
* od_save_screen()
*
* Stores the contents of the entire screen into a buffer, along with
* the current cursor location and display colour. Supports all display
* modes.
*
* Parameters: pBuffer - Pointer to a buffer of at least 4004 bytes in size,
* where the information on the current screen state
* will be stored.
*
* Return: TRUE on success, FALSE on failure.
*/
ODAPIDEF BOOL ODCALL od_save_screen(void *pBuffer)
{
char btHeight;
tODScrnTextInfo TextState;
/* Log function entry if running in trace mode. */
TRACE(TRACE_API, "od_save_screen()");
/* Ensure that OpenDoors is initialized before proceeding. */
if(!bODInitialized) od_init();
OD_API_ENTRY();
/* Check parameters and current output window size. */
ODScrnGetTextInfo(&TextState);
if(TextState.winleft!=1 || TextState.winright!=80 || !pBuffer)
{
od_control.od_error = ERR_PARAMETER;
OD_API_EXIT();
return(FALSE);
}
/* Store current cursor location in buffer. */
((char *)pBuffer)[0]=TextState.curx;
((char *)pBuffer)[1]=TextState.cury;
/* Store current display colour in buffer. */
((char *)pBuffer)[2]=TextState.attribute;
/* Store height of buffer stored. */
((char *)pBuffer)[3]=btHeight=TextState.winbottom-TextState.wintop+1;
/* Store screen contents using local screen gettext() function. */
OD_API_EXIT();
return(ODScrnGetText(1,1,80,btHeight,(char *)pBuffer+4));
}
/* ----------------------------------------------------------------------------
* od_restore_screen()
*
* Restores the screen contents, along with the current text colour and cursor
* location, as previously stored by od_save_screen().
*
* Parameters: pBuffer - Pointer to buffer which was filled by a previous call
* to od_save_screen().
*
* Return: TRUE on success, FALSE on failure.
*/
ODAPIDEF BOOL ODCALL od_restore_screen(void *pBuffer)
{
char *pch;
char btPos;
char chLast;
char *pchTextBuffer;
char btHeight;
int nToReturn=TRUE;
tODScrnTextInfo TextState;
char btLine;
char btDistance=0;
char btCursorRow;
/* Log function entry if running in trace mode. */
TRACE(TRACE_API, "od_restore_screen()");
/* Ensure that OpenDoors is initialized before proceeding. */
if(!bODInitialized) od_init();
OD_API_ENTRY();
/* Check parameters and current output window size. */
ODScrnGetTextInfo(&TextState);
if(TextState.winleft!=1 || TextState.winright!=80 || !pBuffer)
{
od_control.od_error = ERR_PARAMETER;
OD_API_EXIT();
return(FALSE);
}
/* Determine current window height were text will be restored. */
btHeight=TextState.winbottom-TextState.wintop+1;
/* If current display window height is too small for entire buffer */
/* to be re-displayed. */
if(btHeight<((char *)pBuffer)[3])
{
/* Then we will always display as much of the END of the buffer */
/* as possible. */
btDistance = btHeight - ((char *)pBuffer)[3];
}
else if(btHeight > ((char *)pBuffer)[3])
{
/* Otherwise, ensure that we don't try to display more lines that */
/* are in the buffer. */
btHeight=((char *)pBuffer)[3];
}
/* Clear the remote and local screens. */
od_clr_scr();
/* If ANSI or AVATAR modes are available. */
if(od_control.user_avatar || od_control.user_ansi)
{
/* Then we can efficiently display the buffer using od_puttext(). */
bScrollAction=FALSE;
nToReturn=od_puttext(1,1,80,btHeight,(char *)pBuffer+(4+((int)btDistance*160)));
bScrollAction=TRUE;
/* Restore original cursor location. */
od_set_cursor(((char *)pBuffer)[1],((char *)pBuffer)[0]);
/* Restore original display attribute. */
od_set_attrib(((char *)pBuffer)[2]);
}
/* If we are operating in ASCII mode. */
else /* if (!od_control.od_avatar && !od_control.caller_ansi) */
{
/* Then the buffer is displayed one line at a time, beginning */
/* at the top of the screen, up to the saved cusrsor location. */
/* Set pointer to beginning of buffer to be displayed. */
pchTextBuffer=(char *)pBuffer+4;
/* Get final cursor row number. */
btCursorRow=((char *)pBuffer)[1];
/* Loop for each line in the buffer. */
for(btLine=1;btLine<=btHeight;++btLine)
{
/* Set pointer to last character of line. */
pch=(char *)pchTextBuffer+158;
/* Loop backwards until a non-blank character is found, or we */
/* reach the beginning of the line. */
for(chLast=80;chLast>1;)
{
/* If this is a blank character. */
if(*pch==32 || *pch==0)
{
/* Move to previous character. */
--chLast;
pch-=2;
}
/* If this is not a blank character, then stop looping. */
else
{
break;
}
}
/* If this is the line on which the cursor resides. */
if(btLine==btCursorRow)
{
/* If last non-blank character of line is at or past the final */
/* cursor location, then we backup the last character to be */
/* displayed to the cursor before the final cursor position. */
/* This code could be improved to be able to display text on */
/* the entire cursor line by displaying the entire line, */
/* sending a C/R, and redisplaying first portion of line to */
/* end up with the cursor in the desired position. */
if(chLast>=((char *)pBuffer)[0])
{
chLast=((char *)pBuffer)[0]-1;
}
}
/* Display all characters on this line */
pch = (char *)pchTextBuffer;
for(btPos=1;btPos<=chLast;++btPos)
{
od_putch(*pch);
pch+=2;
}
/* If this is the row where the cursor should be left, then we */
/* stop displaying now. */
if(btLine==btCursorRow)
{
break;
}
/* If cursor hasn't been wrapped, then we should send a C/R - */
/* L/F sequence. */
if(chLast != 80)
{
od_disp_str("\n\r");
pchTextBuffer+=160;
}
}
}
/* Return with the appropriate success/failure status. */
OD_API_EXIT();
return(nToReturn);
}

View File

@ -0,0 +1,933 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODCFile.c
*
* Description: Implements the configuration file sub-system.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Oct 13, 1994 6.00 BP New file header format.
* Dec 09, 1994 6.00 BP Standardized coding style.
* Nov 11, 1995 6.00 BP 32-bit portability.
* Nov 11, 1995 6.00 BP Removed register keyword.
* Nov 16, 1995 6.00 BP Removed oddoor.h, added odcore.h.
* Dec 30, 1995 6.00 BP Added ODCALL for calling convention.
* Jan 01, 1996 6.00 BP Added DisableDTR and NoDTRDisable.
* Jan 19, 1996 6.00 BP Display error if config file not found
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
* Mar 19, 1996 6.10 BP MSVC15 source-level compatibility.
* Aug 10, 2003 6.23 SH *nix support
*/
#define BUILDING_OPENDOORS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include "OpenDoor.h"
#include "ODStr.h"
#include "ODCore.h"
#include "ODGen.h"
#include "ODInEx.h"
#include "ODUtil.h"
/* Internal private variables */
static WORD awTimeVal[3];
static BYTE btTimeNumVals;
/* Local functions. */
static WORD ODCfgGetWordDecimal(char *pszConfigText);
static DWORD ODCfgGetDWordDecimal(char *pszConfigText);
static WORD ODCfgGetWordHex(char *pszConfigText);
static void ODCfgGetNextTime(char **ppchConfigText);
static BOOL ODCfgIsTrue(char *pszConfigText);
/* ----------------------------------------------------------------------------
* ODConfigInit()
*
* Called to perform OpenDoors initialization when the configuration file
* system is being used. This function is called from the normal od_init(),
* and also uses the normal od_init() to perform base initialization after
* the configuration file has been read, but before certain configuration
* settings are set in od_control.
*
* Parameters: none
*
* Return: void
*/
ODAPIDEF void ODCALL ODConfigInit(void)
{
void (*custom_line_function)(char *keyword, char *options)
= od_control.config_function;
char *pchConfigText;
WORD wCurrent;
INT nConfigOption;
BOOL bConfigFileRequired = TRUE;
static FILE *pfConfigFile;
static FILE *pfCustomDropFile = NULL;
static char szConfigLine[257];
static char szToken[33];
static char szTempString[256];
static char szWorkDir[80];
static BOOL bWorkDirSet = FALSE;
static time_t nUnixTime;
static struct tm *TimeBlock;
static INT16 nPageStart;
static INT16 nPageEnd;
static BOOL bPageSet = FALSE;
static BOOL bInactivitySet = FALSE;
static INT16 nInactivity;
static char *pszWork;
static BOOL bPageLengthSet = FALSE;
static BYTE btPageLength;
static char *apszFileNames[1];
bIsCallbackActive = TRUE;
nUnixTime = time(NULL);
TimeBlock = localtime(&nUnixTime);
/* Use default configuration file filename if none has been specified. */
if(od_control.od_config_filename == NULL)
{
od_control.od_config_filename = "door.cfg";
bConfigFileRequired = FALSE;
}
if((pfConfigFile = fopen(od_control.od_config_filename, "rt")) == NULL)
{
if(strchr(od_control.od_config_filename, DIRSEP) != NULL
|| strchr(od_control.od_config_filename, ':') != NULL)
{
wCurrent = strlen(od_control.od_config_filename);
pchConfigText = (char *)od_control.od_config_filename + (wCurrent - 1);
while(wCurrent > 0)
{
if(*pchConfigText == DIRSEP || *pchConfigText == ':')
{
strcpy(szConfigLine, (char *)pchConfigText + 1);
pfConfigFile = fopen(szConfigLine, "rt");
break;
}
--pchConfigText;
--wCurrent;
}
}
else
{
strcpy(szConfigLine, od_control.od_config_filename);
}
}
/* If we were able to open the configuration file. */
if(pfConfigFile != NULL)
{
/* Get configuration file strings in upper case. */
for(wCurrent = 0; wCurrent < TEXT_SIZE; ++wCurrent)
{
strupr(od_config_text[wCurrent]);
}
for(wCurrent = 0; wCurrent < LINES_SIZE; ++wCurrent)
{
strupr(od_config_lines[wCurrent]);
}
for(;;)
{
/* Read the next line from the configuration file. */
if(fgets(szConfigLine, 257, pfConfigFile) == NULL) break;
/* Ignore all of line after comments or CR/LF char. */
pchConfigText = (char *)szConfigLine;
while(*pchConfigText)
{
if(*pchConfigText == '\n' || *pchConfigText == '\r'
|| *pchConfigText == ';')
{
*pchConfigText = '\0';
break;
}
++pchConfigText;
}
/* Search for beginning of first token on line. */
pchConfigText = (char *)szConfigLine;
while(*pchConfigText
&& (*pchConfigText == ' ' || *pchConfigText == '\t'))
{
++pchConfigText;
}
if(!*pchConfigText) continue;
/* Get first token from line. */
wCurrent = 0;
while(*pchConfigText
&& !(*pchConfigText == ' ' || *pchConfigText == '\t'))
{
if(wCurrent < 32) szToken[wCurrent++] = *pchConfigText;
++pchConfigText;
}
if(wCurrent <= 32)
{
szToken[wCurrent] = '\0';
}
else
{
szToken[32] = '\0';
}
strupr(szToken);
/* Find beginning of configuration option parameters */
while(*pchConfigText && (*pchConfigText == ' '
|| *pchConfigText == '\t'))
{
++pchConfigText;
}
/* Trim trailing spaces from setting string. */
for(wCurrent = strlen(pchConfigText) - 1; wCurrent > 0; --wCurrent)
{
if(pchConfigText[wCurrent] == ' '
|| pchConfigText[wCurrent] == '\t')
{
pchConfigText[wCurrent] = '\0';
}
else
{
break;
}
}
for(wCurrent = 0; wCurrent < TEXT_SIZE; ++wCurrent)
{
if(strcmp(szToken, od_config_text[wCurrent]) == 0)
{
switch(wCurrent)
{
case 0:
wODNodeNumber = ODCfgGetWordDecimal(pchConfigText);
break;
case 1:
strcpy(od_control.info_path,pchConfigText);
break;
case 2:
if(pchConfigText[strlen(pchConfigText) - 1] == DIRSEP
&& pchConfigText[strlen(pchConfigText) - 2] != ':'
&& strlen(pchConfigText) > 1)
{
pchConfigText[strlen(pchConfigText) - 1] = '\0';
}
szOriginalDir = (char *)malloc(256);
if(szOriginalDir != NULL)
{
ODDirGetCurrent(szOriginalDir, 256);
}
strcpy(szWorkDir, pchConfigText);
bWorkDirSet = TRUE;
break;
case 3:
strcpy(od_control.od_logfile_name, pchConfigText);
break;
case 4:
od_control.od_logfile_disable = TRUE;
break;
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
if((wCurrent - 5) == (WORD)TimeBlock->tm_wday)
{
ODCfgGetNextTime((char **)&pchConfigText);
nPageStart = awTimeVal[0] * 60 + awTimeVal[1];
ODCfgGetNextTime((char **)&pchConfigText);
nPageEnd = awTimeVal[0] * 60 + awTimeVal[1];
bPageSet = TRUE;
}
break;
case 12:
od_control.od_maxtime = ODCfgGetWordDecimal(pchConfigText);
break;
case 13:
bSysopNameSet = TRUE;
strncpy((char *)&szForcedSysopName, pchConfigText, 39);
szForcedSysopName[39] = '\0';
break;
case 14:
bSystemNameSet = TRUE;
strncpy((char *)&szForcedSystemName, pchConfigText, 39);
szForcedSystemName[39] = '\0';
break;
case 15:
od_control.od_swapping_disable = TRUE;
break;
case 16:
strncpy(od_control.od_swapping_path, pchConfigText, 79);
od_control.od_swapping_path[79] = '\0';
break;
case 17:
od_control.od_swapping_noems = TRUE;
break;
case 18:
dwForcedBPS = ODCfgGetDWordDecimal(pchConfigText);
break;
case 19:
nForcedPort = ODCfgGetWordDecimal(pchConfigText);
break;
case 20:
if(pfCustomDropFile == NULL && !od_control.od_force_local)
{
apszFileNames[0] = (char *)pchConfigText;
if(ODSearchForDropFile(apszFileNames, 1, szTempString,
NULL) != -1)
{
if((pfCustomDropFile = fopen(szTempString, "rt"))
!= NULL)
{
od_control.od_info_type = CUSTOM;
od_control.user_attribute = 0x06;
od_control.user_screen_length = 23;
od_control.user_ansi = TRUE;
od_control.user_rip = FALSE;
od_control.user_avatar = FALSE;
od_control.od_page_pausing = TRUE;
od_control.od_page_len = 15;
od_control.user_timelimit = 0;
strcpy(od_control.user_name, "Unknown User");
strcpy(od_control.user_location,
"Unknown Location");
od_control.user_security = 1;
}
}
}
break;
case 21:
if(pfCustomDropFile != NULL)
{
if(fgets(szTempString, 255, pfCustomDropFile)!=NULL)
{
if(szTempString[strlen(szTempString) - 1] == '\n')
{
szTempString[strlen(szTempString) - 1] = '\0';
}
else
{
INT ch;
do
{
ch = fgetc(pfCustomDropFile);
} while(ch != '\n' && ch != EOF);
}
if(szTempString[strlen(szTempString) - 1] == '\r')
{
szTempString[strlen(szTempString) - 1] = '\0';
}
strupr(pchConfigText);
for(nConfigOption = 0; nConfigOption < LINES_SIZE;
++nConfigOption)
{
if(strcmp(pchConfigText,
od_config_lines[nConfigOption]) == 0)
{
switch(nConfigOption)
{
case 1:
od_control.port =
ODCfgGetWordDecimal(szTempString) - 1;
break;
case 2:
od_control.port =
ODCfgGetWordDecimal(szTempString);
break;
case 3:
od_control.baud =
ODCfgGetWordDecimal(szTempString);
break;
case 4:
if(ODCfgIsTrue(szTempString))
{
#ifdef ODPLAT_NIX
od_control.baud = 1;
#else
od_control.baud = 0;
#endif
}
break;
case 5:
case 6:
ODStringToName(szTempString);
strncpy(od_control.user_name,
szTempString, 34);
od_control.user_name[34] = '\0';
break;
case 7:
strcat(od_control.user_name, " ");
ODStringToName(szTempString);
strncat(od_control.user_name,
szTempString,
35 - strlen(od_control.user_name));
od_control.user_name[35] = '\0';
break;
case 8:
ODStringToName(szTempString);
strncpy(od_control.user_handle,
szTempString, 35);
od_control.user_handle[35] = '\0';
break;
case 9:
pszWork = (char *)szTempString;
ODCfgGetNextTime((char **)&pszWork);
od_control.user_timelimit +=
(awTimeVal[0] * 60);
break;
case 10:
pszWork = (char *)szTempString;
ODCfgGetNextTime((char **)&pszWork);
if(btTimeNumVals <= 1)
{
od_control.user_timelimit +=
awTimeVal[0];
}
else
{
od_control.user_timelimit +=
awTimeVal[1] + (awTimeVal[0] * 60);
}
break;
case 11:
pszWork = (char *)szTempString;
ODCfgGetNextTime((char **)&pszWork);
if(btTimeNumVals <= 1)
{
od_control.user_timelimit +=
awTimeVal[0] / 60;
}
else if(btTimeNumVals == 2)
{
od_control.user_timelimit +=
(awTimeVal[1] / 60) + awTimeVal[0];
}
else
{
od_control.user_timelimit +=
(awTimeVal[2] / 60) + awTimeVal[1]
+ (awTimeVal[0] * 60);
}
break;
case 12:
od_control.user_ansi =
ODCfgIsTrue(szTempString);
break;
case 13:
od_control.user_avatar =
ODCfgIsTrue(szTempString);
break;
case 14:
od_control.od_page_pausing =
ODCfgIsTrue(szTempString);
break;
case 15:
od_control.user_screen_length =
ODCfgGetWordDecimal(szTempString);
break;
case 16:
if(ODCfgIsTrue(szTempString))
{
od_control.user_attribute |= 0x02;
}
else
{
od_control.user_attribute &=~ 0x02;
}
break;
case 17:
od_control.user_security =
ODCfgGetWordDecimal(szTempString);
break;
case 18:
ODStringToName(szTempString);
strncpy(od_control.user_location,
szTempString, 25);
od_control.user_location[25] = '\0';
break;
case 19:
wODNodeNumber =
ODCfgGetWordDecimal(szTempString);
break;
case 20:
case 21:
ODStringToName(szTempString);
strncpy(od_control.sysop_name,
szTempString, 38);
od_control.sysop_name[38] = '\0';
break;
case 22:
strcat(od_control.sysop_name, " ");
ODStringToName(szTempString);
strncat(od_control.sysop_name,
szTempString,
39 - strlen(od_control.system_name));
od_control.sysop_name[39] = '\0';
break;
case 23:
strncpy(od_control.system_name,
szTempString, 39);
od_control.system_name[39] = '\0';
break;
case 24:
od_control.user_rip =
ODCfgIsTrue(szTempString);
}
}
}
}
}
break;
case 22:
bInactivitySet = TRUE;
nInactivity = ODCfgGetWordDecimal(pchConfigText);
if(nInactivity < 0) nInactivity = 0;
break;
case 23:
btPageLength = (BYTE)ODCfgGetWordDecimal(pchConfigText);
bPageLengthSet = TRUE;
break;
case 24:
od_control.od_chat_color2 =
od_color_config(pchConfigText);
break;
case 25:
od_control.od_chat_color1 =
od_color_config(pchConfigText);
break;
case 26:
od_control.od_list_title_col =
od_color_config(pchConfigText);
break;
case 27:
od_control.od_list_name_col =
od_color_config(pchConfigText);
break;
case 28:
od_control.od_list_size_col =
od_color_config(pchConfigText);
break;
case 29:
od_control.od_list_comment_col =
od_color_config(pchConfigText);
break;
case 30:
od_control.od_list_offline_col =
od_color_config(pchConfigText);
break;
case 31:
strncpy(szDesiredPersonality, pchConfigText, 32);
szDesiredPersonality[32] = '\0';
break;
case 32:
/* "NoFossil" */
od_control.od_no_fossil = TRUE;
break;
case 33:
/* "PortAddress" */
od_control.od_com_address = ODCfgGetWordHex(pchConfigText);
break;
case 34:
/* "PortIRQ" */
od_control.od_com_irq =
(char)ODCfgGetWordDecimal(pchConfigText);
break;
case 35:
/* "ReceiveBuffer" */
od_control.od_com_rx_buf =
ODCfgGetWordDecimal(pchConfigText);
break;
case 36:
/* "TransmitBuffer" */
od_control.od_com_tx_buf =
ODCfgGetWordDecimal(pchConfigText);
break;
case 37:
/* "PagePromptColour" */
od_control.od_continue_col =
od_color_config(pchConfigText);
break;
case 38:
/* "LocalMode" */
od_control.od_force_local = TRUE;
break;
case 39:
/* "PopupMenuTitleColour" */
od_control.od_menu_title_col =
od_color_config(pchConfigText);
break;
case 40:
/* "PopupMenuBorderColour" */
od_control.od_menu_border_col =
od_color_config(pchConfigText);
break;
case 41:
/* "PopupMenuTextColour" */
od_control.od_menu_text_col =
od_color_config(pchConfigText);
break;
case 42:
/* "PopupMenuKeyColour" */
od_control.od_menu_key_col =
od_color_config(pchConfigText);
break;
case 43:
/* "PopupMenuHighlightColour" */
od_control.od_menu_highlight_col =
od_color_config(pchConfigText);
break;
case 44:
/* "PopupMenuHighKeyColour" */
od_control.od_menu_highkey_col =
od_color_config(pchConfigText);
break;
case 45:
/* "NoFIFO" */
od_control.od_com_no_fifo = TRUE;
break;
case 46:
/* "FIFOTriggerSize" */
od_control.od_com_fifo_trigger =
(BYTE)ODCfgGetWordDecimal(pchConfigText);
break;
case 47:
/* "DisableDTR" */
ODStringCopy(od_control.od_disable_dtr, pchConfigText,
sizeof(od_control.od_disable_dtr));
break;
case 48:
/* "NoDTRDisable" */
od_control.od_disable |= DIS_DTR_DISABLE;
break;
}
}
}
/* Check if command is a programmer customized option. */
if(wCurrent >= TEXT_SIZE && custom_line_function != NULL)
{
(*custom_line_function)((char *)&szToken, pchConfigText);
}
}
/* Close the configuration file. */
fclose(pfConfigFile);}
else
{
if(bConfigFileRequired)
{
od_control.od_error = ERR_FILEOPEN;
ODInitError("Unable to access configuration file.");
exit(od_control.od_errorlevel[1]);
}
}
/* Close custom door info file */
if(pfCustomDropFile != NULL)
{
fclose(pfCustomDropFile);
}
bIsCallbackActive = FALSE;
/* Carry out normal OpenDoors initialization. */
bCalledFromConfig = TRUE;
od_init();
bCalledFromConfig = FALSE;
/* Update any settings that need to be updated. */
if(bPageSet)
{
od_control.od_pagestartmin = nPageStart;
od_control.od_pageendmin = nPageEnd;
}
if(bInactivitySet && nInactivity != 0)
{
od_control.od_inactivity = nInactivity;
}
if(bSysopNameSet)
{
strcpy((char *)&od_control.sysop_name, (char *)&szForcedSysopName);
}
if(bSystemNameSet)
{
strcpy((char *)&od_control.system_name, (char *)&szForcedSystemName);
}
if(bPageLengthSet)
{
od_control.od_page_len = btPageLength;
}
if(bWorkDirSet)
{
ODDirChangeCurrent(szWorkDir);
}
}
/* ----------------------------------------------------------------------------
* ODCfgGetWordDecimal() *** PRIVATE FUNCTION ***
*
* Obtains the value of the next decimal number in the provided string, in the
* form of a WORD (16 bit value).
*
* Parameters: pszConfigText - String to examine.
*
* Return: The first number obtained from the string.
*/
static WORD ODCfgGetWordDecimal(char *pszConfigText)
{
ASSERT(pszConfigText != NULL);
/* Skip any initial non-numerical characters. */
while(*pszConfigText && (*pszConfigText < '0' || *pszConfigText > '9'))
{
++pszConfigText;
}
/* Return value of number. */
return(atoi(pszConfigText));
}
/* ----------------------------------------------------------------------------
* ODCfgGetDWordDecimal() *** PRIVATE FUNCTION ***
*
* Obtains the value of the next decimal number in the provided string, in the
* form of a DWORD (32 bit value).
*
* Parameters: pszConfigText - String to examine.
*
* Return: The first number obtained from the string.
*/
static DWORD ODCfgGetDWordDecimal(char *pszConfigText)
{
ASSERT(pszConfigText != NULL);
/* Skip any initial non-numerical characters. */
while(*pszConfigText && (*pszConfigText < '0' || *pszConfigText > '9'))
{
++pszConfigText;
}
/* Return value of number. */
return(atol(pszConfigText));
}
/* ----------------------------------------------------------------------------
* ODCfgGetWordHex() *** PRIVATE FUNCTION ***
*
* Obtains the value of the next hexidecimal number in the provided string, in
* the form of a WORD (16 bit value).
*
* Parameters: pszConfigText - String to examine.
*
* Return: The first number obtained from the string.
*/
static WORD ODCfgGetWordHex(char *pszConfigText)
{
WORD wToReturn;
ASSERT(pszConfigText != NULL);
/* Skip any initial non-hexidecimal characters. */
while(*pszConfigText && (*pszConfigText < '0' || *pszConfigText > '9')
&& (toupper(*pszConfigText) < 'A' || toupper(*pszConfigText) > 'F'))
{
++pszConfigText;
}
sscanf(pszConfigText, "%x", &wToReturn);
return(wToReturn);
}
/* ----------------------------------------------------------------------------
* ODCfgGetNextTime() *** PRIVATE FUNCTION ***
*
* Obtains the next time from a string, updating the string pointer to point to
* the position in the string after the end of the time. The time information
* is stored in the btTimeNumVals and awTimeVal private global variables.
*
* Parameters: ppchConfigText - Pointer to character pointer to the string,
* which is to be updated.
*
* Return: void
*/
static void ODCfgGetNextTime(char **ppchConfigText)
{
char *pchConfigText = (char *)(*ppchConfigText);
ASSERT(ppchConfigText != NULL);
ASSERT(*ppchConfigText != NULL);
btTimeNumVals = 0;
awTimeVal[0] = 0;
awTimeVal[1] = 0;
awTimeVal[2] = 0;
while(*pchConfigText && (*pchConfigText == ' ' || *pchConfigText == '\t'))
{
++pchConfigText;
}
while(*pchConfigText && btTimeNumVals < 3)
{
if(*pchConfigText < '0' || *pchConfigText > '9') break;
awTimeVal[btTimeNumVals++] = atoi(pchConfigText);
while(*pchConfigText && *pchConfigText >= '0' && *pchConfigText <= '9')
{
++pchConfigText;
}
if(*pchConfigText == ':' || *pchConfigText == '.' || *pchConfigText == ','
|| *pchConfigText == ';')
{
++pchConfigText;
}
}
*ppchConfigText = (char *)pchConfigText;
}
/* ----------------------------------------------------------------------------
* ODCfgIsTrue() *** PRIVATE FUNCTION ***
*
* Determines whether the specified string represents a TRUE or FALSE value.
* For example "Yes", "TRUE", "Y" and "1" all represent TRUE values, while
* "No", "FALSE", "N" and "0" all represent FALSE values.
*
* Parameters: pszConfigText - String to examine.
*
* Return: The Boolean value represented by the string.
*/
static BOOL ODCfgIsTrue(char *pszConfigText)
{
ASSERT(pszConfigText != NULL);
while(*pszConfigText && (*pszConfigText == ' ' || *pszConfigText == '\t'))
{
++pszConfigText;
}
switch(*pszConfigText)
{
case '1':
case 't':
case 'T':
case 'y':
case 'Y':
case 'g':
case 'G':
return(TRUE);
}
return(FALSE);
}

View File

@ -0,0 +1,664 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODCmdLn.c
*
* Description: Implementation of od_parse_cmd_line() function, which
* parses standard command-line parameters for OpenDors programs.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Jan 29, 1995 6.00 BP Created.
* Aug 19, 1995 6.00 BP Cleaned up indentations.
* Nov 12, 1995 6.00 BP 32-bit portability.
* Nov 12, 1995 6.00 BP Added -CONFIG parameter.
* Dec 21, 1995 6.00 BP Added -HANDLE parameter.
* Dec 24, 1995 6.00 BP puts() -> printf().
* Dec 30, 1995 6.00 BP Added ODCALL for calling convention.
* Jan 03, 1996 6.00 BP Recognize -D for -DROPFILE.
* Jan 03, 1996 6.00 BP Parameters must begin with - or /.
* Feb 06, 1996 6.00 BP Added -SILENT for od_silent_mode.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Feb 20, 1996 6.00 BP Added bParsedCmdLine.
* Feb 21, 1996 6.00 BP Make cmd line options overriding.
* Feb 25, 1996 6.00 BP Fix -P COMx.
* Feb 27, 1996 6.00 BP Add -P COMx to command line help.
* Mar 03, 1996 6.10 BP Begin version 6.10.
* Apr 08, 1996 6.10 BP Added command-line parsing callbacks.
* Apr 24, 2002 6.22 RS Added -SOCKET parameter.
* Aug 10, 2003 6.23 SH *nix support
*/
#define BUILDING_OPENDOORS
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "OpenDoor.h"
#include "ODStr.h"
#include "ODPlat.h"
#include "ODCore.h"
#include "ODInEx.h"
/* Maximum number of command-line arguments. Any additional arguments will */
/* simply be ignored. */
#define MAX_ARGS 32
/* Size of temporary string that will hold any options following custom */
/* command-line keywords that are passed to the client application's handler */
/* function. */
#define CUSTOM_OPTION_SIZE 80
/* Command-line parameter identifiers. */
typedef enum
{
kParamConfigFile,
kParamLocal,
kParamBPS,
kParamPort,
kParamNode,
kParamHelp,
kParamPersonality,
kParamMaxTime,
kParamAddress,
kParamIRQ,
kParamNoFOSSIL,
kParamNoFIFO,
kParamDropFile,
kParamUserName,
kParamTimeLeft,
kParamSecurity,
kParamLocation,
kParamGraphics,
kParamBBSName,
kParamPortHandle,
kParamSocketDescriptor,
kParamSilentMode,
kParamOption,
kParamUnknown
} tCommandLineParameter;
/* Private function prototypes. */
static void ODAdvanceToNextArg(INT *pnCurrentArg, INT nArgCount,
char *pszOption);
static void ODGetNextArgName(INT *pnCurrentArg, INT nArgCount,
char *papszArguments[], char *pszString, size_t nStringSize);
static tCommandLineParameter ODGetCommandLineParameter(char *pszArgument);
/* Private variables. */
#define CONFIG_FILENAME_SIZE 80
static char szConfigFilename[CONFIG_FILENAME_SIZE];
/* ----------------------------------------------------------------------------
* od_parse_cmd_line()
*
* Function to parse an OpenDoors program's command-line, interpreting
* standard command-line parameters. This is one of the few OpenDoors APIs
* that will not automatically initialize OpenDoors if it hasn't already
* been done. This is because od_parse_cmd_line() performs setup that must
* be done prior to OpenDoors initialization.
*
* Parameters: FOR NON-WIN32 VERSIONS:
*
* nArgCount - Number of command line arguments, as passed to
* main() in argc.
*
* papszArguments - Pointer to array of pointers to string
* arguments, as passed to main() in argv. The
* first element of this array (usually the
* full path and filename of the executable)
* is ignored.
*
* FOR WIN32 VERSION:
*
* pszCmdLine - Pointer to the command line string, as passed
* to WinMain().
*
* Return: void
*/
#ifdef ODPLAT_WIN32
ODAPIDEF void ODCALL od_parse_cmd_line(LPSTR pszCmdLine)
#else /* !ODPLAT_WIN32 */
ODAPIDEF void ODCALL od_parse_cmd_line(INT nArgCount, char *papszArguments[])
#endif /* !ODPLAT_WIN32 */
{
char *pszCurrentArg;
INT nCurrentArg;
INT n;
#ifdef ODPLAT_WIN32
INT nArgCount;
char *papszArguments[MAX_ARGS];
char *pszCmdLineCopy;
char *pchCurrent
#endif /* ODPLAT_WIN32 */
/* Log function entry if running in trace mode. */
TRACE(TRACE_API, "od_parse_cmd_line()");
#ifdef ODPLAT_WIN32
/* Attempt to allocate space for a copy of the command line. */
pszCmdLineCopy = malloc(strlen(pszCmdLine) + 1);
if(pszCmdLineCopy == NULL)
{
od_control.od_error = ERR_MEMORY;
return;
}
/* Copy the command line text into our working copy. */
strcpy(pszCmdLineCopy, pszCmdLine);
/* Loop, building papszArguments and nArgCount. */
pchCurrent = pszCmdLineCopy;
for(nArgCount = 0; nArgCount < MAX_ARGS && *pchCurrent != '\0'; ++nArgCount)
{
/* Store address of the next command line argument. */
papszArguments[nArgCount] = pchCurrent;
/* Skip forward to the next white space. */
while(*pchCurrent != '\0' && !isspace(*pchCurrent))
{
++pchCurrent;
}
/* Replace white space characters with '\0' string terminators, until */
/* we reach the next command line argument, or the end of the string. */
while(*pchCurrent != '\0' && isspace(*pchCurrent))
{
*pchCurrent = '\0';
++pchCurrent;
}
}
#endif /* ODPLAT_WIN32 */
#ifndef ODPLAT_WIN32
/* Check validity of parameters. */
if(papszArguments == NULL)
{
od_control.od_error = ERR_PARAMETER;
return;
}
#endif /* !ODPLAT_WIN32 */
/* Record that od_parse_cmd_line() has been called. */
bParsedCmdLine = TRUE;
/* Initialize variables that are not initialized in od_init() if */
/* od_parse_cmd_line is specified. */
od_control.user_ansi = TRUE;
od_control.user_timelimit = 60;
#ifdef ODPLAT_WIN32
for(nCurrentArg = 0; nCurrentArg < nArgCount; ++nCurrentArg)
#else /* !ODPLAT_WIN32 */
for(nCurrentArg = 1; nCurrentArg < nArgCount; ++nCurrentArg)
#endif /* !ODPLAT_WIN32 */
{
pszCurrentArg = papszArguments[nCurrentArg];
switch(ODGetCommandLineParameter(pszCurrentArg))
{
case kParamConfigFile:
ODAdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
strncpy(szConfigFilename, papszArguments[nCurrentArg],
sizeof(szConfigFilename) - 1);
szConfigFilename[sizeof(szConfigFilename) - 1] = '\0';
od_control.od_config_filename = szConfigFilename;
break;
case kParamLocal:
od_control.od_force_local = TRUE;
break;
case kParamBPS:
ODAdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
od_control.baud = atol(papszArguments[nCurrentArg]);
wPreSetInfo |= PRESET_BPS;
break;
case kParamPort:
ODAdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
if(strnicmp(papszArguments[nCurrentArg], "COM", 3) == 0)
{
od_control.port = atoi(papszArguments[nCurrentArg] + 3) - 1;
}
else
{
od_control.port = atoi(papszArguments[nCurrentArg]);
}
wPreSetInfo |= PRESET_PORT;
break;
case kParamHelp:
if(od_control.od_cmd_line_help_func != NULL)
{
(*od_control.od_cmd_line_help_func)();
exit(0);
}
#ifdef ODPLAT_WIN32
sprintf(szODWorkString, "%s Command Line Options",
strlen(od_control.od_prog_name) > 0 ? od_control.od_prog_name
: OD_VER_SHORTNAME);
if(od_control.od_cmd_line_help != NULL)
{
MessageBox(NULL, od_control.od_cmd_line_help, szODWorkString,
MB_ICONINFORMATION | MB_OK);
}
else
{
MessageBox(NULL,
"(Note that some options can be overriden by configuration or drop files.)\n"
"\n"
"-C x or -CONFIG x\t- Specfies configuration filename.\n"
"-L or -LOCAL\t- Causes door to operate in local mode, without requiring a drop file.\n"
"-D or -DROPFILE x\t- Door information file directory and/or filename.\n"
"-N x or -NODE x\t- Sets the node number to use.\n"
"-B x or -BPS x\t- Sets the serial port <---> modem bps (baud) rate to use.\n"
"-P x or -PORT x\t- Sets serial port to use. For COM1: use -P 0 or -P COM1, for COM2: use -P 1 or -P COM2, etc.\n"
"-HANDLE x\t- Provides an already open serial port handle.\n"
"-SOCKET x\t- Provides an already open TCP/IP socket descriptor.\n"
"-SILENT\t\t- Operate in silent mode, with no local display.\n"
"-MAXTIME x\t- Sets the maximum number of minutes that user will be permitted to access the door.\n"
"-G or -GRAPHICS\t- Unless followed by 0 or N, turns on ANSI display mode.\n"
"-BBSNAME x\t- Name of BBS.\n"
"-USERNAME x\t- Name of user who is currently online.\n"
"-TIMELEFT x\t- User's time remaining online.\n"
"-SECURITY x\t- User's security level.\n"
"-LOCATION x\t- Location from which user is calling.\n"
"-?, -H or -HELP\t- Displays command-line help and exits.",
szODWorkString, MB_ICONINFORMATION | MB_OK);
}
#else /* !ODPLAT_WIN32 */
printf("AVALIABLE COMMAND LINE OPTIONS ");
if(od_control.od_cmd_line_help != NULL)
{
printf(od_control.od_cmd_line_help);
}
else
{
printf("(Some can be overriden by config/drop file)\n");
printf(" -C or -CONFIG - Specfies configuration filename.\n");
printf(" -L or -LOCAL - Causes door to operate in local mode, without requiring a\n");
printf(" door information (drop) file.\n");
printf(" -D or -DROPFILE - Door information file directory and/or filename.\n");
printf(" -N x or -NODE x - Sets the node number to use.\n");
printf(" -B x or -BPS x - Sets the serial port <---> modem bps (baud) rate to use.\n");
printf(" -P x or -PORT x - Sets serial port to use. For COM1: use -P 0 or -P COM1, for\n");
printf(" COM2: use -P 1 or -P COM2, etc.\n");
printf(" -ADDRESS x - Sets serial port address in HEXIDECIMAL (if no FOSSIL).\n");
printf(" -IRQ x - Sets the serial port IRQ line (if FOSSIL is not used).\n");
printf(" -NOFOSSIL - Disables use of FOSSIL driver, even if available.\n");
printf(" -NOFIFO - Disables use of 16550 FIFO buffers (only if no FOSSIL).\n");
printf(" -MAXTIME x - Sets the maximum number of minutes that any user will be\n");
printf(" permitted to access the door, regardless of time left.\n");
printf(" -SILENT - Operate in silent mode, with no local display.\n");
printf(" -G or -GRAPHICS - Unless followed by 0 or N, turns on ANSI display mode.\n");
printf(" -BBSNAME x - Name of BBS.\n");
printf(" -USERNAME x - Name of user who is currently online.\n");
printf(" -TIMELEFT x - User's time remaining online.\n");
printf(" -SECURITY x - User's security level.\n");
printf(" -LOCATION x - Location from which user is calling.\n");
printf(" -?, -H or -HELP - Displays command-line help and exits.\n");
}
#endif /* !ODPLAT_WIN32 */
exit(1);
break;
case kParamNode:
ODAdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
od_control.od_node = atoi(papszArguments[nCurrentArg]);
break;
case kParamMaxTime:
ODAdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
od_control.od_maxtime = atoi(papszArguments[nCurrentArg]);
break;
case kParamAddress:
ODAdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
od_control.od_com_address =
(WORD)strtol(papszArguments[nCurrentArg], NULL, 16);
break;
case kParamIRQ:
ODAdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
od_control.od_com_irq = atoi(papszArguments[nCurrentArg]);
break;
case kParamNoFOSSIL:
od_control.od_no_fossil = TRUE;
break;
case kParamNoFIFO:
od_control.od_com_no_fifo = TRUE;
break;
case kParamDropFile:
ODAdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
strncpy(od_control.info_path, papszArguments[nCurrentArg],
sizeof(od_control.info_path) - 1);
od_control.info_path[sizeof(od_control.info_path) - 1] = '\0';
break;
case kParamUserName:
ODGetNextArgName(&nCurrentArg, nArgCount, papszArguments,
od_control.user_name, sizeof(od_control.user_name));
break;
case kParamTimeLeft:
ODAdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
od_control.user_timelimit = atoi(papszArguments[nCurrentArg]);
break;
case kParamSecurity:
ODAdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
od_control.user_security = atoi(papszArguments[nCurrentArg]);
break;
case kParamLocation:
ODGetNextArgName(&nCurrentArg, nArgCount, papszArguments,
od_control.user_location, sizeof(od_control.user_location));
break;
case kParamGraphics:
n = nCurrentArg;
if(++n < nArgCount)
{
if(atoi(papszArguments[n]) == 0 ||
stricmp(papszArguments[n], "N") == 0)
{
od_control.user_ansi = FALSE;
++nCurrentArg;
break;
}
}
od_control.user_ansi = TRUE;
break;
case kParamBBSName:
ODGetNextArgName(&nCurrentArg, nArgCount, papszArguments,
od_control.system_name, sizeof(od_control.system_name));
break;
case kParamSocketDescriptor:
od_control.od_use_socket = TRUE;
/* fall through */
case kParamPortHandle:
ODAdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
od_control.od_open_handle = atoi(papszArguments[nCurrentArg]);
break;
case kParamSilentMode:
od_control.od_silent_mode = TRUE;
break;
case kParamUnknown:
/* If the client application provided a custom command line */
/* handler function, then pass this unrecognized command-line */
/* parameter and any options to that callback function. */
if(od_control.od_cmd_line_handler != NULL)
{
char szCustomOptions[CUSTOM_OPTION_SIZE];
ODGetNextArgName(&nCurrentArg, nArgCount, papszArguments,
szCustomOptions, sizeof(szCustomOptions));
(*od_control.od_cmd_line_handler)(pszCurrentArg,
szCustomOptions);
}
break;
}
}
#ifdef ODPLAT_WIN32
free(pszCmdLineCopy);
#endif /* ODPLAT_WIN32 */
}
/* ----------------------------------------------------------------------------
* ODAdvanceToNextArg() *** PRIVATE FUNCTION ***
*
* Moves to the argument for a particular command line option.
*
* Parameters: pnCurrentArg - Pointer to current argument number.
*
* nArgCount - Total number of arguments available.
*
* pszOption - Pointer to command line option name.
*
* Return: void
*/
static void ODAdvanceToNextArg(INT *pnCurrentArg, INT nArgCount,
char *pszOption)
{
ASSERT(pnCurrentArg != NULL);
ASSERT(pszOption != NULL);
if(++*pnCurrentArg >= nArgCount)
{
printf("Missing parameter for option: %s\n", pszOption);
exit(1);
}
}
/* ----------------------------------------------------------------------------
* ODGetNextArgName() *** PRIVATE FUNCTION ***
*
* Obtains a multi-word name from command-line.
*
* Parameters: pnCurrentArg - Pointer to integer storing current argument
* number.
*
* nArgCount - The total number of command-line argument
*
* papszArguments - Pointer to array of pointers to string
* arguments, as passed to main() in argv.
*
* pszString - Pointer to string in which name will string
* be stored.
*
* nStringSize - Size of the string.
*
* Return: void
*/
static void ODGetNextArgName(INT *pnCurrentArg, INT nArgCount,
char *papszArguments[], char *pszString, size_t nStringSize)
{
BOOL bFirst = TRUE;
ASSERT(pnCurrentArg != NULL);
ASSERT(papszArguments != NULL);
ASSERT(pszString != NULL);
ASSERT(nStringSize > 0);
if((*pnCurrentArg) + 1 >= nArgCount)
{
printf("Missing parameter for option: %s\n",
papszArguments[(*pnCurrentArg) - 1]);
exit(1);
}
pszString[0] = '\0';
while(++*pnCurrentArg < nArgCount)
{
if(ODGetCommandLineParameter(papszArguments[*pnCurrentArg])
!= kParamOption)
{
--*pnCurrentArg;
break;
}
if(strlen(pszString) >= nStringSize - 1)
{
break;
}
if(!bFirst)
{
strcat(pszString, " ");
}
strncat(pszString, papszArguments[*pnCurrentArg],
strlen(pszString) - nStringSize - 1);
pszString[nStringSize - 1] = '\0';
bFirst = FALSE;
}
}
/* ----------------------------------------------------------------------------
* ODGetCommandLineParameter() *** PRIVATE FUNCTION ***
*
* Determines which command-line option, if any, is specified by an argument
* string.
*
* Parameters: pszArgument - Pointer to string containing raw command-line
* argument.
*
* Return: A tCommandLineParameter, identifying which command-line option,
* if any, matches the argument string.
*/
static tCommandLineParameter ODGetCommandLineParameter(char *pszArgument)
{
ASSERT(pszArgument != NULL);
if(*pszArgument == '-' || *pszArgument == '/')
{
++pszArgument;
}
else
{
return(kParamOption);
}
if(stricmp(pszArgument, "C") == 0
|| stricmp(pszArgument, "CONFIG") == 0
|| stricmp(pszArgument, "CONFIGFILE") == 0
|| stricmp(pszArgument, "CFGFILE") == 0
|| stricmp(pszArgument, "CFG") == 0)
{
return(kParamConfigFile);
}
else if(stricmp(pszArgument, "L") == 0
|| stricmp(pszArgument, "LOCAL") == 0)
{
return(kParamLocal);
}
else if(stricmp(pszArgument, "B") == 0
|| stricmp(pszArgument, "BPS") == 0
|| stricmp(pszArgument, "BAUD") == 0)
{
return(kParamBPS);
}
else if(stricmp(pszArgument, "P") == 0
|| stricmp(pszArgument, "PORT") == 0)
{
return(kParamPort);
}
else if(stricmp(pszArgument, "N") == 0
|| stricmp(pszArgument, "NODE") == 0)
{
return(kParamNode);
}
else if(stricmp(pszArgument, "?") == 0
|| stricmp(pszArgument, "H") == 0
|| stricmp(pszArgument, "HELP") == 0)
{
return(kParamHelp);
}
else if(stricmp(pszArgument, "PERSONALITY") == 0)
{
return(kParamPersonality);
}
else if(stricmp(pszArgument, "MAXTIME") == 0)
{
return(kParamMaxTime);
}
else if(stricmp(pszArgument, "ADDRESS") == 0)
{
return(kParamAddress);
}
else if(stricmp(pszArgument, "IRQ") == 0)
{
return(kParamIRQ);
}
else if(stricmp(pszArgument, "NOFOSSIL") == 0)
{
return(kParamNoFOSSIL);
}
else if(stricmp(pszArgument, "NOFIFO") == 0)
{
return(kParamNoFIFO);
}
else if(stricmp(pszArgument, "DROPFILE") == 0 ||
stricmp(pszArgument, "D") == 0)
{
return(kParamDropFile);
}
else if(stricmp(pszArgument, "USERNAME") == 0)
{
return(kParamUserName);
}
else if(stricmp(pszArgument, "TIMELEFT") == 0)
{
return(kParamTimeLeft);
}
else if(stricmp(pszArgument, "SECURITY") == 0)
{
return(kParamSecurity);
}
else if(stricmp(pszArgument, "LOCATION") == 0)
{
return(kParamLocation);
}
else if(stricmp(pszArgument, "GRAPHICS") == 0
|| stricmp(pszArgument, "G") == 0)
{
return(kParamGraphics);
}
else if(stricmp(pszArgument, "BBSNAME") == 0)
{
return(kParamBBSName);
}
else if(stricmp(pszArgument, "HANDLE") == 0)
{
return(kParamPortHandle);
}
else if(stricmp(pszArgument, "SOCKET") == 0)
{
return(kParamSocketDescriptor);
}
else if(stricmp(pszArgument, "SILENT") == 0)
{
return(kParamSilentMode);
}
else
{
return(kParamUnknown);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,137 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* Oct-2001 door32.sys/socket modifications by Rob Swindell (www.synchro.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODCom.h
*
* Description: Public definitions for serial communications module, which
* is implemented in odcom.c
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Oct 21, 1994 6.00 BP Created.
* Jan 01, 1995 6.00 BP Added ODComWaitEvent().
* Dec 21, 1995 6.00 BP Add ability to use already open port.
* Jan 09, 1996 6.00 BP Supply actual in/out buffer size used.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
* Mar 06, 1996 6.10 BP Initial support for Door32 interface.
* Oct 19, 2001 6.20 RS Added TCP/IP socket (telnet) support.
*/
#ifndef _INC_ODCOM
#define _INC_ODCOM
/* odtypes.h is needed for definitions of tODHandle, and BOOL. */
#include "ODTypes.h"
/* Serial I/O handle. */
typedef tODHandle tPortHandle;
/* Flow Control setting manifest constants. */
#define FLOW_NONE 0x00
#define FLOW_RTSCTS 0x02
#define FLOW_DEFAULT 0x80
/* Parity bit setting manifest constants. */
#define ODPARITY_NONE 0x00
#define ODPARITY_ODD 0x08
#define ODPARITY_EVEN 0x18
#define ODPARITY_MASK 0x18
/* Stop bit setting manifest constants. */
#define STOP_ONE 0x00
#define STOP_ONE_POINT_FIVE 0x04 /* Only with DATABITS_FIVE. */
#define STOP_TWO 0x04 /* Only if not using DATABITS_FIVE. */
#define STOP_MASK 0x04
/* Character length manifest constants. */
#define DATABITS_FIVE 0x00
#define DATABITS_SIX 0x01
#define DATABITS_SEVEN 0x02
#define DATABITS_EIGHT 0x03
#define DATABITS_MASK 0x03
/* FIFO setting constants. */
#define FIFO_DISABLE 0x00
#define FIFO_ENABLE 0x01
#define FIFO_TRIGGER_1 0x00
#define FIFO_TRIGGER_4 0x40
#define FIFO_TRIGGER_8 0x80
#define FIFO_TRIGGER_14 0xc0
/* Misc. manifest constants. */
#define SPEED_UNSPECIFIED 0
#define SIZE_NON_ZERO -1
/* Serial I/O method settings. */
typedef enum
{
kComMethodUnspecified,
kComMethodFOSSIL,
kComMethodUART,
kComMethodWin32,
kComMethodDoor32,
kComMethodSocket,
kComMethodStdIO
} tComMethod;
/* Serial I/O event types. */
typedef enum
{
kNoCarrier
} tComEvent;
/* Serial I/O function prototypes. */
tODResult ODComAlloc(tPortHandle *phPort);
tODResult ODComFree(tPortHandle hPort);
tODResult ODComSetIdleFunction(tPortHandle hPort,
void (*pfCallback)(void));
tODResult ODComSetFlowControl(tPortHandle hPort, BYTE btFlowControlSetting);
tODResult ODComSetSpeed(tPortHandle hPort, long lSpeed);
tODResult ODComSetPort(tPortHandle hPort, BYTE btPort);
tODResult ODComSetIRQ(tPortHandle hPort, BYTE btIRQLevel);
tODResult ODComSetPortAddress(tPortHandle hPort, int nPortAddress);
tODResult ODComSetWordFormat(tPortHandle hPort, BYTE btWordFormat);
tODResult ODComSetRXBuf(tPortHandle hPort, int nReceiveBufferSize);
tODResult ODComSetTXBuf(tPortHandle hPort, int nTransmitBufferSize);
tODResult ODComSetFIFO(tPortHandle hPort, BYTE btFIFOSetting);
tODResult ODComSetPreferredMethod(tPortHandle hPort, tComMethod Method);
tODResult ODComGetMethod(tPortHandle hPort, tComMethod *pMethod);
tODResult ODComOpen(tPortHandle hPort);
tODResult ODComOpenFromExistingHandle(tPortHandle hPort,
DWORD dwExistingHandle);
tODResult ODComClose(tPortHandle hPort);
tODResult ODComClearInbound(tPortHandle hPort);
tODResult ODComClearOutbound(tPortHandle hPort);
tODResult ODComInbound(tPortHandle hPort, int *pnInboundWaiting);
tODResult ODComOutbound(tPortHandle hPort, int *pnOutboundWaiting);
tODResult ODComCarrier(tPortHandle hPort, BOOL *pbIsCarrier);
tODResult ODComSetDTR(tPortHandle hPort, BOOL bHigh);
tODResult ODComSendByte(tPortHandle hPort, BYTE btToSend);
tODResult ODComGetByte(tPortHandle hPort, char *pbtNext, BOOL bWait);
tODResult ODComSendBuffer(tPortHandle hPort, BYTE *pbtBuffer, int nSize);
tODResult ODComGetBuffer(tPortHandle hPort, BYTE *pbtBuffer, int nSize,
int *pnBytesRead);
tODResult ODComWaitEvent(tPortHandle hPort, tComEvent Event);
#endif /* !_INC_ODCOM */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,109 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODCore.h
*
* Description: Global functions and variables provide by the odcore.c
* module. These core facilities are used throughout OpenDoors,
* and are required regardless of what OpenDoors features that
* a given program uses.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Nov 16, 1995 6.00 BP Created.
* Nov 17, 1995 6.00 BP Use new input queue mechanism.
* Dec 24, 1995 6.00 BP Added abtGreyBlock.
* Dec 30, 1995 6.00 BP Added ODCALL for calling convention.
* Jan 01, 1996 6.00 BP Changed TEXT_SIZE to 49.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
* Sep 01, 1996 6.10 BP Update output area on od_set_per...().
*/
#ifndef _INC_ODCORE
#define _INC_ODCORE
/* Include other header files that have definitions neede by this one. */
#include "ODInQue.h"
#include "ODCom.h"
#include "ODPlat.h"
#include "ODScrn.h"
/* OpenDoors global initialized flag. */
extern BOOL bODInitialized;
/* Global serial port object handle. */
extern tPortHandle hSerialPort;
/* Global input queue object handle. */
extern tODInQueueHandle hODInputQueue;
/* Reentrancy control. */
extern BOOL bIsCallbackActive;
extern BOOL bShellChatActive;
/* Global working space. */
#define OD_GLOBAL_WORK_STRING_SIZE 1025
extern char szODWorkString[OD_GLOBAL_WORK_STRING_SIZE];
/* Global instance of the text information structure for general use. */
extern tODScrnTextInfo ODTextInfo;
/* Logfile function hooks. */
extern BOOL (*pfLogWrite)(INT);
extern void (*pfLogClose)(INT);
/* od_colour_config() support for od_printf(). */
extern char chColorCheck;
extern char *pchColorEndPos;
/* Status line information. */
extern BYTE btCurrentStatusLine;
extern OD_PERSONALITY_CALLBACK *pfCurrentPersonality;
extern char szDesiredPersonality[33];
typedef BOOL ODCALL SET_PERSONALITY_FUNC(char *pszName);
extern SET_PERSONALITY_FUNC *pfSetPersonality;
/* Commonly used character sequences. */
extern char abtBlackBlock[2];
extern char abtGreyBlock[2];
extern char szBackspaceWithDelete[4];
/* Current output area on screen. */
extern BYTE btOutputTop;
extern BYTE btOutputBottom;
/* Core functions used throughout OpenDoors. */
void ODWaitDrain(tODMilliSec MaxWait);
void ODStoreTextInfo(void);
void ODRestoreTextInfo(void);
void ODStringToName(char *pszToConvert);
BOOL ODPagePrompt(BOOL *pbPausing);
/* Number of built-in configuration file options. */
#define TEXT_SIZE 49
/* Number of user-defined info file options. */
#define LINES_SIZE 25
#endif /* _INC_ODCORE */

View File

@ -0,0 +1,187 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODDrBox.c
*
* Description: Implements the od_draw_box() function.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Oct 13, 1994 6.00 BP New file header format.
* Dec 09, 1994 6.00 BP Standardized coding style.
* Aug 19, 1995 6.00 BP 32-bit portability.
* Nov 16, 1995 6.00 BP Removed oddoor.h, added odcore.h.
* Dec 12, 1995 6.00 BP Added entry, exit and kernel macros.
* Dec 30, 1995 6.00 BP Added ODCALL for calling convention.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
* Aug 10, 2003 6.23 SH *nix support
*/
#define BUILDING_OPENDOORS
#include "OpenDoor.h"
#include "ODCore.h"
#include "ODGen.h"
#include "ODKrnl.h"
/* ----------------------------------------------------------------------------
* od_draw_box()
*
* Draws a box on the local and remote screens, using the box characters
* specified in od_control.od_box_chars. Unlike the window functions, this
* function does not store the original contents of the screen where the box
* is drawn.
*
* Parameters: btLeft - Column number of the left side of the box.
*
* btTop - Row number of the top side of the box.
*
* btRight - Column number of hte right side of the box.
*
* btBottom - Row number of the bottom side of the box.
*
* Return: TRUE on success, or FALSE on failure.
*/
ODAPIDEF BOOL ODCALL od_draw_box(BYTE btLeft, BYTE btTop, BYTE btRight,
BYTE btBottom)
{
/* Number of current line being drawn. */
BYTE btLine;
/* X size of window. */
BYTE btBetweenSize = (btRight - btLeft) - 1;
/* Log function entry if running in trace mode */
TRACE(TRACE_API, "od_draw_box()");
/* Ensure that OpenDoors has been initialized */
if(!bODInitialized) od_init();
OD_API_ENTRY();
/* Setup od_box_chars appropriately */
if(od_control.od_box_chars[BOX_BOTTOM] == 0)
{
od_control.od_box_chars[BOX_BOTTOM] = od_control.od_box_chars[BOX_TOP];
}
if(od_control.od_box_chars[BOX_RIGHT] == 0)
{
od_control.od_box_chars[BOX_RIGHT] = od_control.od_box_chars[BOX_LEFT];
}
/* Check that required display capabilities are supported. */
if(!(od_control.user_ansi || od_control.user_avatar))
{
od_control.od_error = ERR_NOGRAPHICS;
OD_API_EXIT();
return(FALSE);
}
/* Check that parameters are within valid range. */
if(btLeft<1 || btTop<1 || btRight>80 || btBottom>25)
{
od_control.od_error = ERR_PARAMETER;
OD_API_EXIT();
return(FALSE);
}
/* Move to top corner, if needed. */
od_set_cursor(btTop, btLeft);
/* Display left corner character. */
od_putch(od_control.od_box_chars[BOX_UPPERLEFT]);
/* Display top line. */
od_repeat(od_control.od_box_chars[BOX_TOP], btBetweenSize);
/* Display right corner character. */
od_putch(od_control.od_box_chars[BOX_UPPERRIGHT]);
/* If AVATAR display mode is available. */
if(od_control.user_avatar)
{
/* Display first left vertical line. */
od_set_cursor(btTop + 1, btLeft);
od_putch(od_control.od_box_chars[BOX_LEFT]);
/* Fill in the center of the window. */
od_emulate(22);
od_emulate(12);
od_emulate((BYTE)od_control.od_cur_attrib);
od_emulate((BYTE)((btBottom - btTop) - 1));
od_emulate(btBetweenSize);
/* Display first right vertical line. */
od_set_cursor(btTop + 1, btRight);
od_putch(od_control.od_box_chars[BOX_RIGHT]);
/* Display remaining vertical lines. */
for(btLine = btTop + 2; btLine < btBottom; ++btLine)
{
/* Move to the start of the line. */
od_set_cursor(btLine, btLeft);
/* Display left line character. */
od_putch(od_control.od_box_chars[BOX_LEFT]);
/* Move to line start. */
od_set_cursor(btLine, btRight);
/* Display right line character. */
od_putch(od_control.od_box_chars[BOX_RIGHT]);
}
}
/* If AVATAR mode is not available. */
else
{
/* Loop through middle lines of window. */
for(btLine = btTop + 1; btLine < btBottom; ++btLine)
{
/* Move to the start of the line. */
od_set_cursor(btLine,btLeft);
/* Display left line character. */
od_putch(od_control.od_box_chars[BOX_LEFT]);
/* Display the blank area. */
od_repeat(' ', btBetweenSize);
/* Display the right line character. */
od_putch(od_control.od_box_chars[BOX_RIGHT]);
}
}
/* Move to bottom corner. */
od_set_cursor(btBottom, btLeft);
/* Display left corner character. */
od_putch(od_control.od_box_chars[BOX_LOWERLEFT]);
/* Display bottom line. */
od_repeat(od_control.od_box_chars[BOX_BOTTOM], btBetweenSize);
/* Display right corner character. */
od_putch(od_control.od_box_chars[BOX_LOWERRIGHT]);
/* Return with success. */
OD_API_EXIT();
return(TRUE);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,58 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODFrame.h
*
* Description: Defines the public interface to the OpenDoors frame window.
* This file is only applicable when building the Win32 version
* of OpenDoors.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Aug 20, 1995 6.00 BP Created.
* Jan 20, 1996 6.00 BP Made ODFrameCenter...() shared.
* Feb 17, 1996 6.00 BP Add ...Accelerator() return value.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
*/
#ifndef _INC_ODFRAME
#define _INC_ODFRAME
#include "ODPlat.h"
#include "ODGen.h"
#ifdef ODPLAT_WIN32
/* Public frame window functions. */
tODResult ODFrameStart(HANDLE hInstance, tODThreadHandle *phFrameThread);
INT ODFrameGetUsedClientAtTop(HWND hwndFrame);
INT ODFrameGetUsedClientAtBottom(HWND hwndFrame);
BOOL ODFrameTranslateAccelerator(HWND hwndFrame, LPMSG pMsg);
void ODFrameUpdateCmdUI(void);
void ODFrameUpdateTimeDisplay(void);
void ODFrameUpdateWantChat(void);
void ODFrameCenterWindowInParent(HWND hwndChild);
/* User defined messages that are handled by the frame window. */
#define WM_SHOW_MESSAGE (WM_USER + 1)
#define WM_REMOVE_MESSAGE (WM_USER + 2)
#endif /* ODPLAT_WIN32 */
#endif /* _INC_ODFRAME */

View File

@ -0,0 +1,199 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* Oct-2001 door32.sys/socket modifications by Rob Swindell (www.synchro.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODGen.h
*
* Description: Contains general definitions used throughout OpenDoors,
* including: - version information manifest constants
* - debugging macros
* - compiler-dependent definitions
* - internally used macros
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Oct 13, 1994 6.00 BP Created.
* Oct 20, 1994 6.00 BP Added DIM macro.
* Dec 31, 1994 6.00 BP Remove USEINLINE option.
* Dec 12, 1995 6.00 BP Moved ODPLAT_??? to OpenDoor.h.
* Dec 19, 1995 6.00 BP Implement ASSERT() for Win32.
* Jan 23, 1996 6.00 BP Added OD_TEXTMODE.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Feb 24, 1996 6.00 BP Turn off OD_DIAGNOSTICS.
* Mar 03, 1996 6.10 BP Begin version 6.10.
* Mar 03, 1996 6.10 BP Moved ODFAR to OpenDoor.h.
* Oct 19, 2001 6.20 RS Incremented version for socket support.
*/
#ifndef _INC_ODGEN
#define _INC_ODGEN
/* PLATFORM-SPECIFIC DEFINITIONS. */
/* DLL specific defintions. */
#ifdef OD_DLL
#ifdef ODPLAT_WIN32
#define OD_DLL_NAME "ODOORS62"
#endif /* ODPLAT_WIN32 */
#endif /* OD_DLL */
/* Mutlithreading specific definitions. */
#ifdef ODPLAT_WIN32
#define OD_MULTITHREADED
#endif /* ODPLAT_WIN32 */
/* Text mode specific definitions. */
#if defined(ODPLAT_DOS) || defined(ODPLAT_NIX)
#define OD_TEXTMODE
#endif /* ODPLAT_DOS */
/* DOS specific definitions. */
#ifdef ODPLAT_DOS
/* Keyword to flag ISR functions. */
#define INTERRUPT interrupt
/* Inline assembly keyword varies from compiler to compiler. */
#ifdef _MSC_VER
#define ASM __asm
#else
#define ASM asm
#endif
/* Memory model information. */
#ifdef __TINY__
#define SMALLDATA
#define SMALLCODE
#endif
#ifdef __SMALL__
#define SMALLDATA
#define SMALLCODE
#endif
#ifdef __COMPACT__
#define LARGEDATA
#define SMALLCODE
#endif
#ifdef __MEDIUM__
#define SMALLDATA
#define LARGECODE
#endif
#ifdef __LARGE__
#define LARGEDATA
#define LARGECODE
#endif
#ifdef __HUGE__
#define LARGEDATA
#define LARGECODE
#endif
#endif /* ODPLAT_DOS */
/* VERSION INFORMATION CONSTANTS. */
#define OD_VER_SHORTNAME "OpenDoors"
#define OD_VER_STATUSLINE " OpenDoors 6.24 - (C) Copyright 1991-2001" \
" by Brian Pirie "
#define OD_VER_UNREG_STAT " OpenDoors 6.24 *WARNING* Unregistered Version" \
" - Limit 1 month trial period! "
#ifdef ODPLAT_DOS
#define OD_VER_SIGNON "[OpenDoors 6.24/DOS - " \
"(C) Copyright 1991-2001 by Brian Pirie]\n\r"
#define OD_VER_FULLNAME "OpenDoors 6.24/DOS"
#endif /* ODPLAT_DOS */
#ifdef ODPLAT_WIN32
#define OD_VER_SIGNON "[OpenDoors 6.24/Win32 - " \
"(C) Copyright 1991-2001 by Brian Pirie]\n\r"
#define OD_VER_FULLNAME "OpenDoors 6.24/Win32"
#endif /* ODPLAT_WIN32 */
#ifdef ODPLAT_NIX
#define OD_VER_SIGNON "[OpenDoors 6.24/*nix - " \
"(C) Copyright 1991-2001 by Brian Pirie]\n\r"
#define OD_VER_FULLNAME "OpenDoors 6.24/*nix"
#endif /* ODPLAT_NIX */
/* COMPILER DEPENDENT DEFINITIONS. */
/* Some compilers don't like const keyword on parameters. */
#define CONST const
/* DEBUG MACROS. */
/* OD_DEBUG is defined for debug version of the library. */
/* #define OD_DEBUG */
/* OD_DIAGNOSTICS is defined to enable od_internal_debug. */
/* #define OD_DIAGNOSTICS */
/* ASSERTion macro - terminates if test condition fails. */
#ifdef OD_DEBUG
#define __STR(x) __VAL(x)
#define __VAL(x) #x
#ifdef ODPLAT_WIN32
#define ASSERT(x) if(!(x)) { MessageBox(NULL, __FILE__ ":" \
__STR(__LINE__) "\n" #x, OD_VER_FULLNAME " - Test condition failed", \
MB_ICONSTOP | MB_OK); exit(1); }
#else /* !ODPLAT_WIN32 */
#define ASSERT(x) if(!(x)) { puts(OD_VER_FULLNAME \
" - Test condition failed:\n" __FILE__ ":" __STR(__LINE__) "\n" #x); \
exit(1); }
#endif /* !ODPLAT_WIN32 */
#else /* !OD_DEBUG */
#define ASSERT(x)
#endif /* !OD_DEBUG */
/* TRACE() macro - used to generate debug output. */
#ifdef OD_TRACE
#include <stdio.h>
#define TRACE_API 1
#define TRACE(x, y) printf("[%s]", y);
#else
#define TRACE(x, y)
#endif
/* SCREEN SIZE. */
#define OD_SCREEN_WIDTH 80
#define OD_SCREEN_HEIGHT 25
/* INTERNALLY USED MACROS. */
/* MIN() and MAX() macros. Note that expressions passed to macros may be */
/* evaluated more than once. For this reason, it is best to only pass */
/* constants or variables to these macros. */
#ifndef MIN
#define MIN(x, y) ((x) > (y)) ? (y) : (x)
#endif /* !MIN */
#ifndef MAX
#define MAX(x, y) ((x) > (y)) ? (x) : (y)
#endif /* !MAX */
/* DIM() macro. Returns the number of elements in an array. */
#ifndef DIM
#define DIM(x) (sizeof(x) / sizeof(*x))
#endif /* !DIM */
/* UNUSED() macro. Used to flag that a function parameter is intentionally */
/* not used, thus preventing a compile-time warning. */
#define UNUSED(x) ((void)(x))
#endif /* !_INC_ODGEN */

View File

@ -0,0 +1,511 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODGetIn.c
*
* Description: Implements the od_get_input() function, which obtains the
* next input event of any type, optionally performing
* translation.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Jan 04, 1996 6.00 BP Created.
* Jan 30, 1996 6.00 BP Tweaked TREAT_ESC_AS_ANSI_TIMEOUT.
* Jan 30, 1996 6.00 BP Replaced od_yield() with od_sleep().
* Jan 30, 1996 6.00 BP Add ODInQueueGetNextEvent() timeout.
* Jan 31, 1996 6.00 BP Added timeout for od_get_input().
* Feb 13, 1996 6.00 BP Added od_get_input() flags parameter.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Feb 19, 1996 6.00 BP Switched to table implementation.
* Feb 25, 1996 6.00 BP Added new control sequences to table.
* Feb 27, 1996 6.00 BP Added od_max_key_latency.
* Mar 03, 1996 6.10 BP Begin version 6.10.
* Aug 10, 2003 6.23 SH *nix support
* Apr 11, 2005 6.23 SH Fix hang forver on ESC press and latency timeout.
*/
#define BUILDING_OPENDOORS
#include <stddef.h>
#include <string.h>
#include "OpenDoor.h"
#include "ODInQue.h"
#include "ODCore.h"
#include "ODKrnl.h"
/* Control sequence table definitions. */
typedef struct
{
char *pszSequence;
char chExtendedKey;
BOOL bIsControlKey;
} tODKeySequence;
tODKeySequence aKeySequences[] =
{
/* VT-52 control sequences. */
{"\033A", OD_KEY_UP, FALSE},
{"\033B", OD_KEY_DOWN, FALSE},
{"\033C", OD_KEY_RIGHT, FALSE},
{"\033D", OD_KEY_LEFT, FALSE},
{"\033H", OD_KEY_HOME, FALSE},
{"\033K", OD_KEY_END, FALSE},
{"\033P", OD_KEY_F1, FALSE},
{"\033Q", OD_KEY_F2, FALSE},
{"\033?w", OD_KEY_F3, FALSE},
{"\033?x", OD_KEY_F4, FALSE},
{"\033?t", OD_KEY_F5, FALSE},
{"\033?u", OD_KEY_F6, FALSE},
{"\033?q", OD_KEY_F7, FALSE},
{"\033?r", OD_KEY_F8, FALSE},
{"\033?p", OD_KEY_F9, FALSE},
/* Control sequences common to VT-100/VT-102/VT-220/VT-320/ANSI. */
{"\033[A", OD_KEY_UP, FALSE},
{"\033[B", OD_KEY_DOWN, FALSE},
{"\033[C", OD_KEY_RIGHT, FALSE},
{"\033[D", OD_KEY_LEFT, FALSE},
{"\033[M", OD_KEY_PGUP, FALSE},
{"\033[H\x1b[2J", OD_KEY_PGDN, FALSE},
{"\033[H", OD_KEY_HOME, FALSE},
{"\033[K", OD_KEY_END, FALSE},
{"\033OP", OD_KEY_F1, FALSE},
{"\033OQ", OD_KEY_F2, FALSE},
{"\033OR", OD_KEY_F3, FALSE},
{"\033OS", OD_KEY_F4, FALSE},
/* VT-220/VT-320 specific control sequences. */
{"\033[1~", OD_KEY_HOME, FALSE}, /* Windows XP telnet.exe. Is actually FIND */
{"\033[2~", OD_KEY_INSERT, FALSE},
{"\033[3~", OD_KEY_DELETE, FALSE},
{"\033[4~", OD_KEY_END, FALSE}, /* Windows XP telnet.exe. Is actually SELECT */
{"\033[5~", OD_KEY_PGUP, FALSE},
{"\033[6~", OD_KEY_PGDN, FALSE},
{"\033[17~", OD_KEY_F6, FALSE},
{"\033[18~", OD_KEY_F7, FALSE},
{"\033[19~", OD_KEY_F8, FALSE},
{"\033[20~", OD_KEY_F9, FALSE},
{"\033[21~", OD_KEY_F10, FALSE},
{"\033[23~", OD_KEY_F11, FALSE},
{"\033[24~", OD_KEY_F12, FALSE},
/* ANSI-specific control sequences. */
{"\033[L", OD_KEY_HOME, FALSE},
{"\033Ow", OD_KEY_F3, FALSE},
{"\033Ox", OD_KEY_F4, FALSE},
{"\033Ot", OD_KEY_F5, FALSE},
{"\033Ou", OD_KEY_F6, FALSE},
{"\033Oq", OD_KEY_F7, FALSE},
{"\033Or", OD_KEY_F8, FALSE},
{"\033Op", OD_KEY_F9, FALSE},
/* PROCOMM-specific control sequences (non-keypad alternatives). */
{"\033OA", OD_KEY_UP, FALSE},
{"\033OB", OD_KEY_DOWN, FALSE},
{"\033OC", OD_KEY_RIGHT, FALSE},
{"\033OD", OD_KEY_LEFT, FALSE},
{"\033OH", OD_KEY_HOME, FALSE},
{"\033OK", OD_KEY_END, FALSE},
/* Other standard control sequences. */
{"\x16\t", OD_KEY_INSERT, TRUE},
/* OpenDoors-specific alternatives. */
{"\x7f", OD_KEY_DELETE, FALSE},
{"\x5", OD_KEY_UP, TRUE},
{"\x18", OD_KEY_DOWN, TRUE},
{"\x13", OD_KEY_LEFT, TRUE},
{"\x4", OD_KEY_RIGHT, TRUE},
{"\x7", OD_KEY_DELETE, TRUE},
{"\x16", OD_KEY_INSERT, TRUE},
};
/* Constant that indicates no match has been found. */
#define NO_MATCH DIM(aKeySequences)
/* Configurable constants. */
/* The time, in milliseconds, to wait for a second character in a control */
/* sequence, before deciding that none is going to come. */
#define MAX_CHARACTER_LATENCY 250
/* Size of inbound sequence buffer. */
#define SEQUENCE_BUFFER_SIZE 10
/* Current control sequence received state. */
static char szCurrentSequence[SEQUENCE_BUFFER_SIZE] = "";
#if 0 // Unused...
static tODTimer SequenceFailTimer;
static BOOL bSequenceFromRemote;
static int nMatchedSequence = NO_MATCH;
static BOOL bTimerActive = FALSE;
#endif
static BOOL bDoorwaySequence = FALSE;
static BOOL bDoorwaySequencePending = FALSE;
/* Local private function prototypes. */
static int ODGetCodeIfLongest(WORD wFlags);
static int ODHaveStartOfSequence(WORD wFlags);
static int ODLongestFullCode(WORD wFlags);
static void ODShiftSeq(int chars);
/* ----------------------------------------------------------------------------
* od_get_input()
*
* Obtains the next input event of any type, optionally performing
* translation on input events.
*
* Parameters: pInputEvent - Pointer to a tODInputEvent structure, which
* will be filled by information on the next input
* event, if any is obtained.
*
* TimeToWait - Number of milliseconds to wait for input to be
* available. A value of 0 causes od_get_input()
* to return immediately if no input is waiting,
* while a value of OD_NO_TIMEOUT causes the
* function to never return unless input has been
* obtained.
*
* wFlags - Flags which customize od_get_input()'s behaviour.
*
* Return: TRUE if an input event was obtained, FALSE if not.
*/
ODAPIDEF BOOL ODCALL od_get_input(tODInputEvent *pInputEvent,
tODMilliSec TimeToWait, WORD wFlags)
{
tODInputEvent LastInputEvent;
int nSequence;
int nSequenceLen;
/* Log function entry if running in trace mode. */
TRACE(TRACE_API, "od_get_input()");
/* Initialize OpenDoors if it hasn't already been done. */
if(!bODInitialized) od_init();
OD_API_ENTRY();
/* Check for parameter validity. */
if(pInputEvent == NULL)
{
od_control.od_error = ERR_PARAMETER;
OD_API_EXIT();
return(FALSE);
}
/* Call the OpenDoors kernel, if applicable */
CALL_KERNEL_IF_NEEDED();
/* If you don't know better, it's a remote char */
/* Local chars are always correctly received (no ANSI sequences) */
LastInputEvent.bFromRemote = TRUE;
if((!bDoorwaySequence) && bDoorwaySequencePending && (!szCurrentSequence[0])) {
bDoorwaySequencePending=FALSE;
bDoorwaySequence=TRUE;
}
/* If no pending input string, wait for the first keystroke */
if((!szCurrentSequence[0]) && (!bDoorwaySequence)) {
if(ODInQueueGetNextEvent(hODInputQueue, &LastInputEvent, TimeToWait)
!= kODRCSuccess) {
OD_API_EXIT();
return(FALSE);
}
/* If you have a *local* char, send it immediately */
if((!LastInputEvent.bFromRemote) && (LastInputEvent.chKeyPress != 0)
#if 0
&& (LastInputEvent.EventType == EVENT_EXTENDED_KEY)) {
#else
) {
#endif
memcpy(pInputEvent, &LastInputEvent, sizeof(tODInputEvent));
OD_API_EXIT();
return(TRUE);
}
/* IF the received char is a NULL, this is the start of a doorway char */
if(!LastInputEvent.chKeyPress)
bDoorwaySequence = TRUE;
else {
szCurrentSequence[0]=LastInputEvent.chKeyPress;
szCurrentSequence[1]=0;
}
}
nSequenceLen=strlen(szCurrentSequence);
CALL_KERNEL_IF_NEEDED();
/* If you don't have the start of a sequence, and it's not doorway mode, you have
* a char. It's that simple.
*/
if((!bDoorwaySequence) && (!ODHaveStartOfSequence(wFlags))) {
pInputEvent->chKeyPress = szCurrentSequence[0];
pInputEvent->EventType = EVENT_CHARACTER;
pInputEvent->bFromRemote = LastInputEvent.bFromRemote;
/* Shift the sequence buffer over one */
ODShiftSeq(1);
OD_API_EXIT();
return(TRUE);
}
/* Now... if the current sequence IS the longest valid one, return it
* immediately. If it's sequence leftovers, it HAS to be a remote key
* since local chars are #1 always doorway mode and #2 have no delay
* betwixt them.
*/
if((nSequence = ODGetCodeIfLongest(wFlags)) != NO_MATCH) {
pInputEvent->chKeyPress = aKeySequences[nSequence].chExtendedKey;
pInputEvent->EventType = EVENT_EXTENDED_KEY;
pInputEvent->bFromRemote = LastInputEvent.bFromRemote;
/* Shift the sequence buffer... being sure to copy the terminator */
ODShiftSeq(strlen(aKeySequences[nSequence].pszSequence));
OD_API_EXIT();
return(TRUE);
}
/* Now, continue adding chars, waiting at MOST MAX_CHARACTER_LATENCY between them */
CALL_KERNEL_IF_NEEDED();
while((!bDoorwaySequencePending)
&& (ODInQueueGetNextEvent(hODInputQueue, &LastInputEvent, MAX_CHARACTER_LATENCY)
== kODRCSuccess)) {
/* If you are looking for a doorway sequence, any char completes it (honest!) */
/* Further, thanks to some lack of planning, it's EXACTLY THE SAME as the char,
* only it's extended.
*/
if(bDoorwaySequence) {
memcpy(pInputEvent, &LastInputEvent, sizeof(tODInputEvent));
pInputEvent->EventType = EVENT_EXTENDED_KEY;
bDoorwaySequence=FALSE;
OD_API_EXIT();
return(TRUE);
}
/* If we get a 0, we *WILL BE* looking for a doorway sequence. But NOT
* until the current sequence buffer is drained!
*/
if(LastInputEvent.chKeyPress == 0) {
bDoorwaySequencePending=TRUE;
break;
}
/* If you have a *local* char, send it immediately */
if((!LastInputEvent.bFromRemote) && (LastInputEvent.chKeyPress != 0)
#if 0
&& (LastInputEvent.EventType == EVENT_EXTENDED_KEY)) {
#else
) {
#endif
memcpy(pInputEvent, &LastInputEvent, sizeof(tODInputEvent));
OD_API_EXIT();
return(TRUE);
}
/* Put this char into the sequence buffer */
szCurrentSequence[nSequenceLen++]=LastInputEvent.chKeyPress;
szCurrentSequence[nSequenceLen]=0;
/* When you have the longest possible sequence, you ARE done */
if((nSequence = ODGetCodeIfLongest(wFlags)) != NO_MATCH) {
pInputEvent->chKeyPress = aKeySequences[nSequence].chExtendedKey;
pInputEvent->EventType = EVENT_EXTENDED_KEY;
pInputEvent->bFromRemote = LastInputEvent.bFromRemote;
/* Shift the sequence buffer... being sure to copy the terminator */
ODShiftSeq(strlen(aKeySequences[nSequence].pszSequence));
OD_API_EXIT();
return(TRUE);
}
CALL_KERNEL_IF_NEEDED();
}
/* If we were looking for a doorway sequence, tough, we didn't get it. */
if(bDoorwaySequence) {
pInputEvent->chKeyPress = 0;
pInputEvent->EventType = EVENT_CHARACTER;
pInputEvent->bFromRemote = LastInputEvent.bFromRemote;
bDoorwaySequence=FALSE;
OD_API_EXIT();
return(TRUE);
}
/* Now, if we have any kind of sequence, we'll settle for it. */
if((nSequence = ODLongestFullCode(wFlags)) != NO_MATCH) {
pInputEvent->chKeyPress = aKeySequences[nSequence].chExtendedKey;
pInputEvent->EventType = EVENT_EXTENDED_KEY;
pInputEvent->bFromRemote = LastInputEvent.bFromRemote;
/* Shift the sequence buffer... being sure to copy the terminator */
ODShiftSeq(strlen(aKeySequences[nSequence].pszSequence));
OD_API_EXIT();
return(TRUE);
}
/* If we don't have a complete sequence, send a single char */
pInputEvent->chKeyPress = szCurrentSequence[0];
if(szCurrentSequence[0]) {
pInputEvent->EventType = EVENT_CHARACTER;
pInputEvent->bFromRemote = LastInputEvent.bFromRemote;
/* Shift the sequence buffer over one */
ODShiftSeq(1);
}
OD_API_EXIT();
/* Return false if something broke */
return(pInputEvent->chKeyPress);
}
/* ----------------------------------------------------------------------------
* ODLongestFullCode() *** PRIVATE FUNCTION ***
*
* Return the index of the longest full code that matches the start of the
* sequence buffer
*
* Parameters: wFlags from od_get_input()
*
* Return: void
*/
static int ODLongestFullCode(WORD wFlags)
{
int CurrLen=0;
int seqlen;
int i;
int retval=NO_MATCH;;
if(wFlags & GETIN_RAW)
return(NO_MATCH);
for(i = 0; i < DIM(aKeySequences); ++i) {
if((wFlags & GETIN_RAWCTRL) && aKeySequences[i].bIsControlKey) {
continue;
}
seqlen=strlen(aKeySequences[i].pszSequence);
if(seqlen>CurrLen) {
if(strncmp(aKeySequences[i].pszSequence, szCurrentSequence, seqlen)==0) {
retval=i;
CurrLen=seqlen;
}
}
}
return(retval);
}
/* ----------------------------------------------------------------------------
* ODHaveStartOfSequence() *** PRIVATE FUNCTION ***
*
* If the current sequence buffer is the start of a valid sequence, return TRUE
*
* Parameters: wFlags from od_get_input()
*
* Return: void
*/
static int ODHaveStartOfSequence(WORD wFlags)
{
int seqlen1;
int seqlen2;
int i;
if(wFlags & GETIN_RAW)
return(FALSE);
seqlen1=strlen(szCurrentSequence);
for(i = 0; i < DIM(aKeySequences); ++i) {
if((wFlags & GETIN_RAWCTRL) && aKeySequences[i].bIsControlKey) {
continue;
}
seqlen2=strlen(aKeySequences[i].pszSequence);
if(seqlen1<seqlen2)
seqlen2=seqlen1;
if(strncmp(aKeySequences[i].pszSequence, szCurrentSequence, seqlen2)==0) {
return(TRUE);
}
}
return(FALSE);
}
/* ----------------------------------------------------------------------------
* ODGetCodeIfLongest() *** PRIVATE FUNCTION ***
*
* Returns the index of the entry in the sequence buffer only if there
* are no longer sequences that could start the same way.
*
* Parameters: wFlags from od_get_input()
*
* Return: void
*/
static int ODGetCodeIfLongest(WORD wFlags)
{
int CurrLen=0;
int seqlen1;
int seqlen2;
int i;
int retval=NO_MATCH;;
if(wFlags & GETIN_RAW)
return(NO_MATCH);
seqlen1=strlen(szCurrentSequence);
for(i = 0; i < DIM(aKeySequences); ++i) {
if((wFlags & GETIN_RAWCTRL) && aKeySequences[i].bIsControlKey) {
continue;
}
seqlen2=strlen(aKeySequences[i].pszSequence);
if(seqlen2>CurrLen) {
if(seqlen2<=seqlen1) { /* The sequence would be completed in buffer */
if(strncmp(aKeySequences[i].pszSequence, szCurrentSequence, seqlen2)==0) {
retval=i;
CurrLen=seqlen2;
}
}
else { /* Possible partial sequence */
if(strncmp(aKeySequences[i].pszSequence, szCurrentSequence, seqlen1)==0) {
return(NO_MATCH);
}
}
}
}
return(retval);
}
/* ----------------------------------------------------------------------------
* ODShiftSeq() *** PRIVATE FUNCTION ***
*
* Shifts szCurrentSequence left the specified number of chars
*
* Parameters: int chars to shift
*
* Return: void
*/
static void ODShiftSeq(int chars)
{
char *in;
char *out;
if(!chars)
return;
out=szCurrentSequence;
in=out+chars;
if(in>strchr(szCurrentSequence,0))
return;
while(*in) {
*(out++)=*(in++);
}
*out=*in;
}

View File

@ -0,0 +1,247 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODGraph.c
*
* Description: Implements special ANSI/AVATAR control functions.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Oct 13, 1994 6.00 BP New file header format.
* Dec 09, 1994 6.00 BP Standardized coding style.
* Aug 19, 1995 6.00 BP 32-bit portability.
* Nov 11, 1995 6.00 BP Removed register keyword.
* Nov 14, 1995 6.00 BP Added include of odscrn.h.
* Nov 16, 1995 6.00 BP Removed oddoor.h, added odcore.h.
* Nov 16, 1995 6.00 BP Moved local vars here from odcore.c.
* Dec 12, 1995 6.00 BP Added entry, exit and kernel macros.
* Dec 30, 1995 6.00 BP Added ODCALL for calling convention.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
* Mar 13, 1996 6.10 BP Added od_get_cursor().
* Aug 10, 2003 6.23 SH *nix support
*/
#define BUILDING_OPENDOORS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "OpenDoor.h"
#include "ODCore.h"
#include "ODGen.h"
#include "ODScrn.h"
#include "ODKrnl.h"
/* Local private variables. */
static char szANSIClearLine[3] = {27, '[', 'K'};
static char szAvatarClearLine[2] = {22, 7};
/* ----------------------------------------------------------------------------
* od_clr_line()
*
* Clears the contents of the current line, from the current cursor position
* to the end of the line. This function affects both local and remote
* screens.
*
* Parameters: None.
*
* Return: void
*/
ODAPIDEF void ODCALL od_clr_line(void)
{
char *pchLine;
INT nCharsLeft;
INT nCount;
/* Log function entry if running in trace mode. */
TRACE(TRACE_API, "od_clr_line()");
/* Ensure that OpenDoors has been initialized. */
if(!bODInitialized) od_init();
OD_API_ENTRY();
/* Obtain the current cursor position. */
ODScrnGetTextInfo(&ODTextInfo);
/* Calculate the number of columns that are to be erased. */
nCharsLeft = 80 - ODTextInfo.curx;
/* If either ANSI or AVATAR mode is available, then we first */
/* clear the line on the local screen without affecting the */
/* remote screen. */
if(od_control.user_avatar || od_control.user_ansi)
{
pchLine = (char *)szODWorkString;
for(nCount = 0; nCount <= nCharsLeft; ++nCount) *pchLine++ = ' ';
*pchLine = '\0';
ODScrnEnableScrolling(0);
ODScrnDisplayString(szODWorkString);
ODScrnEnableScrolling(1);
ODScrnSetCursorPos(ODTextInfo.curx, ODTextInfo.cury);
}
/* If AVATAR mode is active. */
if(od_control.user_avatar)
{
/* Transmit the two-character AVATAR clear to end of line sequence. */
od_disp(szAvatarClearLine, 2, FALSE);
}
/* If ANSI mode is active. */
else if(od_control.user_ansi)
{
/* Transmit the three-character ANSI clear to end of line sequence. */
od_disp(szANSIClearLine, 3, FALSE);
}
/* If we are operating in plain-ASCII mode. */
else
{
/* Generate a sequence of space characters followed by backspace */
/* characters. */
pchLine = (char *)szODWorkString;
for(nCount = 0; nCount < nCharsLeft; ++nCount) *pchLine++ = ' ';
for(nCount = 0; nCount < nCharsLeft; ++nCount) *pchLine++ = 8;
*pchLine='\0';
/* Send this sequence to both the local and remote screens. */
od_disp(szODWorkString, strlen(szODWorkString), TRUE);
}
OD_API_EXIT();
}
/* ----------------------------------------------------------------------------
* od_set_cursor()
*
* Moves the position of the cursor on both local and remote screens. This
* function is available in all display modes other than plain-ASCII.
*
* Parameters: nRow - 1-based index of the row to position the cursor in.
*
* nColumn - Index of the column to position the cursor in.
*
* Return: void
*/
ODAPIDEF void ODCALL od_set_cursor(INT nRow, INT nColumn)
{
static char szControlSequence[40];
/* Log function entry if running in trace mode. */
TRACE(TRACE_API, "od_set_cursor()");
/* Ensure that OpenDoors has been initialized. */
if(!bODInitialized) od_init();
OD_API_ENTRY();
/* Check validity of parameters. */
if(nRow < 1 || nColumn < 1)
{
od_control.od_error = ERR_PARAMETER;
return;
}
/* If AVATAR mode is on. */
if(od_control.user_avatar)
{
/* Position the local cursor. */
ODScrnSetCursorPos((BYTE)nColumn, (BYTE)nRow);
/* Generate the AVATAR control sequence to position the remote cursor. */
szControlSequence[0] = 22;
szControlSequence[1] = 8;
szControlSequence[2] = nRow;
szControlSequence[3] = nColumn;
/* Transmit the AVATAR control sequence to the remote terminal. */
od_disp(szControlSequence, 4, FALSE);
}
/* If ANSI mode is on. */
else if(od_control.user_ansi)
{
/* Generate the ANSI control sequence to position the remote cursor. */
sprintf(szControlSequence, "x[%d;%dH", nRow, nColumn);
szControlSequence[0] = 27;
/* Transmit the ANSI control seequence to the remote terminal. */
od_disp(szControlSequence, strlen(szControlSequence), FALSE);
/* Position the cursor on the local screen. */
ODScrnSetCursorPos((BYTE)nColumn, (BYTE)nRow);
}
else
{
/* If neither ANSI nor AVATAR modes are available, indicate this */
/* in the error code in od_control. */
od_control.od_error = ERR_NOGRAPHICS;
}
OD_API_EXIT();
}
/* ----------------------------------------------------------------------------
* od_get_cursor()
*
* Returns our best estimate of the current position of the cursor on the
* remote screen.
*
* Parameters: pnRow - 1-based index of the row to position the cursor in.
*
* pnColumn - Index of the column to position the cursor in.
*
* Return: void
*/
ODAPIDEF void ODCALL od_get_cursor(INT *pnRow, INT *pnColumn)
{
tODScrnTextInfo TextInfo;
/* Log function entry if running in trace mode. */
TRACE(TRACE_API, "od_get_cursor()");
/* Ensure that OpenDoors has been initialized. */
if(!bODInitialized) od_init();
OD_API_ENTRY();
/* Check for parameter validity. */
if(pnRow == NULL && pnColumn == NULL)
{
od_control.od_error = ERR_PARAMETER;
OD_API_EXIT();
return;
}
/* Obtain current state of local screen. */
ODScrnGetTextInfo(&TextInfo);
/* Set the caller's parameters to the current row and column, if each */
/* of these parameters were supplied. */
if(pnRow != NULL) *pnRow = (INT)TextInfo.cury;
if(pnColumn != NULL) *pnColumn = (INT)TextInfo.curx;
OD_API_EXIT();
}

View File

@ -0,0 +1,450 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODInEx.h
*
* Description: OpenDoors initialization and shutdown operations
* (od_init() and od_exit()), including drop file I/O.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Nov 22, 1995 6.00 BP Created.
* Nov 23, 1995 6.00 BP 32-bit portability.
* Dec 03, 1995 6.00 BP Win32 port.
* Jan 19, 1996 6.00 BP Don't use atexit() under Win32.
* Jan 19, 1996 6.00 BP Make ODInitError() a shared function.
* Jan 20, 1996 6.00 BP Prompt for user name if force_local.
* Feb 02, 1996 6.00 BP Added RA 2.50 EXITINFO.BBS support.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Feb 20, 1996 6.00 BP Added bParsedCmdLine.
* Feb 21, 1996 6.00 BP Don't override command line options.
* Feb 21, 1996 6.00 BP Force single-byte structure alignment.
* Feb 23, 1996 6.00 BP Make DTR disable code shared.
* Mar 03, 1996 6.10 BP Begin version 6.10.
*/
#ifndef _INC_ODINEX
#define _INC_ODINEX
#include "ODPlat.h"
/* Drop file structures. */
/* Force byte alignment, if possible */
#ifdef __TURBOC__
#if(__TURBOC__ >= 0x295)
#pragma option -a-
#endif /* __TURBOC__ >= 0x295 */
#endif /* __TURBOC__ */
#ifdef _MSC_VER
#pragma pack(1)
#endif /* _MSC_VER */
typedef struct
{
WORD baud;
DWORD num_calls;
char last_caller[36];
char sLastHandle[36]; /* New to RA 2.50 */
char extra1[92];
char start_date[9];
WORD busyperhour[24];
WORD busyperday[7];
char name[36];
char location[26];
char organisation[51];
char address[3][51];
char handle[36];
char comment[81];
DWORD password_crc;
char dataphone[16];
char homephone[16];
char lasttime[6];
char lastdate[9];
BYTE attrib;
BYTE attrib2;
char flags[4];
DWORD credit;
DWORD pending;
WORD posted;
WORD sec;
DWORD lastread;
DWORD nocalls;
DWORD ups;
DWORD downs;
DWORD upk;
DWORD downk;
DWORD todayk;
INT16 elapsed;
WORD screenlen;
char lastpwdchange;
WORD group;
WORD combinedrecord[200];
char firstcall[9];
char birthday[9];
char subdate[9];
BYTE screenwidth;
BYTE language;
BYTE dateformat;
char forwardto[36];
WORD msgarea;
WORD filearea;
BYTE default_protocol;
WORD file_group;
BYTE last_dob_check;
BYTE sex;
DWORD xirecord;
WORD msg_group;
BYTE btAttribute3; /* New to RA 2.50. */
char sPassword[16]; /* New to RA 2.50. */
BYTE extra2[31];
char status;
char starttime[6];
char errorlevel;
char days;
char forced;
char lasttimerun[9];
char netmailentered;
char echomailentered;
char logintime[6];
char logindate[9];
INT16 timelimit;
DWORD loginsec;
WORD userrecord;
WORD readthru;
WORD numberpages;
WORD downloadlimit;
char timeofcreation[6];
DWORD logonpasswordcrc;
BYTE wantchat;
INT16 deducted_time;
char menustack[50][9];
BYTE menustackpointer;
char extra3[200];
BYTE error_free;
BYTE sysop_next;
char emsi_session;
char emsi_crtdef[41];
char emsi_protocols[41];
char emsi_capabilities[41];
char emsi_requests[41];
char emsi_software[41];
BYTE hold_attr1;
BYTE hold_attr2;
BYTE hold_len;
char page_reason[81];
BYTE status_line;
char last_cost_menu[9];
WORD menu_cost_per_min;
BYTE has_avatar;
BYTE has_rip;
BYTE btRIPVersion; /* New to RA 2.50. */
BYTE btExtraSpace[85];
} tRA2ExitInfoRecord;
typedef struct
{
WORD baud;
DWORD num_calls;
char last_caller[36];
char extraspace[128];
char start_date[9];
WORD busyperhour[24];
WORD busyperday[7];
char uname[36];
char uloc[26];
char password[16];
char dataphone[13];
char homephone[13];
char lasttime[6];
char lastdate[9];
BYTE attrib;
BYTE flags[4];
WORD credit;
WORD pending;
WORD posted;
WORD lastread;
WORD sec;
WORD nocalls;
WORD ups;
WORD downs;
WORD upk;
WORD downk;
WORD todayk;
WORD elapsed;
WORD screenlen;
BYTE lastpwdchange;
BYTE attrib2;
BYTE group;
WORD xirecord;
char extra2[3];
char status;
char starttime[6];
char errorlevel;
char days;
char forced;
char lasttimerun[9];
char netmailentered;
char echomailentered;
char logintime[6];
char logindate[9];
WORD timelimit;
DWORD loginsec;
DWORD net_credit;
WORD userrecord;
WORD readthru;
WORD numberpages;
WORD downloadlimint;
union
{
struct
{
char timeofcreation[6];
char logonpassword[16];
char wantchat;
} ra;
struct
{
char qwantchat;
char gosublevel;
char menustack[20][9];
char menu[9];
BYTE screenclear;
BYTE moreprompts;
BYTE graphicsmode;
BYTE externedit;
INT16 screenlength;
BYTE mnpconnect;
char chatreason[49];
BYTE externlogoff;
BYTE ansicapable;
BYTE ripactive;
BYTE extraspace[199];
} qbbs;
} bbs;
} tExitInfoRecord;
typedef struct
{
INT16 deducted_time;
char menustack[50][9];
char menustackpointer;
char userhandle[36];
char comment[81];
char firstcall[9];
char combinedrecord[25];
char birthday[9];
char subdate[9];
BYTE screenwidth;
BYTE msgarea;
BYTE filearea;
BYTE language;
BYTE dateformat;
char forwardto[36];
char extra_space[43];
char error_free;
char sysop_next;
char emsi_session;
char emsi_crtdef[41];
char emsi_protocols[41];
char emsi_capabilities[41];
char emsi_requests[41];
char emsi_software[41];
char hold_attr1;
char hold_attr2;
char hold_len;
char extr_space[100];
} tExtendedExitInfo;
struct _pcbsys
{
char display[2]; /* "-1" = On, " 0" = Off */
char printer[2];
char pagebell[2];
char calleralarm[2];
char sysopflag; /* ' ', 'N'=sysop next, 'X'=exit to dos */
char errorcorrection[2];
char graphicsmode; /* 'Y'=Yes, 'N'=No, '7'=7E1 */
char nodechat; /* 'A'=available, 'U'=unavailable */
char dteportspeed[5];
char connectspeed[5]; /* "Local"=local mode */
WORD recordnum;
char firstname[15];
char password[15];
INT16 logontimeval; /* minutes since midnight */
INT16 todayused; /* -ve # of minutes */
char logontime[5];
INT16 timeallowed;
WORD kallowed;
char conference;
char joined[5];
char scanned[5];
INT16 conferenceaddtime;
INT16 creditminutes;
char languageext[4];
char fullname[25];
INT16 minutesremaining;
char node; /* ' ' if no network */
char eventtime[5];
char eventactive[2];
char slideevent[2];
DWORD memmessage;
char comport; /* 0=none, 1-8 */
char reserved1[2];
char useansi; /* 1 = yes, 0 = no */
char lasteventdate[8];
WORD lasteventminute;
char dosexit;
char eventupcoming;
char stopuploads;
WORD conferencearea;
};
struct _userssyshdr
{
WORD Version; /* PCBoard version number (i.e. 145) */
DWORD RecNo; /* Record number from USER's file */
WORD SizeOfRec; /* Size of "fixed" user record */
WORD NumOfAreas; /* Number of conference areas (Main=1) */
WORD NumOfBitFields; /* Number of Bit Map fields for conferences */
WORD SizeOfBitFields; /* Size of each Bit Map field */
char AppName[15]; /* Name of the Third Party Application */
WORD AppVersion; /* Version number for the application */
WORD AppSizeOfRec; /* Size of a "fixed length" record (if any) */
WORD AppSizeOfConfRec; /* Size of each conference record (if any) */
DWORD AppRecOffset; /* Offset of AppRec into USERS.INF record */
char Updated; /* TRUE if USERS.SYS has been updated */
};
struct _pcbflags
{
int Dirty :1; /* Dirty Flag (meaning file has been updated) */
int MsgClear :1; /* User's choice for screen clear after messages */
int HasMail :1; /* Indicates if NEW mail has been left for user */
int Reserved :5;
};
struct _pcbdate
{
int Day :5; /* 5 bit integer representing the Day */
int Month :4; /* 4 bit integer representing the Month */
int Year :7; /* 7 bit integer representing the Year MINUS 80 */
};
struct _userssysrec
{
char Name[26]; /* Name (NULL terminated) */
char City[25]; /* City (NULL terminated) */
char Password[13]; /* Password (NULL terminated) */
char BusDataPhone[14]; /* Business or Data Phone (NULL terminated) */
char HomeVoicePhone[14];/* Home or Voice Phone (NULL terminated) */
WORD LastDateOn; /* Julian date for the Last Date On */
char LastTimeOn[6]; /* Last Time On (NULL Terminated) */
char ExpertMode; /* 1=Expert, 0=Novice */
char Protocol; /* Protocol (A thru Z) */
struct _pcbflags PackedFlags;
struct _pcbdate DateLastDirRead;
INT16 SecurityLevel; /* Security Level */
WORD NumTimesOn; /* Number of times the caller has connected */
char PageLen; /* Page Length when display data on the screen */
WORD NumUploads; /* Total number of FILES uploaded */
WORD NumDownloads; /* Total number of FILES downloaded */
DWORD DailyDnldBytes; /* Number of BYTES downloaded so far today */
char UserComment[31]; /* Comment field #1 (NULL terminated) */
char SysopComment[31]; /* Comment field #1 (NULL terminated) */
INT16 ElapsedTimeOn; /* Number of minutes online */
WORD RegExpDate; /* Julian date for Registration Expiration Date */
INT16 ExpSecurityLevel; /* Expired Security Level */
WORD LastConference; /* Number of the conference the caller was in */
DWORD TotDnldBytes; /* Total number of BYTES downloaded */
DWORD TotUpldBytes; /* Total number of BYTES uploaded */
char DeleteFlag; /* 1=delete this record, 0=keep */
DWORD RecNum; /* Record Number in USERS.INF file */
char Reserved[9]; /* Bytes 391-399 from the USERS file */
DWORD MsgsRead; /* Number of messages the user has read in PCB */
DWORD MsgsLeft; /* Number of messages the user has left in PCB */
};
/* Restore original structure alignment, if possible. */
#ifdef _MSC_VER
#pragma pack()
#endif /* _MSC_VER */
/* od_init() and od_exit() global helper functons. */
#ifndef ODPLAT_WIN32
void ODAtExitCallback(void);
#endif /* !ODPLAT_WIN32 */
INT ODWriteExitInfoPrimitive(FILE *pfDropFile, INT nCount);
BOOL ODReadExitInfoPrimitive(FILE *pfDropFile, INT nCount);
INT ODSearchForDropFile(char **papszFileNames, INT nNumFileNames,
char *pszFound, char *pszDirectory);
void ODInitError(char *pszErrorText);
#ifdef ODPLAT_WIN32
BOOL CALLBACK ODInitLoginDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,
LPARAM lParam);
void ODInExDisableDTR(void);
#endif /* ODPLAT_WIN32 */
/* Global variables. */
extern WORD wODNodeNumber;
extern BOOL bIsCoSysop;
extern BOOL bIsSysop;
extern char *apszDropFileInfo[25];
extern BYTE btExitReason;
extern DWORD dwForcedBPS;
extern INT nForcedPort;
extern DWORD dwFileBPS;
extern char szDropFilePath[120];
extern char szExitinfoBBSPath[120];
extern INT16 nInitialElapsed;
extern char *szOriginalDir;
extern BYTE btDoorSYSLock;
extern time_t nStartupUnixTime;
extern INT16 nInitialRemaining;
extern BOOL bSysopNameSet;
extern char szForcedSysopName[40];
extern BOOL bSystemNameSet;
extern char szForcedSystemName[40];
extern BOOL bUserFull;
extern BOOL bCalledFromConfig;
extern tRA2ExitInfoRecord *pRA2ExitInfoRecord;
extern tExitInfoRecord *pExitInfoRecord;
extern tExtendedExitInfo *pExtendedExitInfo;
extern struct _pcbsys *pPCBoardSysRecord;
extern struct _userssyshdr *pUserSysHeader;
extern struct _userssysrec *pUserSysRecord;
extern BOOL bPreOrExit;
extern BOOL bRAStatus;
extern BOOL bPromptForUserName;
extern BOOL bParsedCmdLine;
extern WORD wPreSetInfo;
#ifdef ODPLAT_WIN32
extern tODThreadHandle hFrameThread;
#endif /* ODPLAT_WIN32 */
/* wPreSetInfo flags. */
#define PRESET_BPS 0x0001
#define PRESET_PORT 0x0002
#define PRESET_REQUIRED (PRESET_BPS | PRESET_PORT)
#endif /* _INC_ODINEX */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,443 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODInQue.h
*
* Description: OpenDoors input queue management. This input queue is where
* all input events (e.g. keystrokes) from both local and remote
* systems are combined into a single stream.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Nov 16, 1995 6.00 BP Created.
* Nov 17, 1995 6.00 BP Added multithreading support.
* Jan 04, 1996 6.00 BP tODInQueueEvent -> tODInputEvent.
* Jan 30, 1996 6.00 BP Replaced od_yield() with od_sleep().
* Jan 30, 1996 6.00 BP Add semaphore timeout.
* Jan 30, 1996 6.00 BP Add ODInQueueGetNextEvent() timeout.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
* Aug 10, 2003 6.23 SH *nix support
*/
#define BUILDING_OPENDOORS
#include <stdlib.h>
#include <string.h>
#include "OpenDoor.h"
#include "ODGen.h"
#include "ODInQue.h"
#include "ODPlat.h"
#include "ODKrnl.h"
/* Input queue handle structure. */
typedef struct
{
tODInputEvent *paEvents;
INT nQueueEntries;
INT nInIndex;
INT nOutIndex;
time_t nLastActivityTime;
#ifdef OD_MULTITHREADED
tODSemaphoreHandle hItemCountSemaphore;
tODSemaphoreHandle hAddEventSemaphore;
#endif /* OD_MULTITHREADED */
} tInputQueueInfo;
/* ----------------------------------------------------------------------------
* ODInQueueAlloc()
*
* Allocates a new input queue.
*
* Parameters: phInQueue - Pointer to location where a handle to the
* newly allocated input queue should be
* stored.
*
* nInitialQueueSize - The minimum number of events that the
* input queue should be able to hold.
*
* Return: kODRCSuccess on success, or an error code on failure.
*/
tODResult ODInQueueAlloc(tODInQueueHandle *phInQueue, INT nInitialQueueSize)
{
tInputQueueInfo *pInputQueueInfo = NULL;
tODInputEvent *pInputQueue = NULL;
tODResult Result = kODRCNoMemory;
ASSERT(phInQueue != NULL);
if(phInQueue == NULL) return(kODRCInvalidCall);
/* Attempt to allocate a serial port information structure. */
pInputQueueInfo = malloc(sizeof(tInputQueueInfo));
/* If memory allocation failed, return with failure. */
if(pInputQueueInfo == NULL) goto CleanUp;
/* Initialize semaphore handles to NULL. */
#ifdef OD_MULTITHREADED
pInputQueueInfo->hItemCountSemaphore = NULL;
pInputQueueInfo->hAddEventSemaphore = NULL;
#endif /* OD_MULTITHREADED */
/* Attempt to allocate space for the queue itself. */
pInputQueue = calloc(nInitialQueueSize, sizeof(tODInputEvent));
if(pInputQueue == NULL) goto CleanUp;
/* Create semaphores if this is a multithreaded platform. */
#ifdef OD_MULTITHREADED
if(ODSemaphoreAlloc(&pInputQueueInfo->hItemCountSemaphore, 0,
nInitialQueueSize) != kODRCSuccess)
{
goto CleanUp;
}
if(ODSemaphoreAlloc(&pInputQueueInfo->hAddEventSemaphore, 1, 1)
!= kODRCSuccess)
{
goto CleanUp;
}
#endif /* OD_MULTITHREADED */
/* Initialize input queue information structure. */
pInputQueueInfo->paEvents = pInputQueue;
pInputQueueInfo->nQueueEntries = nInitialQueueSize;
pInputQueueInfo->nInIndex = 0;
pInputQueueInfo->nOutIndex = 0;
/* Convert intut queue information structure pointer to a handle. */
*phInQueue = ODPTR2HANDLE(pInputQueueInfo, tInputQueueInfo);
/* Reset the time of the last activity. */
ODInQueueResetLastActivity(*phInQueue);
Result = kODRCSuccess;
CleanUp:
if(Result != kODRCSuccess)
{
#ifdef OD_MULTITHREADED
if(pInputQueueInfo != NULL
&& pInputQueueInfo->hItemCountSemaphore != NULL)
{
ODSemaphoreFree(pInputQueueInfo->hItemCountSemaphore);
}
if(pInputQueueInfo != NULL
&& pInputQueueInfo->hAddEventSemaphore != NULL)
{
ODSemaphoreFree(pInputQueueInfo->hAddEventSemaphore);
}
#endif /* OD_MULTITHREADED */
if(pInputQueue != NULL) free(pInputQueue);
if(pInputQueueInfo != NULL) free(pInputQueueInfo);
*phInQueue = ODPTR2HANDLE(NULL, tInputQueueInfo);
}
/* Return with the appropriate result code. */
return(Result);
}
/* ----------------------------------------------------------------------------
* ODInQueueFree()
*
* Destroys an input queue that was previously created by ODInQueueAlloc().
*
* Parameters: hInQueue - Handle to the input queue to destroy.
*
* Return: void
*/
void ODInQueueFree(tODInQueueHandle hInQueue)
{
tInputQueueInfo *pInputQueueInfo = ODHANDLE2PTR(hInQueue, tInputQueueInfo);
ASSERT(pInputQueueInfo != NULL);
/* Deallocate semaphores, if appropriate. */
#ifdef OD_MULTITHREADED
ASSERT(pInputQueueInfo->hItemCountSemaphore != NULL);
ODSemaphoreFree(pInputQueueInfo->hItemCountSemaphore);
#endif /* OD_MULTITHREADED */
/* Deallocate the input queue itself. */
ASSERT(pInputQueueInfo->paEvents != NULL);
free(pInputQueueInfo->paEvents);
/* Deallocate port information structure. */
free(pInputQueueInfo);
}
/* ----------------------------------------------------------------------------
* ODInQueueWaiting()
*
* Determines whether or not an event is currently waiting in the input queue.
*
* Parameters: hInQueue - Handle to the input queue to check.
*
* Return: TRUE if there is one or more waiting events, or FALSE if the
* queue is empty.
*/
BOOL ODInQueueWaiting(tODInQueueHandle hInQueue)
{
tInputQueueInfo *pInputQueueInfo = ODHANDLE2PTR(hInQueue, tInputQueueInfo);
BOOL bEventWaiting;
ASSERT(pInputQueueInfo != NULL);
/* There is data waiting in the queue if the in index is not equal to */
/* the out index. */
bEventWaiting = (pInputQueueInfo->nInIndex != pInputQueueInfo->nOutIndex);
return(bEventWaiting);
}
/* ----------------------------------------------------------------------------
* ODInQueueAddEvent()
*
* Adds a new event to the input queue.
*
* Parameters: hInQueue - Handle to the input queue to add an event to.
*
* pEvent - Pointer to the event structure to obtain the
* event information from.
*
* Return: kODRCSuccess on success, or an error code on failure.
*/
tODResult ODInQueueAddEvent(tODInQueueHandle hInQueue,
tODInputEvent *pEvent)
{
tInputQueueInfo *pInputQueueInfo = ODHANDLE2PTR(hInQueue, tInputQueueInfo);
INT nNextInPos;
ASSERT(pInputQueueInfo != NULL);
ASSERT(pEvent != NULL);
if(pInputQueueInfo == NULL || pEvent == NULL) return(kODRCInvalidCall);
/* Serialize access to add event function. */
#ifdef OD_MULTITHREADED
ODSemaphoreDown(pInputQueueInfo->hAddEventSemaphore, OD_NO_TIMEOUT);
#endif /* OD_MULTITHREADED */
/* Reset the time of the last activity. */
ODInQueueResetLastActivity(hInQueue);
/* Determine what the next in index would be after this addition to the */
/* queue. */
nNextInPos = (pInputQueueInfo->nInIndex + 1)
% pInputQueueInfo->nQueueEntries;
/* If the queue is full, then return an out of space error. */
if(nNextInPos == pInputQueueInfo->nOutIndex)
{
/* Allow further access to input queue. */
#ifdef OD_MULTITHREADED
ODSemaphoreUp(pInputQueueInfo->hAddEventSemaphore, 1);
#endif /* OD_MULTITHREADED */
return(kODRCNoMemory);
}
/* Otherwise, add the new event to the input queue. */
memcpy(&pInputQueueInfo->paEvents[pInputQueueInfo->nInIndex], pEvent,
sizeof(tODInputEvent));
/* Update queue in index. */
pInputQueueInfo->nInIndex = nNextInPos;
/* Increment queue items count semaphore. */
#ifdef OD_MULTITHREADED
ODSemaphoreUp(pInputQueueInfo->hItemCountSemaphore, 1);
#endif /* OD_MULTITHREADED */
/* Allow further access to add event function. */
#ifdef OD_MULTITHREADED
ODSemaphoreUp(pInputQueueInfo->hAddEventSemaphore, 1);
#endif /* OD_MULTITHREADED */
return(kODRCSuccess);
}
/* ----------------------------------------------------------------------------
* ODInQueueGetNextEvent()
*
* Obtains the next event from the input queue. If no events are currently
* waiting in the input queue, this function blocks until an item is added
* to the queue, or the maximum wait time is reached.
*
* Parameters: hInQueue - Handle to the input queue to obtain the next event
* from.
*
* pEvent - Pointer to structure to store input event information
* in.
*
* Timeout - Maximum time, in milliseconds, to wait for next input
* event. A value of OD_NO_TIMEOUT causes this function
* to only return when an input event is obtained.
*
* Return: kODRCSuccess on succes, or kODRCTimeout if the maximum wait time
* is exceeded.
*/
tODResult ODInQueueGetNextEvent(tODInQueueHandle hInQueue,
tODInputEvent *pEvent, tODMilliSec Timeout)
{
tInputQueueInfo *pInputQueueInfo = ODHANDLE2PTR(hInQueue, tInputQueueInfo);
ASSERT(pInputQueueInfo != NULL);
ASSERT(pEvent != NULL);
#ifdef OD_MULTITHREADED
/* In multithreaded implementations, we wait for there to be an item in */
/* the queue by decrementing the queue size semaphore. This will cause */
/* this thread to be blocked until an event is added to the queue, if it */
/* is currently empty. */
if(ODSemaphoreDown(pInputQueueInfo->hItemCountSemaphore, Timeout)==kODRCTimeout)
return(kODRCTimeout);
#else /* !OD_MULTITHREADED */
/* In non-multithreaded implementations, we check queue in and out */
/* indicies to determine whether there are any events waiting in the */
/* queue. If the queue is empty we loop, calling od_kernel() to check */
/* for new events and od_yeild() to give more time to other processors */
/* if there is nothing for us to do, until an event is added to the */
/* queue. */
if(pInputQueueInfo->nInIndex == pInputQueueInfo->nOutIndex)
{
tODTimer Timer;
/* If a timeout has been specified, then start timer to keep track */
/* of how long we have been waiting. */
if(Timeout != 0 && Timeout != OD_NO_TIMEOUT)
{
ODTimerStart(&Timer, Timeout);
}
/* As soon as we see that there is nothing in the queue, we do an */
/* od_kernel() call to check for new input. */
CALL_KERNEL_IF_NEEDED();
/* As long as we don't have new input, we loop, yielding to other */
/* processes, and then giving od_kernel() a chance to run. */
while(pInputQueueInfo->nInIndex == pInputQueueInfo->nOutIndex)
{
/* If a timeout has been specified, then ensure that the maximum */
/* wait time has not elapsed. */
if(Timeout != 0 && Timeout != OD_NO_TIMEOUT
&& ODTimerElapsed(&Timer))
{
return(kODRCTimeout);
}
/* Yield the processor to other tasks. */
od_sleep(0);
/* Call od_kernel(). */
CALL_KERNEL_IF_NEEDED();
}
}
#endif /* !OD_MULTITHREADED */
/* Copy next input event from the queue into the caller's structure. */
memcpy(pEvent, &pInputQueueInfo->paEvents[pInputQueueInfo->nOutIndex],
sizeof(tODInputEvent));
/* Move out pointer to the next queue item, wrapping back to the start */
/* of the queue if needed. */
pInputQueueInfo->nOutIndex
= (pInputQueueInfo->nOutIndex + 1) % pInputQueueInfo->nQueueEntries;
/* Now, return with success. */
return(kODRCSuccess);
}
/* ----------------------------------------------------------------------------
* ODInQueueEmpty()
*
* Removes all events from the input queue.
*
* Parameters: hInQueue - Handle to the input queue to be emptied.
*
* Return: void
*/
void ODInQueueEmpty(tODInQueueHandle hInQueue)
{
tODInputEvent InputEvent;
ASSERT(hInQueue != NULL);
/* Remove all items from the queue. */
while(ODInQueueWaiting(hInQueue))
{
ODInQueueGetNextEvent(hInQueue, &InputEvent, OD_NO_TIMEOUT);
}
}
/* ----------------------------------------------------------------------------
* ODInQueueGetLastActivity()
*
* Returns the time of the last input activity. This is the latest of the time
* that the queue was created, the time of the last call to
* ODInQueueAddEvent() on this input queue, and the time of the last call to
* ODInQueueResetLastActivity() on this input queue.
*
* Parameters: hInQueue - Handle to the input queue.
*
* Return: void
*/
time_t ODInQueueGetLastActivity(tODInQueueHandle hInQueue)
{
tInputQueueInfo *pInputQueueInfo = ODHANDLE2PTR(hInQueue, tInputQueueInfo);
ASSERT(pInputQueueInfo != NULL);
/* Returns the last activity time. */
return(pInputQueueInfo->nLastActivityTime);
}
/* ----------------------------------------------------------------------------
* ODInQueueResetLastActivity()
*
* Resets the time of the last input activity to the current time.
*
* Parameters: hInQueue - Handle to the input queue.
*
* Return: void
*/
void ODInQueueResetLastActivity(tODInQueueHandle hInQueue)
{
tInputQueueInfo *pInputQueueInfo = ODHANDLE2PTR(hInQueue, tInputQueueInfo);
ASSERT(pInputQueueInfo != NULL);
/* Resets the last activity time to the current time. */
pInputQueueInfo->nLastActivityTime = time(NULL);
}

View File

@ -0,0 +1,57 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODInQue.h
*
* Description: OpenDoors input queue management. This input queue is where
* all input events (e.g. keystrokes) from both local and remote
* systems are combined into a single stream.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Nov 16, 1995 6.00 BP Created.
* Jan 04, 1996 6.00 BP Moved event type defs to OpenDoor.h.
* Jan 04, 1996 6.00 BP tODInQueueEvent -> tODInputEvent.
* Jan 30, 1996 6.00 BP Add ODInQueueGetNextEvent() timeout.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
*/
#ifndef _INC_ODINQUE
#define _INC_ODINQUE
#include <time.h>
#include "ODTypes.h"
/* OpenDoors input queue handle. */
typedef tODHandle tODInQueueHandle;
/* Input queue functions. */
tODResult ODInQueueAlloc(tODInQueueHandle *phInQueue, INT nInitialQueueSize);
void ODInQueueFree(tODInQueueHandle hInQueue);
BOOL ODInQueueWaiting(tODInQueueHandle hInQueue);
tODResult ODInQueueAddEvent(tODInQueueHandle hInQueue,
tODInputEvent *pEvent);
tODResult ODInQueueGetNextEvent(tODInQueueHandle hInQueue,
tODInputEvent *pEvent, tODMilliSec Timeout);
void ODInQueueEmpty(tODInQueueHandle hInQueue);
time_t ODInQueueGetLastActivity(tODInQueueHandle hInQueue);
void ODInQueueResetLastActivity(tODInQueueHandle hInQueue);
#endif /* _INC_ODINQUE */

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,88 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODKrnl.h
*
* Description: Contains the public definitions related to odkrnl.c
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Jan 01, 1995 6.00 BP Split off from odcore.c and oddoor.h
* Dec 12, 1995 6.00 BP Added entry, exit and kernel macros.
* Jan 12, 1996 6.00 BP Added bOnlyShiftArrow.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
* Mar 13, 1996 6.10 BP bOnlyShiftArrow -> nArrowUseCount.
*/
#ifndef _INC_ODKRNL
#define _INC_ODKRNL
#include "ODPlat.h"
/* Global kernel-related variables. */
extern tODTimer RunKernelTimer;
extern time_t nNextTimeDeductTime;
extern char chLastControlKey;
extern INT nArrowUseCount;
extern BOOL bForceStatusUpdate;
extern BOOL bSysopColor;
#ifdef OD_MULTITHREADED
extern tODSemaphoreHandle hODActiveSemaphore;
#endif /* OD_MULTITHREADED */
/* Chat mode global variables. */
extern BOOL bIsShell;
extern BOOL bChatted;
/* Kernel function prototypes. */
tODResult ODKrnlInitialize(void);
void ODKrnlShutdown(void);
void ODKrnlHandleLocalKey(WORD wKeyCode);
void ODKrnlEndChatMode(void);
void ODKrnlForceOpenDoorsShutdown(BYTE btReasonForShutdown);
#ifdef OD_MULTITHREADED
tODResult ODKrnlStartChatThread(BOOL bTriggeredInternally);
#endif /* OD_MULTITHREADED */
/* Macro used to generate the appropriate code (if any) to call */
/* the OpenDoors kernel from within OpenDoors code. */
#ifdef OD_MULTITHREADED
#define CALL_KERNEL_IF_NEEDED()
#else /* !OD_MULTITHREADED */
#ifdef ODPLAT_NIX
#ifdef USE_KERNEL_SIGNAL
#define CALL_KERNEL_IF_NEEDED()
#else
#define CALL_KERNEL_IF_NEEDED() od_kernel()
#endif
#else
#define CALL_KERNEL_IF_NEEDED() od_kernel()
#endif /* !ODPLAT_NIX */
#endif /* !OD_MULTITHREADED */
/* Macro used to increment or decrement OpenDoors active semaphore. */
#ifdef OD_MULTITHREADED
#define OD_API_ENTRY() ODSemaphoreUp(hODActiveSemaphore, 1);
#define OD_API_EXIT() ODSemaphoreDown(hODActiveSemaphore, 1);
#else /* !OD_MULTITHREADED */
#define OD_API_ENTRY()
#define OD_API_EXIT()
#endif /* !OD_MULTITHREADED */
#endif /* _INC_ODKRNL */

View File

@ -0,0 +1,565 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODList.c
*
* Description: Implements the od_list_files() function for displaying
* a FILES.BBS file.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Oct 13, 1994 6.00 BP New file header format.
* Oct 21, 1994 6.00 BP Further isolated com routines.
* Dec 09, 1994 6.00 BP Use new directory access functions.
* Dec 31, 1994 6.00 BP Remove #ifndef USEINLINE DOS code.
* Aug 19, 1995 6.00 BP 32-bit portability.
* Nov 11, 1995 6.00 BP Moved functions from odcore.c
* Nov 11, 1995 6.00 BP Removed register keyword.
* Nov 16, 1995 6.00 BP Removed oddoor.h, added odcore.h.
* Dec 12, 1995 6.00 BP Added entry, exit and kernel macros.
* Dec 30, 1995 6.00 BP Added ODCALL for calling convention.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
* Aug 10, 2003 6.23 SH *nix support
*/
#define BUILDING_OPENDOORS
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "OpenDoor.h"
#include "ODCore.h"
#include "ODGen.h"
#include "ODCom.h"
#include "ODPlat.h"
#include "ODKrnl.h"
#include "ODUtil.h"
/* Filename component identifies. */
#define WILDCARDS 0x01
#define EXTENSION 0x02
#define FILENAME 0x04
#define DIRECTORY 0x08
#define DRIVE 0x10
/* Local private helper function prototypes. */
static void ODListFilenameMerge(char *pszEntirePath, const char *pszDrive,
const char *pszDir, const char *pszName, const char *pszExtension);
static char *ODListGetFirstWord(char *pszInStr, char *pszOutStr);
static char *ODListGetRemainingWords(char *pszInStr);
static INT ODListFilenameSplit(const char *pszEntirePath, char *pszDrive,
char *pszDir, char *pszName, char *pszExtension);
/* ----------------------------------------------------------------------------
* od_list_files()
*
* Displays a list of files available for download, using an extended version
* of the standard FILES.BBS format index file.
*
* Parameters: pszFileSpec - Directory name where the FILES.BBS file can be
* found, or full path and filename of a FILES.BBS
* format index file.
*
* Return: TRUE on success or FALSE on failure.
*/
ODAPIDEF BOOL ODCALL od_list_files(char *pszFileSpec)
{
BYTE btLineCount = 2;
BOOL bPausing;
static char szLine[513];
static char szFilename[80];
static char szDrive[3];
static char szDir[70];
static char szTemp1[9];
static char szTemp2[5];
static char szBaseName[9];
static char szExtension[5];
static char szDirectory[100];
INT nFilenameInfo;
FILE *pfFilesBBS;
static char *pszCurrent;
BOOL bIsDir;
BOOL bUseNextLine = TRUE;
tODDirHandle hDir;
tODDirEntry DirEntry;
/* Log function entry if running in trace mode. */
TRACE(TRACE_API, "od_list_files()");
/* Initialize OpenDoors if it hasn't already been done. */
if(!bODInitialized) od_init();
OD_API_ENTRY();
/* Check user's page pausing setting. */
bPausing = od_control.od_page_pausing;
if(od_control.od_extended_info) bPausing = od_control.user_attribute & 0x04;
/* Parse directory parameter. */
if(pszFileSpec == NULL)
{
strcpy(szODWorkString, ".");
strcpy(szDirectory, "."DIRSEP_STR);
}
else if(*pszFileSpec == '\0')
{
strcpy(szODWorkString, ".");
strcpy(szDirectory, "."DIRSEP_STR);
}
else
{
strcpy(szODWorkString, pszFileSpec);
strcpy(szDirectory, pszFileSpec);
if(szODWorkString[strlen(szODWorkString) - 1] == DIRSEP)
{
szODWorkString[strlen(szODWorkString) - 1] = '\0';
}
}
/* Get directory information on path. */
if(ODDirOpen(szODWorkString, DIR_ATTRIB_ARCH | DIR_ATTRIB_RDONLY
| DIR_ATTRIB_DIREC, &hDir) != kODRCSuccess)
{
od_control.od_error = ERR_FILEOPEN;
OD_API_EXIT();
return(FALSE);
}
if(ODDirRead(hDir, &DirEntry) != kODRCSuccess)
{
ODDirClose(hDir);
od_control.od_error = ERR_FILEOPEN;
OD_API_EXIT();
return(FALSE);
}
ODDirClose(hDir);
/* If it is a directory. */
if(DirEntry.wAttributes & DIR_ATTRIB_DIREC)
{
/* Append FILES.BBS to directory name & open. */
bIsDir = TRUE;
ODMakeFilename(szODWorkString, szODWorkString, "FILES.BBS",
sizeof(szODWorkString));
if((pfFilesBBS = fopen(szODWorkString, "r")) == NULL)
{
od_control.od_error = ERR_FILEOPEN;
OD_API_EXIT();
return(FALSE);
}
}
/* If it is not a directory. */
else
{
bIsDir = FALSE;
if((pfFilesBBS = fopen(szODWorkString,"r")) == NULL)
{
od_control.od_error = ERR_FILEOPEN;
OD_API_EXIT();
return(FALSE);
}
}
/* Ignore previously pressed control keys. */
chLastControlKey = 0;
/* Loop until the end of the FILES.BBS file has been reached. */
for(;;)
{
if(fgets(szLine, 512, pfFilesBBS) == NULL) break;
if(!bUseNextLine)
{
if(szLine[strlen(szLine) - 1] == '\n')
{
bUseNextLine = TRUE;
}
continue;
}
if(szLine[strlen(szLine) - 1] == '\n')
{
szLine[strlen(szLine) - 1] = '\0';
}
else
{
bUseNextLine = FALSE;
}
if(szLine[strlen(szLine) - 1] == '\r')
{
szLine[strlen(szLine) - 1] = '\0';
}
if(chLastControlKey != 0)
{
switch(chLastControlKey)
{
case 's':
if(od_control.od_list_stop)
{
if(od_control.baud)
{
ODComClearOutbound(hSerialPort);
}
od_clear_keybuffer();
fclose(pfFilesBBS);
OD_API_EXIT();
return(TRUE);
}
break;
case 'p':
if(od_control.od_list_pause)
{
od_clear_keybuffer();
od_get_key(TRUE);
}
}
chLastControlKey = 0;
}
/* Determine whether or not this is a comment line. */
if(szLine[0] == ' ' || strlen(szLine) == 0)
{
/* If so, display the line in comment color. */
od_set_attrib(od_control.od_list_title_col);
od_disp_str(szLine);
od_disp_str("\n\r");
++btLineCount;
}
/* If the line is not a comment. */
else
{
/* Extract the first word of the line, */
ODListGetFirstWord(szLine, szFilename);
/* And extract the filename. */
nFilenameInfo = ODListFilenameSplit(szFilename, szDrive, szDir,
szBaseName, szExtension);
if(!((nFilenameInfo & DRIVE) || (nFilenameInfo & DIRECTORY)))
{
if(bIsDir)
{
ODMakeFilename(szDirectory, szDirectory, szFilename,
sizeof(szDirectory));
strcpy(szFilename, szDirectory);
}
else
{
ODListFilenameSplit(szDirectory, szDrive, szDir, szTemp1,
szTemp2);
ODListFilenameMerge(szFilename, szDrive, szDir, szBaseName,
szExtension);
}
}
/* Search for the filespec in directory. */
if(ODDirOpen(szFilename, DIR_ATTRIB_ARCH | DIR_ATTRIB_RDONLY, &hDir)
== kODRCSuccess)
{
/* Display information on every file that matches. */
while(ODDirRead(hDir, &DirEntry) == kODRCSuccess)
{
od_set_attrib(od_control.od_list_name_col);
od_printf("%-12.12s ", DirEntry.szFileName);
od_set_attrib(od_control.od_list_size_col);
od_printf("%-6ld ", DirEntry.dwFileSize);
od_set_attrib(od_control.od_list_comment_col);
pszCurrent = ODListGetRemainingWords(szLine);
if(strlen(pszCurrent) <= 56)
{
od_disp_str(pszCurrent);
od_disp_str("\n\r");
}
else
{
od_printf("%-56.56s\n\r", pszCurrent);
}
++btLineCount;
}
ODDirClose(hDir);
}
/* Otherwise, indicate that the file is "Offline". */
else
{
ODListFilenameMerge(szFilename, "", "", szBaseName, szExtension);
od_set_attrib(od_control.od_list_name_col);
od_printf("%-12.12s ", szFilename);
od_set_attrib(od_control.od_list_offline_col);
od_disp_str(od_control.od_offline);
od_set_attrib(od_control.od_list_comment_col);
od_printf("%-56.56s\n\r", ODListGetRemainingWords(szLine));
++btLineCount;
}
}
/* Check for end of screen & page pausing. */
if(btLineCount >= od_control.user_screen_length && bPausing)
{
/* Provide page pausing at end of each screen. */
if(ODPagePrompt(&bPausing))
{
fclose(pfFilesBBS);
OD_API_EXIT();
return(TRUE);
}
/* Reset the line number counter. */
btLineCount = 2;
}
}
/* When finished, close the file. */
fclose(pfFilesBBS);
/* Return with success. */
OD_API_EXIT();
return(TRUE);
}
/* ----------------------------------------------------------------------------
* ODListFilenameMerge() *** PRIVATE FUNCTION ***
*
* Builds a fully-qualified path name from the provided path component
* strings.
*
* Parameters: pszEntirePath - Pointer to the destination string where the
* generated path should be stored.
*
* pszDrive - Pointer to the drive string.
*
* pszDir - Pointer to the directory string.
*
* pszName - Pointer to the base filename string.
*
* pszExtension - Pointer to the extension name string.
*
* Return: void
*/
static void ODListFilenameMerge(char *pszEntirePath, const char *pszDrive,
const char *pszDir, const char *pszName, const char *pszExtension)
{
if(pszEntirePath == NULL) return;
pszEntirePath[0] = '\0';
if(pszDrive != NULL)
{
strcpy(pszEntirePath, pszDrive);
}
if(pszDir != NULL)
{
strcat(pszEntirePath, pszDir);
}
if(pszName != NULL)
{
strcat(pszEntirePath,pszName);
}
if(pszExtension != NULL)
{
strcat(pszEntirePath,pszExtension);
}
}
/* ----------------------------------------------------------------------------
* ODListFilenameSplit() *** PRIVATE FUNCTION ***
*
* Splits the provided path string into drive, directory name, file base name
* and file extension components.
*
* Parameters: pszEntirePath - A string containing the path to split.
*
* pszDrive - A string where the drive letter should be stored.
*
* pszDir - A string where the directory name should be
* stored.
*
* pszName - A string where the base filename should be
* stored.
*
* pszExtension - A string where the filename extension should be
* stored.
*
* Return: One or more flags indicating which components where found in the
* provided path name.
*/
static INT ODListFilenameSplit(const char *pszEntirePath, char *pszDrive,
char *pszDir, char *pszName, char *pszExtension)
{
char *pchCurrentPos;
char *pchStart;
BYTE btSize;
INT nToReturn;
ASSERT(pszEntirePath != NULL);
ASSERT(pszDrive != NULL);
ASSERT(pszDir != NULL);
ASSERT(pszName != NULL);
ASSERT(pszExtension != NULL);
pchStart = (char *)pszEntirePath;
nToReturn = 0;
if((pchCurrentPos = strrchr(pchStart,':')) == NULL)
{
pszDrive[0] = '\0';
}
else
{
btSize = (int)(pchCurrentPos - pchStart) + 1;
if(btSize > 2) btSize = 2;
strncpy(pszDrive, pchStart, btSize);
pszDrive[btSize] = '\0';
pchStart = pchCurrentPos + 1;
nToReturn |= DRIVE;
}
if((pchCurrentPos = strrchr(pchStart, DIRSEP))==NULL)
{
pszDir[0] = '\0';
}
else
{
btSize = (int)(pchCurrentPos - pchStart) + 1;
strncpy(pszDir,pchStart,btSize);
pszDir[btSize] = '\0';
pchStart = pchCurrentPos + 1;
nToReturn |= DIRECTORY;
}
if(strchr(pchStart,'*') != NULL || strchr(pchStart, '?') != NULL)
{
nToReturn |= WILDCARDS;
}
if((pchCurrentPos = strrchr(pchStart, '.')) == NULL)
{
if(pchStart =='\0')
{
pszExtension[0] = '\0';
pszName[0] = '\0';
}
else
{
pszExtension[0] = '\0';
btSize = strlen(pchStart);
if (btSize > 8) btSize = 0;
strncpy(pszName, pchStart, btSize);
pszName[btSize] = '\0';
nToReturn |= FILENAME;
}
}
else
{
nToReturn |= FILENAME;
nToReturn |= EXTENSION;
btSize = (int)(pchCurrentPos - pchStart);
if(btSize > 8) btSize = 8;
strncpy(pszName, pchStart, btSize);
pszName[btSize] = '\0';
btSize = strlen(pchCurrentPos);
if(btSize > 4) btSize = 4;
strncpy(pszExtension, pchCurrentPos, btSize);
pszExtension[btSize]='\0';
}
return(nToReturn);
}
/* ----------------------------------------------------------------------------
* ODListGetFirstWord() *** PRIVATE FUNCTION ***
*
* Returns the first word in a string containing a series of words separated by
* one or more spaced.
*
* Parameters: pszInStr - String to look in.
*
* pszOutStr - Buffer to store result in. This buffer should be at
* least as long as the pszInStr string.
*
* Return: Pointer to the pszOutStr that was passed in.
*/
static char *ODListGetFirstWord(char *pszInStr, char *pszOutStr)
{
char *pchOut = (char *)pszOutStr;
ASSERT(pszInStr != NULL);
ASSERT(pszOutStr != NULL);
while(*pszInStr && *pszInStr != ' ')
{
*pchOut++ = *pszInStr++;
}
*pchOut = '\0';
return(pszOutStr);
}
/* ----------------------------------------------------------------------------
* ODListGetRemainingWords() *** PRIVATE FUNCTION ***
*
* Obtains the remaining words in a string, after the first word. This function
* is a companion to ODListGetFirstWord(), which obtains just the first word
* in a string of many words.
*
* Parameters: pszInStr - String to look at.
*
* Return: A pointer to the position in a string of the second word.
*/
static char *ODListGetRemainingWords(char *pszInStr)
{
char *pchStartOfRemaining = (char *)pszInStr;
/* Skip over the first word in the string. */
while(*pchStartOfRemaining && *pchStartOfRemaining != ' ')
{
++pchStartOfRemaining;
}
/* Skip over any spaces after the first word. */
while(*pchStartOfRemaining && *pchStartOfRemaining == ' ')
{
++pchStartOfRemaining;
}
/* Return pointer to the rest of the string. */
return((char *)pchStartOfRemaining);
}

View File

@ -0,0 +1,258 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODLog.c
*
* Description: Implements the logfile subsystem.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Oct 13, 1994 6.00 BP New file header format.
* Dec 09, 1994 6.00 BP Standardized coding style.
* Aug 19, 1995 6.00 BP 32-bit portability.
* Nov 16, 1995 6.00 BP Removed oddoor.h, added odcore.h.
* Dec 30, 1995 6.00 BP Added ODCALL for calling convention.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
* Aug 10, 2003 6.23 SH *nix support
*/
#define BUILDING_OPENDOORS
#include <stdio.h>
#include <time.h>
#include "OpenDoor.h"
#include "ODCore.h"
#include "ODGen.h"
#include "ODInEx.h"
#include "ODKrnl.h"
/* Private logfile file handle */
static FILE *logfile_pointer;
/* Private helper functions. */
static BOOL ODLogWriteStandardMsg(INT nLogfileMessage);
static void ODLogClose(INT nReason);
/* ----------------------------------------------------------------------------
* ODLogEnable()
*
* This function is called from od_init() when the user explicitly includes the
* OpenDoors logfile option using the od_control.od_logfile setting.
*
* Parameters: None.
*
* Return: void
*/
ODAPIDEF void ODCALL ODLogEnable(void)
{
/* At this time, this function simply maps to a call to od_log_open(). */
od_log_open();
}
/* ----------------------------------------------------------------------------
* od_log_open()
*
* Called to begin logfile operations. This is when the first message is
* written to the logfile, indicating that the user is entering OpenDoors.
*
* Parameters: None.
*
* Return: TRUE on success, or FALSE on failure.
*/
ODAPIDEF BOOL ODCALL od_log_open()
{
time_t nUnixTime;
struct tm *ptmTimeRecord;
/* Log function entry if running in trace mode. */
TRACE(TRACE_API, "od_log_open()");
/* Initialize OpenDoors if not already done. */
if(!bODInitialized) od_init();
/* Don't open logfile if it has been disabled in config file, etc. */
if(od_control.od_logfile_disable) return(TRUE);
/* Open actual logfile. */
if((logfile_pointer=fopen(od_control.od_logfile_name, "a")) == NULL)
{
return(FALSE);
}
/* Get the current time. */
nUnixTime = time(NULL);
ptmTimeRecord = localtime(&nUnixTime);
/* Print logfile tear line. */
fprintf(logfile_pointer, "\n---------- %s %02d %s %02d, %s\n",
od_control.od_day[ptmTimeRecord->tm_wday],
ptmTimeRecord->tm_mday,
od_control.od_month[ptmTimeRecord->tm_mon],
ptmTimeRecord->tm_year,
od_program_name);
/* Print message of door start up. */
sprintf(szODWorkString, (char *)od_control.od_logfile_messages[11],
od_control.user_name);
od_log_write(szODWorkString);
/* Set internal function hooks to enable calling of logfile features */
/* from elsewhere in OpenDoors. */
pfLogWrite = ODLogWriteStandardMsg;
pfLogClose = ODLogClose;
return(TRUE);
}
/* ----------------------------------------------------------------------------
* ODLogWriteStandardMsg() *** PRIVATE FUNCTION ***
*
* Function called to write a standard message to the logfile.
*
* Parameters: nLogfileMessage - Index of the standard message to write to
* the logfile.
*
* Return: TRUE on success, or FALSE on failure.
*/
static BOOL ODLogWriteStandardMsg(INT nLogfileMessage)
{
if(nLogfileMessage < 0 || nLogfileMessage > 11)
{
return(FALSE);
}
od_log_write((char *)od_control.od_logfile_messages[nLogfileMessage]);
if(nLogfileMessage == 8)
{
sprintf(szODWorkString, od_control.od_logfile_messages[12],
od_control.user_reasonforchat);
szODWorkString[67] = '\0';
od_log_write(szODWorkString);
}
return(TRUE);
}
/* ----------------------------------------------------------------------------
* od_log_write()
*
* Called to write a message to the logfile.
*
* Parameters: pszMessage - Pointer to a string containing the message text.
*
* Return: TRUE on success, or FALSE on failure.
*/
ODAPIDEF BOOL ODCALL od_log_write(char *pszMessage)
{
char *pszFormat;
time_t nUnixTime;
struct tm *ptmTimeRecord;
/* Verify that OpenDoors has been initialized. */
if(!bODInitialized) od_init();
OD_API_ENTRY();
/* Stop if logfile has been disabled in config file, etc. */
if(od_control.od_logfile_disable)
{
OD_API_EXIT();
return(TRUE);
}
/* If logfile has not yet been opened, then open it. */
if(logfile_pointer==NULL)
{
if(!od_log_open())
{
OD_API_EXIT();
return(FALSE);
}
}
/* Get the current system time. */
nUnixTime=time(NULL);
ptmTimeRecord=localtime(&nUnixTime);
/* Determine which logfile format string to use. */
if(ptmTimeRecord->tm_hour<10)
{
pszFormat=(char *)"> %1.1d:%02d:%02d %s\n";
}
else
{
pszFormat=(char *)"> %2.2d:%02d:%02d %s\n";
}
/* Write a line to the logfile. */
fprintf(logfile_pointer, pszFormat, ptmTimeRecord->tm_hour,
ptmTimeRecord->tm_min, ptmTimeRecord->tm_sec, pszMessage);
OD_API_EXIT();
return(TRUE);
}
/* ----------------------------------------------------------------------------
* ODLogClose() *** PRIVATE FUNCTION ***
*
* Writes final entry to the logfile when OpenDoors is exiting.
*
* Parameters: nReason - Specifies the reason why OpenDoors is exiting.
*
* Return: void
*/
static void ODLogClose(INT nReason)
{
/* Stop if logfile has been disabled in the config file, etc. */
if(od_control.od_logfile_disable) return;
/* If logfile has not been opened, then abort. */
if(logfile_pointer==NULL) return;
if(bPreOrExit)
{
od_log_write((char *)od_control.od_logfile_messages[13]);
}
else if(btExitReason<=5 && btExitReason>=1)
{
od_log_write((char *)od_control.od_logfile_messages[btExitReason-1]);
}
else
{
sprintf(szODWorkString,(char *)od_control.od_logfile_messages[5],nReason);
od_log_write(szODWorkString);
}
/* Close the logfile. */
fclose(logfile_pointer);
/* Prevent further use of logfile without first re-opening it. */
pfLogWrite = NULL;
pfLogClose = NULL;
logfile_pointer = NULL;
}

View File

@ -0,0 +1,255 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODMulti.c
*
* Description: Code for multiple personality system, which allows
* a status line / function key personality to be dynamically
* selected at run-time.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Oct 13, 1994 6.00 BP New file header format.
* Dec 09, 1994 6.00 BP Standardized coding style.
* Aug 19, 1995 6.00 BP 32-bit portability.
* Nov 11, 1995 6.00 BP Removed register keyword.
* Nov 14, 1995 6.00 BP Added include of odscrn.h.
* Nov 16, 1995 6.00 BP Removed oddoor.h, added odcore.h.
* Dec 12, 1995 6.00 BP Added entry, exit and kernel macros.
* Dec 30, 1995 6.00 BP Added ODCALL for calling convention.
* Jan 23, 1996 6.00 BP Disable MPS under Win32 version.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
* Sep 01, 1996 6.10 BP Update output area on od_set_per...().
* Aug 10, 2003 6.23 SH *nix support
*/
#define BUILDING_OPENDOORS
#include <string.h>
#include <ctype.h>
#include <stddef.h>
#include <time.h>
#include <stdio.h>
#include "OpenDoor.h"
#include "ODStr.h"
#include "ODCore.h"
#include "ODGen.h"
#include "ODScrn.h"
#include "ODInEx.h"
#include "ODKrnl.h"
/* Maximum number of personalities that may be installed at once. */
#define MAX_PERSONALITIES 12
/* Information on installed personalities. */
typedef struct
{
char szName[33];
INT nStatusTopLine;
INT nStatusBottomLine;
OD_PERSONALITY_PROC *pfPersonalityFunction;
} tPersonalityInfo;
static tPersonalityInfo aPersonalityInfo[MAX_PERSONALITIES]=
{
{"STANDARD", 1, 23, pdef_opendoors},
{"REMOTEACCESS", 1, 23, pdef_ra},
{"WILDCAT", 1, 23, pdef_wildcat},
{"PCBOARD", 1, 23, pdef_pcboard}
};
/* Private variables. */
static INT nPersonalities = 5;
static INT nCurrentPersonality = 255;
/* ----------------------------------------------------------------------------
* ODMPSEnable()
*
* This function is called from within od_init() when the user enables the
* multiple personality system.
*
* Parameters: None.
*
* Return: void
*/
ODAPIDEF void ODCALL ODMPSEnable(void)
{
pfSetPersonality = od_set_personality;
}
/* ----------------------------------------------------------------------------
* od_set_personality()
*
* Sets the current personality to the one that is specified in pszName.
*
* Parameters: pszName - The name of the personality to switch to.
*
* Return: TRUE on success, or FALSE on failure.
*/
ODAPIDEF BOOL ODCALL od_set_personality(const char *pszName)
{
#ifdef OD_TEXTMODE
BYTE btNewPersonality;
char szNameToMatch[33];
tPersonalityInfo *pNewPersonalityInfo;
#endif /* OD_TEXTMODE */
/* Log function entry if running in trace mode */
TRACE(TRACE_API, "od_set_personality()");
/* Initialize OpenDoors if it hasn't already been done. */
if(!bODInitialized) od_init();
OD_API_ENTRY();
#ifdef OD_TEXTMODE
/* Check for valid parameters. */
if(strlen(pszName) == 0)
{
od_control.od_error = ERR_PARAMETER;
OD_API_EXIT();
return(FALSE);
}
/* Build personality name to match. */
strncpy(szNameToMatch, pszName, 32);
szNameToMatch[32] = '\0';
strupr(szNameToMatch);
/* Loop through installed personalities, checking for a match. */
for(btNewPersonality = 0; btNewPersonality < nPersonalities;
++btNewPersonality)
{
/* If the name of this personality matches the one we are looking for. */
if(strcmp(szNameToMatch, aPersonalityInfo[btNewPersonality].szName) == 0)
{
if(btNewPersonality != nCurrentPersonality)
{
/* Remove current status line from the screen .*/
od_set_statusline(8);
/* Initialize the new personality. */
if(nCurrentPersonality != 255)
(*(OD_PERSONALITY_CALLBACK *)pfCurrentPersonality)(22);
od_control.od_page_statusline = -1;
pNewPersonalityInfo =
&aPersonalityInfo[nCurrentPersonality=btNewPersonality];
bRAStatus = TRUE;
(*(OD_PERSONALITY_CALLBACK *)pNewPersonalityInfo
->pfPersonalityFunction)(20);
ODScrnSetBoundary(1, (BYTE)pNewPersonalityInfo->nStatusTopLine, 80,
(BYTE)pNewPersonalityInfo->nStatusBottomLine);
pfCurrentPersonality
= pNewPersonalityInfo->pfPersonalityFunction;
btCurrentStatusLine = 255;
/* Update output area. */
btOutputTop = (BYTE)pNewPersonalityInfo->nStatusTopLine;
btOutputBottom = (BYTE)pNewPersonalityInfo->nStatusBottomLine;
/* Draw the new statusline. */
od_set_statusline(0);
}
OD_API_EXIT();
return(TRUE);
}
}
OD_API_EXIT();
od_control.od_error = ERR_LIMIT;
return(FALSE);
#else /* !OD_TEXTMODE */
/* The multiple personality system is not supported under this platform. */
od_control.od_error = ERR_UNSUPPORTED;
/* Return with failure. */
OD_API_EXIT();
return(FALSE);
#endif /* !OD_TEXTMODE */
}
/* ----------------------------------------------------------------------------
* od_add_personality()
*
* Installs a new personality into the set of available personalities.
*
* Parameters: pszName - Pointer to string containing the name of
* the new personality.
*
* btOutputTop - Index of the top line of the status bar.
*
* btOutputBottom - Index of the bottom line of the status bar.
*
* pfPerFunc - Pointer to the callback function which
* implements this personality.
*
* Return: TRUE on success or FALSE on failure.
*/
ODAPIDEF BOOL ODCALL od_add_personality(const char *pszName, BYTE btOutputTop,
BYTE btOutputBottom, OD_PERSONALITY_PROC *pfPerFunc)
{
/* Log function entry if running in trace mode */
TRACE(TRACE_API, "od_add_personality()");
#ifdef OD_TEXTMODE
/* Check that we haven't exceeded the limit on the total number of */
/* installed personalities. */
if(nPersonalities == MAX_PERSONALITIES)
{
od_control.od_error = ERR_LIMIT;
return(FALSE);
}
/* Store information on this new personality. */
strncpy(aPersonalityInfo[nPersonalities].szName, pszName, 32);
aPersonalityInfo[nPersonalities].szName[32] = '\0';
strupr(aPersonalityInfo[nPersonalities].szName);
aPersonalityInfo[nPersonalities].nStatusTopLine = btOutputTop;
aPersonalityInfo[nPersonalities].nStatusBottomLine = btOutputBottom;
aPersonalityInfo[nPersonalities].pfPersonalityFunction = pfPerFunc;
/* Increment total number of personalities. */
++nPersonalities;
/* Return with success. */
return(TRUE);
#else /* !OD_TEXTMODE */
/* The multiple personality system is not supported under this platform. */
od_control.od_error = ERR_UNSUPPORTED;
/* Return with failure. */
return(FALSE);
#endif /* !OD_TEXTMODE */
}

View File

@ -0,0 +1,104 @@
***************************************************************************
* OpenDoors v6.24 C/C++ Door Development Kit for DOS/Win32/*nix Platforms *
***************************************************************************
$Id: ODOORS62.TXT,v 1.5 2006/12/07 02:06:14 rswindell Exp $
August 10, 2003
*nix (using StdIO only) update to Brian Pirie's OpenDoors Library
August 22, 2002
Door32.sys and Socket update to Brian Pirie's OpenDoors Library
(http://www.pirieworld.ca/opendoors.html)
by Rob Swindell (http://www.synchro.net/)
The current source code is always available via CVS at cvs.synchro.net.
The latest and greatest Win32 ODoors62.dll can always be downloaded here:
http://cvs.synchro.net/cgi-bin/cvsweb.cgi/~checkout~/src/odoors/ODoors62.dll
==============================================================================
This archive includes the source code to the OpenDoors library with
modifications made by me (Rob Swindell, aka Digital Man) to add support for
the Door32.sys drop file format and Win32 TCP/IP socket (Telnet)
communications.
I made my modifications to the 6.1.1 release by Brian Pirie (ods611.zip) and
used Microsoft Visual C++ v6.0. I also eliminated any warnings or errors
detected by this compiler. The linker still warns of duplicate symbol
definition (od_control and od_printf), but I left those duplicate defintions
in the .def file since they may have been necessary for another platform or
compiler that I'm not using.
This version also includes the ODEmu.c:od_send_file_section() modification
by Michael Dillon (gsvalore@arn.net | http://members.darktech.org/gsvalore/).
DOOR32.SYS
----------
The Door32.sys drop file format was created in June of 2000 to support the
new wave of 32-bit Windows and *nix doors. The main feature of this
drop file format is that it includes the currently open Win32 comm handle or
socket descriptor (whichever is appropriate for the current connection).
I didn't add support for the Win32 comm handle in the door32.sys file
(I run a telnet-only BBS and would have no way to test it). I can't
imagine it would be very difficult to add; I'm just not sure how much demand
there would be for such a feature today.
I did however add support for the socket descriptor in the drop file (used for
TCP/IP - Telnet connections) and this is currently the only "standard" drop
file format that is expected to include a socket descriptor (Synchronet's
XTRN.DAT drop file also includes a socket descriptor, but I don't really
consider that format to be a "standard").
The Door32.sys drop file is currently supported by the following known BBS
packages:
Software Home Page Version
-----------+-------------------------------------+--------
Mystic BBS www.mysticbbs.com 1.07
EleBBS www.elebbs.com 0.08?
Synchronet www.synchro.net 3.x
TCP SOCKET I/O
--------------
When using a Door32.sys drop file, the communications type (Local, Serial, or
Telnet) is automatically determined and I added support for (and tested) the
Telnet/socket communication method using Synchronet BBS Software v3.10 for
Win32 and HyperTerminal Private Edition v6.1.
Since the Telnet protocol specifies that an end-of-line sequence (ENTER or
Carriage Return) is a CRLF (ASCII 13, 10), I had to modify od_get_key() to
ignore any line feed (ASCII 10, Ctrl-J) characters. Without this modification,
hitting enter in most Telnet clients would cause a "double return" to be sent
to the door. There may be a more desirable solution to the problem, but this
one seems to work for now.
v6.21 fixes a bug in the socket disconnection ("carrier-loss") detection in
v6.20. I also lowered the input and carrier-detect thread priorities down to
"normal" which makes the doors appear to run faster and also make debugging
continuous loop problems (like the one in v6.20) much easier.
v6.22 changes:
Another bug fixed in socket disconnection ("carrier-loss") detection.
Added support for non-blocking sockets (e.g. EleBBS) - thanks to GSValore.
Added support for the "-SOCKET" command-line option to specify the socket
descriptor on the command-line.
v6.23 changes:
*nix support using stdio
v6.24 chagnes:
Fixed timeing bugs on *nix
Fixed output truncated bug on *nix
Fixed od_get_input() hang on ESC on Win32
Fixed various other bugs.
Added od_key_pending() function.
/* End of ODOORS62.TXT */

View File

@ -0,0 +1,207 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODPCB.c
*
* Description: Implements the PC-Board personality.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Oct 13, 1994 6.00 BP New file header format.
* Dec 09, 1994 6.00 BP Standardized coding style.
* Nov 11, 1995 6.00 BP Removed register keyword.
* Nov 14, 1995 6.00 BP Added include of odscrn.h.
* Nov 14, 1995 6.00 BP 32-bit portability.
* Nov 16, 1995 6.00 BP Removed oddoor.h, added odcore.h.
* Dec 22, 1995 6.00 BP Added od_connect_speed.
* Dec 30, 1995 6.00 BP Added ODCALL for calling convention.
* Jan 03, 1996 6.00 BP Display connect speed with %lu.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
* Aug 10, 2003 6.23 SH *nix support
*/
#define BUILDING_OPENDOORS
#include <string.h>
#include <stdio.h>
#include <time.h>
#include "OpenDoor.h"
#include "ODStr.h"
#include "ODCore.h"
#include "ODGen.h"
#include "ODScrn.h"
#include "ODKrnl.h"
#include "ODUtil.h"
#include "ODStat.h"
/* ----------------------------------------------------------------------------
* pdef_pcboard()
*
* Personality function for the PC-Board like status line / function key
* personality.
*
* Parameters: btOperation - Indicates personality operation to be performed.
*
* Return: void
*/
ODAPIDEF void ODCALL pdef_pcboard(BYTE btOperation)
{
static char szTemp[81];
BYTE btInfoType = od_control.od_info_type;
switch(btOperation)
{
case PEROP_DISPLAY1:
ODScrnSetAttribute(0x70);
ODScrnSetCursorPos(1, 24);
ODScrnDisplayString(" ALT-H=Help ");
ODScrnSetCursorPos(3, 24);
if(od_control.baud != 0)
{
ODScrnPrintf("(%lu) ", od_control.od_connect_speed);
}
else
{
ODScrnDisplayString("(Local) ");
}
sprintf(szTemp, "%s - %s", od_control.user_name,
od_control.user_location);
szTemp[42] = '\0';
strupr(szTemp);
ODScrnDisplayString(szTemp);
ODScrnSetCursorPos(1,25);
if(od_control.user_ansi || od_control.user_avatar
|| od_control.user_rip)
{
ODScrnDisplayChar('G');
}
else
{
ODScrnDisplayChar('A');
}
if(btInfoType == RA1EXITINFO || btInfoType == RA2EXITINFO
|| btInfoType == DOORSYS_WILDCAT)
{
ODScrnPrintf(" (%s)",od_control.user_firstcall);
}
ODScrnSetCursorPos(15, 25);
ODScrnPrintf("Sec(0)=%u ",od_control.user_security);
if(od_control.od_extended_info || btInfoType == DOORSYS_GAP
|| btInfoType == CHAINTXT || btInfoType == DOORSYS_WILDCAT)
{
ODScrnPrintf("Times On=%u ", od_control.user_numcalls);
}
if(od_control.od_extended_info || btInfoType == SFDOORSDAT
|| btInfoType == DOORSYS_GAP || btInfoType == DOORSYS_WILDCAT)
{
ODScrnPrintf("Up:Dn=%lu:%lu", od_control.user_uploads,
od_control.user_downloads);
}
ODScrnSetCursorPos(70, 25);
ODScrnPrintf("%4d", od_control.user_timelimit);
od_control.key_status[0] = 0x0000;
od_control.key_status[1] = 0x2300;
break;
case PEROP_DISPLAY2:
ODScrnSetAttribute(0x70);
ODScrnSetCursorPos(1, 24);
ODScrnDisplayString(" Alt-> N=Next X=DOS F1/F2=Time 2=LkOut 5=SHELL 8=HngUp 10=Chat ");
od_control.key_status[0] = 0x2300;
od_control.key_status[1] = 0x0000;
break;
case PEROP_UPDATE1:
ODScrnSetAttribute(0x70);
ODScrnSetCursorPos(70, 25);
ODScrnPrintf("%4d", od_control.user_timelimit);
break;
case PEROP_INITIALIZE:
od_control.key_hangup = 0x4200;
od_control.key_drop2bbs = 0x2d00;
od_control.key_dosshell = 0x3f00;
od_control.key_chat = 0x4400;
od_control.key_sysopnext = 0x3100;
od_control.key_lockout = 0x3c00;
od_control.key_status[0] = 0x0000;
od_control.key_status[1] = 0x2300;
od_control.key_status[2] = 0x0000;
od_control.key_status[3] = 0x0000;
od_control.key_status[4] = 0x0000;
od_control.key_status[5] = 0x0000;
od_control.key_status[6] = 0x0000;
od_control.key_status[7] = 0x0000;
od_control.key_status[8] = 0x0000;
od_control.key_keyboardoff = 0x2500;
od_control.key_moretime = 0x0000;
od_control.key_lesstime = 0x0000;
ODStatAddKey(0x6900);
ODStatAddKey(0x6800);
od_control.od_page_statusline = 0;
break;
case PEROP_CUSTOMKEY:
switch(od_control.od_last_hot)
{
/* Key to add five minutes. */
case 0x6900:
if(od_control.user_timelimit <= 1435 &&
od_control.user_timelimit >= 5)
{
od_control.user_timelimit += 5;
bForceStatusUpdate = TRUE;
CALL_KERNEL_IF_NEEDED();
}
else if(od_control.user_timelimit < 5)
{
od_control.user_timelimit++;
bForceStatusUpdate = TRUE;
CALL_KERNEL_IF_NEEDED();
}
break;
/* Subtract five minutes from the user's remaining time. */
case 0x6800:
if(od_control.user_timelimit > 5)
{
od_control.user_timelimit -= 5;
bForceStatusUpdate = TRUE;
CALL_KERNEL_IF_NEEDED();
}
else if(od_control.user_timelimit > 1)
{
--od_control.user_timelimit;
bForceStatusUpdate = TRUE;
CALL_KERNEL_IF_NEEDED();
}
break;
default:
return;
}
od_control.od_last_hot = 0;
break;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,203 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODPlat.h
*
* Description: Contains platform-related definitions and prototypes for
* those function's whose implementation is platform-specific
* (functions implemented in odplat.c). Non-platform specific
* utility functions are defined in odutil.h and implemented in
* odutil.c.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Oct 14, 1994 6.00 BP Created.
* Nov 01, 1994 6.00 BP Added ODDir...() functions.
* Dec 31, 1994 6.00 BP Added timing, file delete functions.
* Dec 31, 1994, 6.00 BP Added ODMultitasker and ODPlatInit()
* Nov 14, 1995 6.00 BP 32-bit portability.
* Nov 17, 1995 6.00 BP Added multithreading functions.
* Dec 13, 1995 6.00 BP Added ODThreadWaitForExit().
* Dec 13, 1995 6.00 BP Added ODThreadGetCurrent().
* Jan 23, 1996 6.00 BP Added ODProcessExit().
* Jan 30, 1996 6.00 BP Add semaphore timeout.
* Jan 31, 1996 6.00 BP Add ODTimerLeft(), rm ODTimerSleep().
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
*/
#ifndef _INC_ODPLAT
#define _INC_ODPLAT
#include <time.h>
#include "ODTypes.h"
#include "ODGen.h"
#ifdef ODPLAT_NIX
#include <sys/time.h>
#endif
#ifdef ODPLAT_WIN32
#include "windows.h"
#endif /* ODPLAT_WIN32 */
/* odplat.c initialization function prototype */
void ODPlatInit(void);
/* ========================================================================= */
/* Millisecond timer functions. */
/* ========================================================================= */
/* Timer data type. */
typedef struct
{
#ifdef ODPLAT_DOS
clock_t Start;
clock_t Duration;
#elif defined(ODPLAT_NIX)
time_t Start;
tODMilliSec Duration;
#else /* !ODPLAT_DOS */
tODMilliSec Start;
tODMilliSec Duration;
#endif /* !ODPLAT_DOS */
} tODTimer;
/* Timer function prototypes. */
void ODTimerStart(tODTimer *pTimer, tODMilliSec Duration);
BOOL ODTimerElapsed(tODTimer *pTimer);
void ODTimerWaitForElapse(tODTimer *pTimer);
tODMilliSec ODTimerLeft(tODTimer *pTimer);
/* ========================================================================= */
/* Multithreading and synchronization support. */
/* ========================================================================= */
#ifdef OD_MULTITHREADED
/* Thread handle data type. */
#ifdef ODPLAT_WIN32
typedef HANDLE tODThreadHandle;
#endif /* ODPLAT_WIN32 */
/* Thread priority enumeration. */
typedef enum
{
OD_PRIORITY_LOWEST,
OD_PRIORITY_BELOW_NORMAL,
OD_PRIORITY_NORMAL,
OD_PRIORITY_ABOVE_NORMAL,
OD_PRIORITY_HIGHEST
} tODThreadPriority;
/* Thread start proceedure type. */
#define OD_THREAD_FUNC WINAPI
#ifdef ODPLAT_WIN32
typedef DWORD (OD_THREAD_FUNC ptODThreadProc)(void *);
#endif /* ODPLAT_WIN32 */
/* Thread creation, temination and suspension. */
tODResult ODThreadCreate(tODThreadHandle *phThread,
ptODThreadProc *pfThreadProc, void *pThreadParam);
void ODThreadExit();
tODResult ODThreadTerminate(tODThreadHandle hThread);
tODResult ODThreadSuspend(tODThreadHandle hThread);
tODResult ODThreadResume(tODThreadHandle hThread);
tODResult ODThreadSetPriority(tODThreadHandle hThread,
tODThreadPriority ThreadPriority);
void ODThreadWaitForExit(tODThreadHandle hThread);
tODThreadHandle ODThreadGetCurrent(void);
/* Semaphore handle data type. */
#ifdef ODPLAT_WIN32
typedef HANDLE tODSemaphoreHandle;
#endif /* ODPLAT_WIN32 */
/* Semaphore manipulation functions. */
tODResult ODSemaphoreAlloc(tODSemaphoreHandle *phSemaphore, INT nInitialCount,
INT nMaximumCount);
void ODSemaphoreFree(tODSemaphoreHandle hSemaphore);
void ODSemaphoreUp(tODSemaphoreHandle hSemaphore, INT nIncrementBy);
tODResult ODSemaphoreDown(tODSemaphoreHandle hSemaphore, tODMilliSec Timeout);
#endif /* OD_MULTITHREADED */
void ODProcessExit(INT nExitCode);
/* ========================================================================= */
/* DOS multitasker information. */
/* ========================================================================= */
#ifdef ODPLAT_DOS
typedef enum
{
kMultitaskerNone,
kMultitaskerDV,
kMultitaskerWin,
kMultitaskerOS2
} tODMultitasker;
extern tODMultitasker ODMultitasker;
#endif /* ODPLAT_DOS */
/* ========================================================================= */
/* Directory Access. */
/* ========================================================================= */
/* Open directory handle type. */
typedef tODHandle tODDirHandle;
/* Directory entry structure. */
#define DIR_FILENAME_SIZE 1024
#define DIR_ATTRIB_NORMAL 0x00
#define DIR_ATTRIB_RDONLY 0x01
#define DIR_ATTRIB_HIDDEN 0x02
#define DIR_ATTRIB_SYSTEM 0x04
#define DIR_ATTRIB_LABEL 0x08
#define DIR_ATTRIB_DIREC 0x10
#define DIR_ATTRIB_ARCH 0x20
typedef struct
{
char szFileName[DIR_FILENAME_SIZE];
WORD wAttributes;
time_t LastWriteTime;
DWORD dwFileSize;
} tODDirEntry;
/* Directory function prototypes. */
tODResult ODDirOpen(CONST char *pszPath, WORD wAttributes, tODDirHandle *phDir);
tODResult ODDirRead(tODDirHandle hDir, tODDirEntry *pDirEntry);
void ODDirClose(tODDirHandle hDir);
void ODDirChangeCurrent(char *pszPath);
void ODDirGetCurrent(char *pszPath, INT nMaxPathChars);
/* ========================================================================= */
/* Miscellaneous Functions. */
/* ========================================================================= */
tODResult ODFileDelete(CONST char *pszPath);
BOOL ODFileAccessMode(char *pszFilename, int nAccessMode);
#endif /* !_INC_ODPLAT */

View File

@ -0,0 +1,716 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODPopUp.c
*
* Description: Implements od_popup_menu(), for displaying a menu in
* a window, allowing the user to make a selection using
* "hot keys" or by using arrow keys.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Oct 13, 1994 6.00 BP New file header format.
* Dec 09, 1994 6.00 BP Standardized coding style.
* Jan 15, 1995 6.00 BP Free menu structure on menu destroy.
* Feb 02, 1995 6.00 BP Added od_yield() call in for(;;) loop.
* Aug 19, 1995 6.00 BP 32-bit portability.
* Nov 11, 1995 6.00 BP Removed register keyword.
* Nov 14, 1995 6.00 BP Change valid range of nLevel to 0-10.
* Nov 16, 1995 6.00 BP Removed oddoor.h, added odcore.h.
* Nov 17, 1995 6.00 BP Use new input queue mechanism.
* Dec 12, 1995 6.00 BP Added entry, exit and kernel macros.
* Dec 23, 1995 6.00 BP Restore original color on exit.
* Dec 30, 1995 6.00 BP Added ODCALL for calling convention.
* Jan 04, 1996 6.00 BP Use od_get_input().
* Jan 12, 1996 6.00 BP Claim exclusive use of arrow keys.
* Jan 30, 1996 6.00 BP Replaced od_yield() with od_sleep().
* Jan 31, 1996 6.00 BP Added timeout for od_get_input().
* Jan 31, 1996 6.00 BP Add ODPopupCheckForKey() wait param.
* Jan 31, 1996 6.00 BP Ignore left & right if !MENU_PULLDOWN.
* Feb 13, 1996 6.00 BP Added od_get_input() flags parameter.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
* Aug 10, 2003 6.23 SH *nix support
*/
#define BUILDING_OPENDOORS
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include "OpenDoor.h"
#include "ODCore.h"
#include "ODGen.h"
#include "ODPlat.h"
#include "ODKrnl.h"
#include "ODStat.h"
/* Configurable od_popup_menu() parameters. */
/* Maximum menu level. */
#define MENU_LEVELS 11
/* Maximum number of items in a menu. */
#define MAX_MENU_ITEMS 21
/* Maximum width of any menu item. */
#define MAX_ITEM_WIDTH 76
/* Other manifest constants. */
#define NO_COMMAND -10
/* Local data types. */
/* Information on an individual menu item. */
typedef struct
{
char szItemText[MAX_ITEM_WIDTH + 1];
BYTE btKeyIndex;
} tMenuItem;
/* Information on a popup menu level. */
typedef struct
{
tMenuItem *paMenuItems;
BYTE btNumMenuItems;
BYTE btWidth;
BYTE btRight;
BYTE btBottom;
BYTE btCursor;
BYTE btLeft;
BYTE btTop;
WORD wFlags;
void *pWindow;
} tMenuLevelInfo;
/* Private variables. */
/* Array of information on each menu level. */
tMenuLevelInfo MenuLevelInfo[MENU_LEVELS];
/* Current menu settings. */
static BYTE btCorrectItem;
static INT nCommand;
static WORD wCurrentFlags;
static BYTE btCurrentNumMenuItems;
static INT nCurrentLevel;
/* Private helper functions used by od_popup_menu(). */
static void ODPopupCheckForKey(BOOL bWaitForInput);
static void ODPopupDisplayMenuItem(BYTE btLeft, BYTE btTop,
tMenuItem *paMenuItems, BYTE btItemIndex, BOOL bHighlighted, BYTE btWidth,
BOOL bPositionCursor);
/* ----------------------------------------------------------------------------
* od_popup_menu()
*
* Displays a popup menu on the local and remote screens.
*
* Parameters: pszTitle - Text to show as the window title of the popup menu.
* If no title is desired, this parameter should be set
* to either "" or NULL.
*
* pszText - String which contains the menu definition. In the
* menu definition string, individual menu items are
* separated by a pipe ('|') character, and hotkeys are
* proceeded by a carat ('^') character.
*
* nLeft - The 1-based column number of the upper right corner
* of the menu.
*
* nTop - The 1-based row number of the upper right corner of
* the menu.
*
* nLevel - Menu level, which must be a value between 0 and
* MENU_LEVELS.
*
* uFlags - One or more flags, combined by the bitwise or (|)
* operator.
*
* Return: POPUP_ERROR on error, POPUP_ESCAPE if user pressed the Escape
* key, POPUP_LEFT if the user choose to move to the next menu to
* the left, POPUP_RIGHT if the user choose to move to the next
* menu to the right, or a postive value if the user choose an item
* from the menu. In this case, the return value is the 1-based
* index of the selected menu item.
*/
ODAPIDEF INT ODCALL od_popup_menu(char *pszTitle, char *pszText, INT nLeft,
INT nTop, INT nLevel, WORD uFlags)
{
tMenuItem *paMenuItems = NULL;
BYTE btCount;
BYTE btWidth;
BYTE btRight;
BYTE btBottom;
BYTE btCursor;
BYTE btLeft;
BYTE btTop;
void *pWindow;
BYTE btBetweenSize;
BYTE btTitleSize;
BYTE btRemaining;
BYTE btLineCount;
INT16 nOriginalAttrib;
/* Log function entry if running in trace mode. */
TRACE(TRACE_API, "od_popup_menu()");
/* Initialize OpenDoors, if not already done. */
if(!bODInitialized) od_init();
OD_API_ENTRY();
/* Setup od_box_chars appropriately. */
if(od_control.od_box_chars[BOX_BOTTOM] == 0)
{
od_control.od_box_chars[BOX_BOTTOM] = od_control.od_box_chars[BOX_TOP];
}
if(od_control.od_box_chars[BOX_RIGHT] == 0)
{
od_control.od_box_chars[BOX_RIGHT] = od_control.od_box_chars[BOX_LEFT];
}
/* Store initial display color. */
nOriginalAttrib = od_control.od_cur_attrib;
/* check level bounds */
if(nLevel < 0 || nLevel > MENU_LEVELS)
{
od_control.od_error = ERR_LIMIT;
OD_API_EXIT();
return(POPUP_ERROR);
}
/* normalize level */
nCurrentLevel = nLevel;
if(MenuLevelInfo[nLevel].pWindow == NULL)
{
btLeft = nLeft;
btTop = nTop;
wCurrentFlags = uFlags;
if(pszText == NULL)
{
od_control.od_error = ERR_PARAMETER;
OD_API_EXIT();
return(POPUP_ERROR);
}
if(paMenuItems == NULL)
{
if((paMenuItems = malloc(sizeof(tMenuItem) * MAX_MENU_ITEMS)) == NULL)
{
od_control.od_error = ERR_PARAMETER;
OD_API_EXIT();
return(POPUP_ERROR);
}
}
MenuLevelInfo[nLevel].paMenuItems = paMenuItems;
btCurrentNumMenuItems = 0;
btWidth = 0;
btCount = 0;
nCommand = NO_COMMAND;
paMenuItems[0].btKeyIndex = 0;
while(*pszText && btCurrentNumMenuItems < MAX_MENU_ITEMS)
{
switch(*pszText)
{
case '|':
paMenuItems[btCurrentNumMenuItems++].szItemText[btCount]
= '\0';
if(btCount > btWidth) btWidth = btCount;
btCount = 0;
paMenuItems[btCurrentNumMenuItems].btKeyIndex = 0;
break;
case '^':
if(btCount < MAX_ITEM_WIDTH)
{
paMenuItems[btCurrentNumMenuItems].btKeyIndex = btCount;
}
break;
default:
if(btCount < MAX_ITEM_WIDTH)
{
paMenuItems[btCurrentNumMenuItems].szItemText[btCount++] =
*pszText;
}
}
++pszText;
}
/* If we were in the middle of a menu item when we encountered the end */
/* of the string, then it should form an additional menu entry. This */
/* handles the case of a menu string to no terminating | for the last */
/* entry. */
if(btCount != 0)
{
/* null-terminate current menu entry string */
paMenuItems[btCurrentNumMenuItems++].szItemText[btCount] = '\0';
/* If this is the widest entry, update he menu width appropriately */
if(btCount > btWidth) btWidth = btCount;
}
/* If the menu description string does not contain any menu items */
if(btCurrentNumMenuItems == 0)
{
/* Return with parameter error */
od_control.od_error = ERR_PARAMETER;
OD_API_EXIT();
return(POPUP_ERROR);
}
/* Adjust menu width to allow title to fit, if possible */
/* If a title string was passed, and that string is wider than widest */
/* menu entry ... */
if(pszTitle != NULL && strlen(pszTitle) + 2 > btWidth)
{
/* Then width of menu window should be large enough to allow up to */
/* the first 76 characters of the title to fit. */
btWidth = strlen(pszTitle) + 2 > MAX_ITEM_WIDTH
? MAX_ITEM_WIDTH : strlen(pszTitle) + 2;
}
/* Based on number and size of menu items, and width of title, */
/* determine the bottom, right and inside width of the menu. */
btBottom = btTop + btCurrentNumMenuItems + 1;
btRight = btLeft + btWidth + 3;
btBetweenSize = (btRight - btLeft) - 1;
/* If neither ANSI nor AVATAR mode is available, return with an error */
if(!(od_control.user_ansi || od_control.user_avatar))
{
od_control.od_error = ERR_NOGRAPHICS;
OD_API_EXIT();
return(POPUP_ERROR);
}
/* If menu would "fall off" edge of screen, return with an error */
if(btLeft < 1 || btTop < 1 || btRight > OD_SCREEN_WIDTH
|| btBottom > OD_SCREEN_HEIGHT || btRight - btLeft < 2
|| btBottom - btTop < 2)
{
od_control.od_error = ERR_PARAMETER;
OD_API_EXIT();
return(POPUP_ERROR);
}
/* Allocate space to store window information. If unable to allocate */
/* enough space, return with an error. */
if((pWindow = malloc((btRight - btLeft + 1) * 2
+ (btBottom - btTop + 1) * 160)) == NULL)
{
od_control.od_error = ERR_MEMORY;
OD_API_EXIT();
return(POPUP_ERROR);
}
/* Store contents of screen where memu will be drawn in the temporary */
/* buffer. */
if(!od_gettext(btLeft, btTop, btRight, btBottom, pWindow))
{
free(pWindow);
pWindow = NULL;
/* Note that od_error code has been set in od_gettext(). */
OD_API_EXIT();
return(POPUP_ERROR);
}
/* Determine number of characters of title to be displayed */
if(pszTitle == NULL)
{
btTitleSize = 0;
}
else
{
if((btTitleSize = strlen(pszTitle)) > (btBetweenSize - 4))
{
btTitleSize = btBetweenSize - 4;
}
}
od_set_cursor(btTop,btLeft);
od_set_attrib(od_control.od_menu_border_col);
od_putch(od_control.od_box_chars[BOX_UPPERLEFT]);
if(btTitleSize == 0)
{
od_repeat(od_control.od_box_chars[BOX_TOP], btBetweenSize);
}
else
{
od_repeat(od_control.od_box_chars[BOX_TOP],
btRemaining = ((btBetweenSize - btTitleSize - 2) / 2));
od_set_attrib(od_control.od_menu_title_col);
od_putch(' ');
od_disp(pszTitle,btTitleSize, TRUE);
od_putch(' ');
od_set_attrib(od_control.od_menu_border_col);
od_repeat(od_control.od_box_chars[BOX_TOP],
(BYTE)(btBetweenSize - btRemaining - btTitleSize - 2));
}
od_putch(od_control.od_box_chars[BOX_UPPERRIGHT]);
btLineCount = btTop + 1;
btCorrectItem = 0;
ODPopupCheckForKey(FALSE);
btCursor = btCorrectItem;
for(btCount = 0; btCount < btCurrentNumMenuItems
&& btLineCount < btBottom; ++btCount)
{
ODPopupCheckForKey(FALSE);
if(nCommand != NO_COMMAND && !(wCurrentFlags & MENU_KEEP))
{
goto exit_now;
}
od_set_cursor(btLineCount,btLeft);
od_putch(od_control.od_box_chars[BOX_LEFT]);
od_set_attrib(od_control.od_menu_text_col);
if(btCount == btCursor)
{
ODPopupDisplayMenuItem(btLeft, btTop, paMenuItems, btCount,
TRUE, btWidth, FALSE);
}
else
{
ODPopupDisplayMenuItem(btLeft, btTop, paMenuItems, btCount,
FALSE, btWidth, FALSE);
}
od_set_attrib(od_control.od_menu_border_col);
od_putch(od_control.od_box_chars[BOX_RIGHT]);
++btLineCount;
}
od_set_cursor(btBottom, btLeft);
od_putch(od_control.od_box_chars[BOX_LOWERLEFT]);
od_repeat(od_control.od_box_chars[BOX_BOTTOM], btBetweenSize);
od_putch(od_control.od_box_chars[BOX_LOWERRIGHT]);
od_set_cursor(btTop + 1, btLeft + 1);
}
else
{
paMenuItems = MenuLevelInfo[nLevel].paMenuItems;
btCurrentNumMenuItems = MenuLevelInfo[nLevel].btNumMenuItems;
btWidth = MenuLevelInfo[nLevel].btWidth;
btRight = MenuLevelInfo[nLevel].btRight;
btBottom = MenuLevelInfo[nLevel].btBottom;
btLeft = MenuLevelInfo[nLevel].btLeft;
btTop = MenuLevelInfo[nLevel].btTop;
wCurrentFlags = MenuLevelInfo[nLevel].wFlags;
pWindow = MenuLevelInfo[nLevel].pWindow;
btCorrectItem = btCursor = MenuLevelInfo[nLevel].btCursor;
nCommand = NO_COMMAND;
if(uFlags & MENU_DESTROY)
{
nCommand = POPUP_ESCAPE;
goto destroy;
}
/* Otherwise, position flashing hardware cursor appropriately */
od_set_cursor(btTop + btCursor + 1, btLeft + 1);
}
/* Claim exclusive use of arrow keys. */
ODStatStartArrowUse();
for(;;)
{
ODPopupCheckForKey(TRUE);
if(btCorrectItem != btCursor)
{
ODPopupDisplayMenuItem(btLeft, btTop, paMenuItems, btCursor,
FALSE, btWidth, TRUE);
btCursor = btCorrectItem;
ODWaitDrain(25);
ODPopupCheckForKey(FALSE);
ODPopupDisplayMenuItem(btLeft, btTop, paMenuItems, btCursor,
TRUE, btWidth, TRUE);
}
if(nCommand != NO_COMMAND)
{
goto exit_now;
}
}
exit_now:
if((!(wCurrentFlags & MENU_KEEP)) || nCommand <= 0)
{
destroy:
od_puttext(btLeft, btTop, btRight, btBottom, pWindow);
free(pWindow);
MenuLevelInfo[nLevel].pWindow = NULL;
if(paMenuItems != NULL)
{
free(paMenuItems);
MenuLevelInfo[nLevel].paMenuItems = NULL;
}
}
else if(wCurrentFlags & MENU_KEEP)
{
MenuLevelInfo[nLevel].paMenuItems = paMenuItems;
MenuLevelInfo[nLevel].btNumMenuItems = btCurrentNumMenuItems;
MenuLevelInfo[nLevel].btWidth = btWidth;
MenuLevelInfo[nLevel].btRight = btRight;
MenuLevelInfo[nLevel].btBottom = btBottom;
MenuLevelInfo[nLevel].btCursor = btCursor;
MenuLevelInfo[nLevel].btLeft = btLeft;
MenuLevelInfo[nLevel].btTop = btTop;
MenuLevelInfo[nLevel].wFlags = wCurrentFlags;
MenuLevelInfo[nLevel].pWindow = pWindow;
}
/* Restore original display color. */
od_set_attrib(nOriginalAttrib);
/* Release exclusive use of arrow keys. */
ODStatEndArrowUse();
OD_API_EXIT();
return(nCommand);
}
/* ----------------------------------------------------------------------------
* ODPopupCheckForKey() *** PRIVATE FUNCTION ***
*
* Checks whether or not the user has pressed any key. If one or more keys
* have been pressed, then these keystrokes are processed. This function
* returns when no more keys are waiting in the inbound buffer, or when a key
* has been pressed that requires immediate action (such as the [ENTER] key).
*
* Parameters: bWaitForInput - Indicates whether this function should return
* immediately if no input is waiting (FALSE), or
* wait for the next input even before returning
* (TRUE).
*
* Return: void
*/
static void ODPopupCheckForKey(BOOL bWaitForInput)
{
BYTE btCount;
tODInputEvent InputEvent;
BOOL bDoneAnythingYet = FALSE;
/* Loop, processing keys. If a command has been selected, stop looping */
/* immediately. If there are no more keys waiting, stop looping */
while(nCommand == NO_COMMAND)
{
CALL_KERNEL_IF_NEEDED();
if(!od_get_input(&InputEvent, bWaitForInput && !bDoneAnythingYet
? OD_NO_TIMEOUT : 0, GETIN_NORMAL))
{
/* Return right away if no input event is waiting. */
return;
}
bDoneAnythingYet = TRUE;
if(InputEvent.EventType == EVENT_EXTENDED_KEY)
{
switch(InputEvent.chKeyPress)
{
case OD_KEY_UP:
up_arrow:
if(btCorrectItem == 0)
{
btCorrectItem = btCurrentNumMenuItems - 1;
}
else
{
--btCorrectItem;
}
break;
case OD_KEY_DOWN:
down_arrow:
if(++btCorrectItem >= btCurrentNumMenuItems)
{
btCorrectItem = 0;
}
break;
case OD_KEY_LEFT:
left_arrow:
if(wCurrentFlags & MENU_PULLDOWN)
{
nCommand = POPUP_LEFT;
return;
}
break;
case OD_KEY_RIGHT:
right_arrow:
if(wCurrentFlags & MENU_PULLDOWN)
{
nCommand = POPUP_RIGHT;
return;
}
break;
}
}
else if(InputEvent.EventType == EVENT_CHARACTER)
{
if(InputEvent.chKeyPress == '\n' || InputEvent.chKeyPress == '\r')
{
nCommand = btCorrectItem + 1;
return;
}
else if(InputEvent.chKeyPress == 27)
{
if(wCurrentFlags & MENU_ALLOW_CANCEL)
{
nCommand = POPUP_ESCAPE;
return;
}
}
else
{
/* Check whether key is a menu "hot key" */
for(btCount = 0; btCount < btCurrentNumMenuItems; ++btCount)
{
if(toupper(MenuLevelInfo[nCurrentLevel].paMenuItems[btCount]
.szItemText[MenuLevelInfo[nCurrentLevel].paMenuItems[btCount]
.btKeyIndex]) == toupper(InputEvent.chKeyPress))
{
btCorrectItem = btCount;
nCommand = btCorrectItem + 1;
return;
}
}
/* At this point, we know that key was not one of the "hot keys" */
/* Check for 4, 6, 8 and 2 keys as arrow keys. */
if(InputEvent.chKeyPress == '4')
{
goto left_arrow;
}
else if(InputEvent.chKeyPress == '6')
{
goto right_arrow;
}
else if(InputEvent.chKeyPress == '8')
{
goto up_arrow;
}
else if(InputEvent.chKeyPress == '2')
{
goto down_arrow;
}
}
}
}
}
/* ----------------------------------------------------------------------------
* ODPopupDisplayMenuItem() *** PRIVATE FUNCTION ***
*
* Displays an individual menu item.
*
* Parameters: btLeft - Column number where the menu item will be
* displayed.
*
* btTop - Row number where the menu item will be
* displayed.
*
* paMenuItems - Pointer to array of available menu items.
*
* btItemIndex - Index into paMenuItems of the menu item that
* is to be displayed.
*
* bHighlighted - TRUE if the items is to be displayed as
* highlighted, FALSE if it is to be displayed as
* non-highlighted.
*
* btWidth - Width of the menu item, in characters.
*
* bPositionCursor - TRUE if the cursor needs to be positioned
* prior to drawing the menu item, FALSE if the
* cursor is already in the required position.
*
* Return: void
*/
static void ODPopupDisplayMenuItem(BYTE btLeft, BYTE btTop,
tMenuItem *paMenuItems, BYTE btItemIndex, BOOL bHighlighted, BYTE btWidth,
BOOL bPositionCursor)
{
BYTE btCount;
char *pchItemText;
BYTE btKeyPosition;
BYTE btTextColor;
BYTE btKeyColor;
/* Check that parameters are reasonable when operating in debug mode. */
ASSERT(paMenuItems != NULL);
ASSERT(btItemIndex < MAX_MENU_ITEMS);
ASSERT(btWidth < OD_SCREEN_WIDTH);
++btLeft;
++btTop;
btTextColor = bHighlighted ? od_control.od_menu_highlight_col
: od_control.od_menu_text_col;
btKeyColor = bHighlighted ? od_control.od_menu_highkey_col
: od_control.od_menu_key_col;
pchItemText = (char *)(paMenuItems[btItemIndex].szItemText);
btKeyPosition = paMenuItems[btItemIndex].btKeyIndex;
if(bPositionCursor) od_set_cursor(btTop + btItemIndex, btLeft);
od_set_attrib(btTextColor);
od_putch(' ');
for(btCount = 0; btCount < btWidth && *pchItemText; ++btCount)
{
if(btCount == btKeyPosition)
{
od_set_attrib(btKeyColor);
od_putch(*pchItemText++);
od_set_attrib(btTextColor);
}
else
{
od_putch(*pchItemText++);
}
}
od_repeat(' ', (BYTE)((btWidth - btCount) + 1));
if(bPositionCursor) od_set_cursor(btTop + btItemIndex, btLeft);
}

View File

@ -0,0 +1,197 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODPrntf.c
*
* Description: Implements the od_printf() function.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Oct 13, 1994 6.00 BP New file header format.
* Dec 09, 1994 6.00 BP Standardized coding style.
* Nov 11, 1995 6.00 BP Removed register keyword.
* Nov 14, 1995 6.00 BP 32-bit portability.
* Nov 16, 1995 6.00 BP Removed oddoor.h, added odcore.h.
* Dec 12, 1995 6.00 BP Added entry, exit and kernel macros.
* Dec 30, 1995 6.00 BP Added ODCALL for calling convention.
* Jan 03, 1996 6.00 BP Use ODVCALL instead of ODCALL.
* Jan 04, 1996 6.00 BP Add missing OD_API_EXIT() at end.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
* Aug 10, 2003 6.23 SH *nix support
*/
#define BUILDING_OPENDOORS
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include "OpenDoor.h"
#include "ODCore.h"
#include "ODGen.h"
#include "ODKrnl.h"
/* Size of od_printf() working buffer. Adjust this upwards if you are */
/* encountering difficulties when calling od_printf() with long strings. */
#define WORK_BUFFER_SIZE 512
/* ----------------------------------------------------------------------------
* od_printf()
*
* The OpenDoors equivalent of the C printf() function, this function performs
* formatted string output to both the local and remote screens.
*
* Parameters: pszFormat - Format string, in the same format as the printf()
* format string.
*
* The semantics of any further parameters are dicated by the
* contents of the format string.
*
* Return: void
*/
ODAPIDEF void ODVCALL od_printf(const char *pszFormat,...)
{
va_list pArgumentList;
static char *pszWorkBuffer = NULL;
char *pchCurrent;
char *pchStart;
BOOL bNotFound;
INT nCharCount;
/* Log function entry if running in trace mode. */
TRACE(TRACE_API, "od_printf()");
/* Initialize OpenDoors if it hasn't already been done. */
if(!bODInitialized) od_init();
OD_API_ENTRY();
/* Allocate work buffer if none has been allocated yet. */
if(pszWorkBuffer == NULL &&
(pszWorkBuffer = malloc(WORK_BUFFER_SIZE)) == NULL)
{
/* If we are unable to allocate a buffer, return with a memory error. */
od_control.od_error = ERR_MEMORY;
OD_API_EXIT();
return;
}
/* Copy the arguments after the format string. */
va_start(pArgumentList, pszFormat);
/* Perform a string printf to the working buffer. */
vsprintf(pszWorkBuffer, pszFormat, pArgumentList);
va_end(pArgumentList);
/* If no color characters are defined, then just display the entire */
/* buffer in one shot. */
if(!od_control.od_color_char && !od_control.od_color_delimiter)
goto quick_print;
chColorCheck = od_control.od_color_delimiter;
bNotFound = TRUE;
pchCurrent = (char *)pszWorkBuffer;
pchStart = (char *)pszWorkBuffer;
nCharCount = 0;
while(*pchCurrent)
{
if(*pchCurrent == od_control.od_color_delimiter)
{
bNotFound = FALSE;
if(nCharCount != 0)
{
od_disp(pchStart, nCharCount, TRUE);
}
if(!*(++pchCurrent))
{
chColorCheck = 0;
OD_API_EXIT();
return;
}
od_set_attrib(od_color_config(pchCurrent));
if(!*(pchCurrent = (char *)pchColorEndPos))
{
chColorCheck = 0;
OD_API_EXIT();
return;
}
if(!*(++pchCurrent))
{
OD_API_EXIT();
return;
}
pchStart = (char *)pchCurrent;
nCharCount = 0;
}
else if(*pchCurrent == od_control.od_color_char)
{
bNotFound = FALSE;
if(nCharCount != 0)
{
od_disp(pchStart, nCharCount, TRUE);
}
if(!*(++pchCurrent))
{
OD_API_EXIT();
return;
}
od_set_attrib(*pchCurrent);
if(!*(++pchCurrent))
{
OD_API_EXIT();
return;
}
pchStart = (char *)pchCurrent;
nCharCount = 0;
}
else
{
++nCharCount;
++pchCurrent;
}
}
chColorCheck = 0;
if(bNotFound)
{
quick_print:
/* Display the entire string in one shot. */
od_disp_str(pszWorkBuffer);
}
else if(nCharCount != 0)
{
/* If there are remaining characters in the string, then display them. */
od_disp(pchStart, nCharCount, TRUE);
}
OD_API_EXIT();
}

View File

@ -0,0 +1,619 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODRA.c
*
* Description: Implements the RemoteAccess personality.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Oct 13, 1994 6.00 BP New file header format.
* Oct 19, 1994 6.00 BP Use new od_page constants.
* Dec 09, 1994 6.00 BP Standardized coding style.
* Jul 18, 1995 6.00 BP Fix ODStatGetUserAge() bug.
* Nov 11, 1995 6.00 BP Removed register keyword.
* Nov 14, 1995 6.00 BP Added include of odscrn.h.
* Nov 14, 1995 6.00 BP 32-bit portability.
* Nov 16, 1995 6.00 BP Removed oddoor.h, added odcore.h.
* Dec 22, 1995 6.00 BP Added od_connect_speed.
* Dec 24, 1995 6.00 BP Fixed black square at pos 25x80.
* Dec 30, 1995 6.00 BP Added ODCALL for calling convention.
* Jan 03, 1996 6.00 BP Display connect speed with %lu.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
* Aug 10, 2003 6.23 SH *nix support
*/
#define BUILDING_OPENDOORS
#include <string.h>
#include <ctype.h>
#include <stddef.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include "OpenDoor.h"
#include "ODCore.h"
#include "ODGen.h"
#include "ODScrn.h"
#include "ODStat.h"
#include "ODInEx.h"
/* Private variables, local to this module. */
static BOOL bRAPersHasBeenOn = FALSE;
/* Private function prototypes. */
static void ODRADisplayPageInfo(void);
static void ODRADisplayDate(char *pszDateString);
static void ODRADisplayFlags(BYTE btFlags);
static void ODRADisplayTime(void);
/* ----------------------------------------------------------------------------
* pdef_ra()
*
* Personality function for the RemoteAccess-like status line / function key
* personality.
*
* Parameters: btOperation - Indicates personality operation to be performed.
*
* Return: void
*/
ODAPIDEF void ODCALL pdef_ra(BYTE btOperation)
{
BYTE btInfoType = od_control.od_info_type;
switch(btOperation)
{
case PEROP_DISPLAY1:
ODScrnSetAttribute(0x70);
ODScrnSetCursorPos(1, 24);
ODScrnDisplayString(" (Node ");
ODScrnSetCursorPos(1, 24);
ODScrnPrintf("%s of %s at %lu BPS", od_control.user_name,
od_control.user_location, od_control.od_connect_speed);
if(!od_control.od_user_keyboard_on)
{
ODScrnSetCursorPos(49, 24);
ODScrnSetAttribute(0x99);
ODScrnDisplayString("(Keyboard)");
ODScrnSetAttribute(0x70);
bRAPersHasBeenOn = TRUE;
}
ODRADisplayPageInfo();
ODScrnSetCursorPos(76, 24);
if(od_control.od_node < 1000)
{
ODScrnPrintf("%u)", od_control.od_node);
}
else
{
ODScrnDisplayString("?)");
}
ODScrnSetCursorPos(1, 25);
ODScrnDisplayString("Security: Time: (F9)=Help ");
ODScrnPutText(80, 25, 80, 25, abtGreyBlock);
ODScrnSetCursorPos(11, 25);
ODScrnPrintf("%u", od_control.user_security);
ODScrnSetCursorPos(24, 25);
ODScrnPrintf("%d mins ", od_control.user_timelimit);
if(od_control.user_ansi)
{
ODScrnSetCursorPos(42, 25);
ODScrnDisplayString("(ANSI)");
}
if(od_control.user_avatar)
{
ODScrnSetCursorPos(48, 25);
ODScrnDisplayString("(AVT)");
}
if(od_control.sysop_next)
{
ODScrnSetCursorPos(53, 25);
ODScrnDisplayString("(SN) ");
}
if(od_control.user_wantchat)
{
ODScrnSetCursorPos(57, 25);
ODScrnSetAttribute(0x99);
ODScrnDisplayString("(Wants Chat)");
ODScrnSetAttribute(0x70);
}
break;
case PEROP_DISPLAY2:
ODScrnSetAttribute(0x70);
ODScrnPutText(80, 25, 80, 25, abtGreyBlock);
ODScrnSetCursorPos(1, 24);
ODScrnDisplayString("Voice#: Last Call : First Call: ");
ODScrnSetCursorPos(1, 25);
ODScrnDisplayString("Data #: Times Called: Age: Birthdate: ");
if(od_control.od_extended_info || btInfoType == SFDOORSDAT
|| btInfoType == DOORSYS_GAP || btInfoType == DOORSYS_WILDCAT)
{
ODScrnSetCursorPos(8, 24);
ODScrnPrintf("%13.13s", od_control.user_homephone);
}
if(od_control.od_extended_info || btInfoType == DOORSYS_GAP
|| btInfoType == DOORSYS_WILDCAT)
{
ODScrnSetCursorPos(8, 25);
ODScrnPrintf("%13.13s", od_control.user_dataphone);
}
if(od_control.od_extended_info || btInfoType == DOORSYS_GAP
|| btInfoType == CHAINTXT || btInfoType == DOORSYS_WILDCAT)
{
ODScrnSetCursorPos(37, 24);
ODRADisplayDate(od_control.user_lastdate);
}
if(od_control.od_extended_info || btInfoType == DOORSYS_GAP
|| btInfoType == DOORSYS_WILDCAT)
{
ODScrnSetCursorPos(37, 25);
ODScrnPrintf("%lu", od_control.user_numcalls);
}
if(btInfoType == RA1EXITINFO || btInfoType == RA2EXITINFO
|| btInfoType == DOORSYS_WILDCAT)
{
char szUserAge[7];
ODScrnSetCursorPos(53, 25);
ODStatGetUserAge(szUserAge);
ODScrnDisplayString(szUserAge);
ODScrnSetCursorPos(71, 24);
ODRADisplayDate(od_control.user_firstcall);
ODScrnSetCursorPos(71, 25);
ODRADisplayDate(od_control.user_birthday);
}
break;
case PEROP_DISPLAY3:
ODScrnSetAttribute(0x70);
ODScrnPutText(80, 25, 80, 25, abtGreyBlock);
ODScrnSetCursorPos(1, 24);
if(od_control.od_extended_info || btInfoType == SFDOORSDAT
|| btInfoType == DOORSYS_GAP || btInfoType == DOORSYS_WILDCAT)
{
ODScrnDisplayString("Uploads: Downloads: Tagged: 0k (0) ");
if(btInfoType == DOORSYS_GAP)
{
ODScrnSetCursorPos(10, 24);
ODScrnPrintf("%lu", od_control.user_uploads);
ODScrnSetCursorPos(36, 24);
ODScrnPrintf("%lu", od_control.user_downloads);
}
else
{
ODScrnSetCursorPos(10, 24);
ODScrnPrintf("%luk (%lu)", od_control.user_upk,
od_control.user_uploads);
ODScrnSetCursorPos(36,24);
ODScrnPrintf("%luk (%lu)", od_control.user_downk,
od_control.user_downloads);
}
}
else
{
ODScrnDisplayString(" ");
}
ODScrnSetCursorPos(1, 25);
if(od_control.od_extended_info)
{
ODScrnDisplayString("Flags: (A):-------- (B):-------- (C):-------- (D):-------- ");
ODScrnSetCursorPos(12, 25);
ODRADisplayFlags(od_control.user_flags[0]);
ODScrnSetCursorPos(26, 25);
ODRADisplayFlags(od_control.user_flags[1]);
ODScrnSetCursorPos(40, 25);
ODRADisplayFlags(od_control.user_flags[2]);
ODScrnSetCursorPos(54, 25);
ODRADisplayFlags(od_control.user_flags[3]);
}
else
{
ODScrnDisplayString(" ");
}
break;
case PEROP_DISPLAY4:
ODScrnSetAttribute(0x70);
ODScrnPutText(80, 25, 80, 25, abtGreyBlock);
ODScrnSetCursorPos(1, 24);
ODScrnDisplayString(" (Time ) ");
if(od_control.od_extended_info)
{
ODScrnSetCursorPos(1, 24);
ODScrnPrintf("Last Caller: %s Total System Calls: %lu",
od_control.system_last_caller, od_control.system_calls);
}
ODRADisplayTime();
ODScrnSetCursorPos(1, 25);
if(od_control.od_extended_info || btInfoType == DOORSYS_WILDCAT)
{
ODScrnDisplayString("(Printer OFF) (Local Screen ON ) Next Event ");
ODScrnSetCursorPos(57, 25);
if(od_control.event_status == ES_ENABLED
|| btInfoType == DOORSYS_WILDCAT)
{
ODScrnPrintf("(%s, errorlevel %u)",od_control.event_starttime,od_control.event_errorlevel);
}
else
{
ODScrnDisplayString("none, errorlevel 0");
}
}
else
{
ODScrnDisplayString(" ");
}
break;
case PEROP_DISPLAY5:
ODScrnSetAttribute(0x70);
ODScrnPutText(80, 25, 80, 25, abtGreyBlock);
ODScrnSetCursorPos(1, 24);
if(od_control.od_extended_info || btInfoType == DOORSYS_WILDCAT)
{
ODScrnDisplayString("Msgs posted : Highread : Group 1 ");
ODScrnSetCursorPos(18,24);
ODScrnPrintf("%u",od_control.user_messages);
ODScrnSetCursorPos(39,24);
ODScrnPrintf("%u",od_control.user_lastread);
if(btInfoType == RA1EXITINFO || btInfoType == RA2EXITINFO)
{
ODScrnSetCursorPos(76, 24);
ODScrnPrintf("%u", od_control.user_group);
}
}
else
{
ODScrnDisplayString(" ");
}
ODScrnSetCursorPos(1, 25);
if(od_control.od_extended_info || btInfoType == CHAINTXT
|| btInfoType == DOORSYS_WILDCAT)
{
ODScrnDisplayString("Credit : Handle : ");
if(btInfoType == EXITINFO || btInfoType == RA1EXITINFO
|| btInfoType == RA2EXITINFO)
{
ODScrnSetCursorPos(18, 25);
ODScrnPrintf("%u.00", (unsigned int)od_control.user_net_credit);
}
if(btInfoType == CHAINTXT || btInfoType == RA1EXITINFO
|| btInfoType == RA2EXITINFO || btInfoType == DOORSYS_WILDCAT)
{
ODScrnSetCursorPos(39, 25);
ODScrnDisplayString(od_control.user_handle);
}
}
else
{
ODScrnDisplayString(" ");
}
break;
case PEROP_DISPLAY6:
ODScrnSetAttribute(0x70);
ODScrnSetCursorPos(1, 24);
ODScrnDisplayString(" ");
ODScrnSetCursorPos(1, 25);
ODScrnDisplayString(" ");
ODScrnPutText(80, 25, 80, 25, abtGreyBlock);
if(btInfoType == RA1EXITINFO || btInfoType == RA2EXITINFO
|| btInfoType == DOORSYS_WILDCAT)
{
ODScrnSetCursorPos(1, 24);
ODScrnDisplayString(od_control.user_comment);
}
if(od_control.user_wantchat
&& strlen(od_control.user_reasonforchat) !=0 )
{
ODScrnSetCursorPos(1, 25);
strcpy(szStatusText, od_control.user_reasonforchat);
szStatusText[69 - strlen(od_control.user_name)] = '\0';
ODScrnPrintf("Chat (%s): %s", od_control.user_name, szStatusText);
}
break;
case PEROP_DISPLAY7:
ODScrnSetAttribute(0x70);
ODScrnSetCursorPos(1, 24);
ODScrnDisplayString(" ");
ODScrnSetCursorPos(1, 25);
ODScrnDisplayString(" ");
ODScrnPutText(80, 25, 80, 25, abtGreyBlock);
break;
case PEROP_DISPLAY8:
ODScrnSetAttribute(0x70);
ODScrnPutText(80, 25, 80, 25, abtGreyBlock);
ODScrnSetCursorPos(1, 24);
ODScrnDisplayString("ALT: (C)hat (H)angup (J)Shell (L)ockOut (K)eyboard (N)extOn (D)rop To BBS ");
ODScrnDisplayString(" -Inc Time -Dec Time (F1)-(F7)=Extra Stats");
break;
case PEROP_UPDATE1:
ODScrnSetAttribute(0x70);
ODScrnSetCursorPos(24, 25);
ODScrnPrintf("%d mins ", od_control.user_timelimit);
ODScrnSetCursorPos(42, 25);
if(od_control.user_ansi)
{
ODScrnDisplayString("(ANSI)");
}
else
{
ODScrnDisplayString(" ");
}
if(od_control.user_avatar)
{
ODScrnDisplayString("(AVT)");
}
else
{
ODScrnDisplayString(" ");
}
if(od_control.sysop_next)
{
ODScrnDisplayString("(SN)");
}
else
{
ODScrnDisplayString(" ");
}
if(od_control.user_wantchat)
{
ODScrnSetAttribute(0x99);
ODScrnDisplayString("(Wants Chat)");
ODScrnSetAttribute(0x70);
}
else
{
ODScrnDisplayString(" ");
}
ODRADisplayPageInfo();
if(od_control.od_user_keyboard_on && bRAPersHasBeenOn)
{
ODScrnSetCursorPos(49, 24);
ODScrnDisplayString(" ");
}
if(!od_control.od_user_keyboard_on)
{
bRAPersHasBeenOn = TRUE;
ODScrnSetCursorPos(49, 24);
ODScrnSetAttribute(0x99);
ODScrnDisplayString("(Keyboard)");
ODScrnSetAttribute(0x70);
}
break;
case PEROP_UPDATE4:
ODScrnSetAttribute(0x70);
ODRADisplayTime();
break;
case PEROP_INITIALIZE:
bRAStatus = TRUE;
od_control.key_hangup = 0x2300;
od_control.key_drop2bbs = 0x2000;
od_control.key_dosshell = 0x2400;
od_control.key_chat = 0x2e00;
od_control.key_sysopnext = 0x3100;
od_control.key_lockout = 0x2600;
od_control.key_status[0] = 0x3b00;
od_control.key_status[1] = 0x3c00;
od_control.key_status[2] = 0x3d00;
od_control.key_status[3] = 0x3e00;
od_control.key_status[4] = 0x3f00;
od_control.key_status[5] = 0x4000;
od_control.key_status[6] = 0x4100;
od_control.key_status[7] = 0x4300;
od_control.key_status[8] = 0x4400;
od_control.key_keyboardoff = 0x2500;
od_control.key_moretime = 0x4800;
od_control.key_lesstime = 0x5000;
od_control.od_page_statusline = 5;
}
}
/* ----------------------------------------------------------------------------
* ODRADisplayPageInfo() *** PRIVATE FUNCTION ***
*
* Displays the current sysop page information on the RemoteAccess status line,
* at the appropriate position, and in the appropriate color.
*
* Parameters: none
*
* Return: void
*/
static void ODRADisplayPageInfo(void)
{
time_t nUnixTime;
struct tm *TimeBlock;
BOOL bFailed = FALSE;
INT nMinute;
ODScrnSetCursorPos(60, 24);
switch(od_control.od_okaytopage)
{
case PAGE_ENABLE:
ODScrnSetAttribute(0x19);
ODScrnDisplayString("(PAGE ON) ");
ODScrnSetAttribute(0x70);
break;
case PAGE_DISABLE:
ODScrnSetAttribute(0x19);
ODScrnDisplayString("(PAGE OFF)");
ODScrnSetAttribute(0x70);
break;
case PAGE_USE_HOURS:
nUnixTime = time(NULL);
TimeBlock = localtime(&nUnixTime);
nMinute = (60 * TimeBlock->tm_hour) + TimeBlock->tm_min;
if(od_control.od_pagestartmin < od_control.od_pageendmin)
{
if(nMinute < od_control.od_pagestartmin
|| nMinute >= od_control.od_pageendmin)
{
bFailed = TRUE;
}
}
else
{
if(nMinute < od_control.od_pagestartmin
&& nMinute >= od_control.od_pageendmin)
{
bFailed=TRUE;
}
}
if(bFailed)
{
ODScrnDisplayString("(PAGE OFF)");
}
else
{
ODScrnDisplayString("(PAGE ON) ");
}
}
}
/* ----------------------------------------------------------------------------
* ODRADisplayTime() *** PRIVATE FUNCTION ***
*
* Displays the current time on the RemoteAccess status line, at the
* appropriate position. The time is displayed in the current color.
*
* Parameters: none
*
* Return: void
*/
static void ODRADisplayTime(void)
{
time_t nUnixTime;
struct tm *TimeBlock;
nUnixTime = time(NULL);
TimeBlock = localtime(&nUnixTime);
ODScrnSetCursorPos(74, 24);
ODScrnPrintf("%02.2d:%02.2d", TimeBlock->tm_hour, TimeBlock->tm_min);
}
/* ----------------------------------------------------------------------------
* ODRADisplayDate() *** PRIVATE FUNCTION ***
*
* Displays a date stored in a string on the RemoteAccess status line, if
* the string represents a valid date. The date is displayed at the current
* cursor location, in the current color.
*
* Parameters: pszDateString - Pointer to a string containing the date to
* display.
*
* Return: void
*/
static void ODRADisplayDate(char *pszDateString)
{
INT nMonth;
INT nTemp;
ASSERT(pszDateString != NULL);
if(strlen(pszDateString) != 8) return;
nMonth = atoi(pszDateString) - 1;
if(nMonth < 0 || nMonth > 11) return;
nTemp=atoi((char *)pszDateString + 3);
if(nTemp < 1 || nTemp > 31) return;
if(pszDateString[6] < '0' || pszDateString[6] > '9'
|| pszDateString[7] < '0' || pszDateString[7] > '9')
{
return;
}
ODScrnDisplayChar(pszDateString[3]);
ODScrnDisplayChar(pszDateString[4]);
ODScrnDisplayChar('-');
ODScrnDisplayString(od_control.od_month[nMonth]);
ODScrnDisplayChar('-');
ODScrnDisplayChar(pszDateString[6]);
ODScrnDisplayChar(pszDateString[7]);
}
/* ----------------------------------------------------------------------------
* ODRADisplayFlags() *** PRIVATE FUNCTION ***
*
* Displays sysop-defined user flags on the status line. The flags are
* displayed at the current cursor location, in the current color.
*
* Parameters: btFlags - Byte of eight flags to display.
*
* Return: void
*/
static void ODRADisplayFlags(BYTE btFlags)
{
BYTE btMask = 0x01;
INT nFlag;
for(nFlag = 0; nFlag < 8; ++nFlag)
{
if(btFlags & btMask)
{
ODScrnDisplayChar('X');
}
else
{
ODScrnDisplayChar('-');
}
btMask <<= 1;
}
}

Binary file not shown.

View File

@ -0,0 +1,78 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODRes.h
*
* Description: OpenDoors resource-related definitions. This file is only
* applicable when building the Win32 version of OpenDoors.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Dec 02, 1995 6.00 BP Created.
* Jan 20, 1996 6.00 BP Added login dialog box.
* Jan 21, 1996 6.00 BP Added message dialog box.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Feb 23, 1996 6.00 BP Remove unused IDs.
* Mar 03, 1996 6.10 BP Begin version 6.10.
* Mar 14, 1996 6.10 BP Added configuration menu option.
*/
/* Resource IDs. */
#define IDR_FRAME_MENU 200
#define IDD_ABOUT 201
#define IDI_OPENDOORS 202
#define IDB_TOOLBAR 203
#define IDR_FRAME 204
#define IDD_LOGIN 205
#define IDI_MESSAGE_INFO 206
#define IDD_MESSAGE 207
/* Dialog box control IDs. (The same values can safely be used by other */
/* dialog boxes.) */
/* Help dialog box. */
#define IDC_DOORNAME 1000
#define IDC_COPYRIGHT 1001
#define IDC_VERSION 1002
/* Login dialog box. */
#define IDC_USER_NAME 1000
/* Message dialog box. */
#define IDC_MESSAGE_ICON 1000
#define IDC_MESSAGE_TEXT1 1001
/* Command IDs. */
#define ID_DOOR_CHATMODE 50000
#define ID_DOOR_USERKEYBOARDOFF 50001
#define ID_DOOR_SYSOPNEXT 50002
#define ID_DOOR_HANGUP 50003
#define ID_VIEW_STATUSBAR 50006
#define ID_USER_ADDONEMINUTE 50007
#define ID_USER_ADDFIVEMINUTES 50008
#define ID_USER_SUBTRACTONEMINUTE 50009
#define ID_USER_SUBTRACTFIVEMINUTES 50010
#define ID_USER_INACTIVITYTIMER 50011
#define ID_HELP_ABOUT 50012
#define ID_HELP_CONTENTS 50013
#define ID_VIEW_TOOL_BAR 50014
#define ID_DOOR_EXIT 50015
#define ID_DOOR_LOCKOUT 50016
#define ID_VIEW_STAT_BAR 50017
#define ID_DOOR_CONFIG 50018

View File

@ -0,0 +1,197 @@
/* OpenDoors 6.10
* (C) Copyright 1991 - 1997 by Brian Pirie. All Rights Reserved.
*
*
* File: ODRes.rc
*
* Description: OpenDoors resource script. Contains defintions for OpenDoors
* menus, dialog boxes, icons, bitmaps, accelerator table and
* string resources. This file is only applicable when building
* the Win32 version of OpenDoors.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Dec 02, 1995 6.00 BP Created.
* Jan 01, 1996 6.00 BP Changed copyright to 1996 in About Box
* Jan 20, 1996 6.00 BP Added login dialog box.
* Jan 21, 1996 6.00 BP Added message dialog box.
* Jan 21, 1996 6.00 BP Renamed opendoor.ico to odapp.ico.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
* Mar 14, 1996 6.10 BP Added configuration menu option.
*/
#include "windows.h"
#include "ODRes.h"
/* ========================================================================= */
/* The OpenDoors frame window menu. */
/* ========================================================================= */
IDR_FRAME_MENU MENU DISCARDABLE
BEGIN
POPUP "&Door"
BEGIN
MENUITEM "C&onfigure..." ID_DOOR_CONFIG
MENUITEM "&Chat Mode\tAlt+C", ID_DOOR_CHATMODE
MENUITEM SEPARATOR
MENUITEM "User &Keyboard Off\tAlt+K", ID_DOOR_USERKEYBOARDOFF
MENUITEM "Sysop &Next\tAlt+N", ID_DOOR_SYSOPNEXT
MENUITEM SEPARATOR
MENUITEM "&Hangup\tAlt+H", ID_DOOR_HANGUP
MENUITEM "&Lockout\tAlt+L", ID_DOOR_LOCKOUT
MENUITEM SEPARATOR
MENUITEM "E&xit To BBS\tAlt+X", ID_DOOR_EXIT
END
POPUP "&View"
BEGIN
MENUITEM "&Toolbar", ID_VIEW_TOOL_BAR, CHECKED
MENUITEM "Status Bar", ID_VIEW_STAT_BAR, CHECKED
END
POPUP "&User"
BEGIN
MENUITEM "Add &One Minute\tShift+Up Arrow", ID_USER_ADDONEMINUTE
MENUITEM "Add &Five Minutes\tAlt+Up Arrow", ID_USER_ADDFIVEMINUTES
MENUITEM SEPARATOR
MENUITEM "&Subtract One Minute\tShift+Down Arrow",
ID_USER_SUBTRACTONEMINUTE
MENUITEM "S&ubtract Five Minutes\tAlt+Down Arrow",
ID_USER_SUBTRACTFIVEMINUTES
MENUITEM SEPARATOR
MENUITEM "&Inactivity Timer", ID_USER_INACTIVITYTIMER
, CHECKED
END
POPUP "&Help"
BEGIN
MENUITEM "&Contents\tF1" ID_HELP_CONTENTS
MENUITEM "&About...", ID_HELP_ABOUT
END
END
/* ========================================================================= */
/* Dialog Boxes. */
/* ========================================================================= */
IDD_ABOUT DIALOG DISCARDABLE 0, 0, 217, 89
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "About"
FONT 8, "MS Sans Serif"
BEGIN
ICON IDI_OPENDOORS,-1,6,7,18,20
LTEXT "BBS Door Program",IDC_DOORNAME,32,5,120,8
LTEXT "",IDC_VERSION,32,14,123,7
LTEXT "",IDC_COPYRIGHT,32,23,119,8
LTEXT "Written using:",-1,31,48,69,8
LTEXT "OpenDoors 6.24, Win32 Edition",-1,31,57,127,8
LTEXT "Copyright \251 1991-1997 by Brian Pirie.",-1,31,
66,139,8,SS_NOPREFIX
LTEXT "All Rights Reserved.",-1,31,75,90,8
DEFPUSHBUTTON "OK",IDOK,161,6,50,14
END
IDD_LOGIN DIALOG DISCARDABLE 0, 0, 194, 80
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "OpenDoors"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "This program has been started in local",-1,6,6,128,8
LTEXT "mode, independently of a BBS system.",-1,6,14,128,8
LTEXT "When operating in this mode, you may",-1,6,22,128,8
LTEXT "specify what name you should be",-1,6,30,128,8
LTEXT "known to the program by.",-1,6,38,128,8
LTEXT "Your &name:",-1,6,52,42,8
EDITTEXT IDC_USER_NAME,6,61,121,12,ES_AUTOHSCROLL
DEFPUSHBUTTON "OK",IDOK,138,6,50,14
PUSHBUTTON "Cancel",IDCANCEL,138,23,50,14
END
IDD_MESSAGE DIALOG DISCARDABLE 0, 0, 186, 31
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "OpenDoors"
FONT 8, "MS Sans Serif"
BEGIN
ICON IDI_MESSAGE_INFO,IDC_MESSAGE_ICON,6,6,18,20
LTEXT "",IDC_MESSAGE_TEXT1,32,10,149,8
END
/* ========================================================================= */
/* Icons. */
/* ========================================================================= */
IDI_OPENDOORS ICON DISCARDABLE "odapp.ico"
IDI_MESSAGE_INFO ICON DISCARDABLE "odinfo.ico"
/* ========================================================================= */
/* Bitmaps. */
/* ========================================================================= */
IDB_TOOLBAR BITMAP DISCARDABLE "toolbar.bmp"
/* ========================================================================= */
/* Accelerator Table. */
/* ========================================================================= */
/* Dumb dumb dumb.
IDR_FRAME ACCELERATORS DISCARDABLE
BEGIN
"C", ID_DOOR_CHATMODE, VIRTKEY, CONTROL, NOINVERT
"H", ID_DOOR_HANGUP, VIRTKEY, CONTROL, NOINVERT
"K", ID_DOOR_USERKEYBOARDOFF, VIRTKEY, CONTROL, NOINVERT
"L", ID_DOOR_LOCKOUT, VIRTKEY, CONTROL, NOINVERT
"N", ID_DOOR_SYSOPNEXT, VIRTKEY, CONTROL, NOINVERT
"X", ID_DOOR_EXIT, VIRTKEY, CONTROL, NOINVERT
VK_DOWN, ID_USER_SUBTRACTFIVEMINUTES, VIRTKEY, CONTROL, NOINVERT
VK_DOWN, ID_USER_SUBTRACTONEMINUTE, VIRTKEY, SHIFT, NOINVERT
VK_F1, ID_HELP_CONTENTS, VIRTKEY, NOINVERT
VK_UP, ID_USER_ADDFIVEMINUTES, VIRTKEY, CONTROL, NOINVERT
VK_UP, ID_USER_ADDONEMINUTE, VIRTKEY, SHIFT, NOINVERT
END
*/
IDR_FRAME ACCELERATORS DISCARDABLE
BEGIN
"C", ID_DOOR_CHATMODE, VIRTKEY, ALT, NOINVERT
"H", ID_DOOR_HANGUP, VIRTKEY, ALT, NOINVERT
"K", ID_DOOR_USERKEYBOARDOFF, VIRTKEY, ALT, NOINVERT
"L", ID_DOOR_LOCKOUT, VIRTKEY, ALT, NOINVERT
"N", ID_DOOR_SYSOPNEXT, VIRTKEY, ALT, NOINVERT
"X", ID_DOOR_EXIT, VIRTKEY, ALT, NOINVERT
VK_DOWN, ID_USER_SUBTRACTFIVEMINUTES, VIRTKEY, ALT, NOINVERT
VK_DOWN, ID_USER_SUBTRACTONEMINUTE, VIRTKEY, SHIFT, NOINVERT
VK_F1, ID_HELP_CONTENTS, VIRTKEY, NOINVERT
VK_UP, ID_USER_ADDFIVEMINUTES, VIRTKEY, ALT, NOINVERT
VK_UP, ID_USER_ADDONEMINUTE, VIRTKEY, SHIFT, NOINVERT
END
/* ========================================================================= */
/* String Resources. */
/* ========================================================================= */
STRINGTABLE DISCARDABLE
BEGIN
ID_DOOR_CHATMODE "Enters or exits chat mode, allowing you to communicate with the remote user."
ID_DOOR_USERKEYBOARDOFF "Causes any keys or commands from the remote user to be ignored."
ID_DOOR_SYSOPNEXT "Reserves the system for the sysop after this user logs off (if supported by BBS)."
ID_DOOR_HANGUP "Hangs up the modem and exits the door."
ID_USER_ADDONEMINUTE "Increases the user's time remaining by one minute."
ID_USER_ADDFIVEMINUTES "Increases the user's time remaining by five minutes."
ID_USER_SUBTRACTONEMINUTE
"Decreases the user's time remaining by one minute."
ID_USER_SUBTRACTFIVEMINUTES
"Decreases the user's time remaining by five minutes."
ID_USER_INACTIVITYTIMER "Enables the timer that will log off the user after a long period of no activity."
ID_HELP_ABOUT "Displays program information and copyright."
ID_VIEW_TOOL_BAR "Shows or hides the toolbar."
END
STRINGTABLE DISCARDABLE
BEGIN
ID_DOOR_EXIT "Exits the door without hanging up."
ID_DOOR_LOCKOUT "Hangs up the modem, denying any further access to the user (if supported by BBS)."
ID_VIEW_STAT_BAR "Shows or hides the status bar."
END

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,110 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODScrn.h
*
* Description: Functions used to access the local display screen buffer, which
* keeps a copy of the text that is displayed on the remote
* terminal. The local display screen buffer also displays the
* OpenDoors status lines on some platforms. In addition to
* maintaining the current screen buffer, the odscrn.c module
* also contains the code to display this buffer on the screen.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Nov 14, 1995 6.00 BP Created.
* Jan 21, 1996 6.00 BP Added ODScrnShowMessage() and related.
* Jan 27, 1996 6.00 BP Made text-mode window f'ns static.
* Jan 31, 1996 6.00 BP Made them non-static again.
* Jan 31, 1996 6.00 BP Added ODScrnLocalInput().
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
* Mar 19, 1996 6.10 BP MSVC15 source-level compatibility.
*/
#ifndef _INC_ODSCRN
#define _INC_ODSCRN
#include "ODTypes.h"
#include "ODPlat.h"
/* Text information structure. */
typedef struct
{
unsigned char winleft;
unsigned char wintop;
unsigned char winright;
unsigned char winbottom;
unsigned char attribute;
unsigned char curx;
unsigned char cury;
} tODScrnTextInfo;
/* Screen buffer initialization and shutdown functions. */
tODResult ODScrnInitialize(void);
void ODScrnShutdown(void);
/* Basic text output functions. */
void ODScrnDisplayChar(unsigned char chToOutput);
void ODScrnDisplayBuffer(const char *pBuffer, INT nCharsToDisplay);
void ODScrnDisplayString(const char *pszString);
INT ODScrnPrintf(char *pszFormat, ...);
/* Functions for manipulating rectangular areas of the screen buffer. */
BOOL ODScrnGetText(BYTE btLeft, BYTE btTop, BYTE btRight, BYTE btBottom,
void *pbtBuffer);
BOOL ODScrnPutText(BYTE btLeft, BYTE btTop, BYTE btRight, BYTE btBottom,
void *pbtBuffer);
BOOL ODScrnCopyText(BYTE btLeft, BYTE btTop, BYTE btRight, BYTE btBottom,
BYTE btDestColumn, BYTE btDestRow);
/* Functions for clearing portions of the screen buffer. */
void ODScrnClear(void);
void ODScrnClearToEndOfLine(void);
/* Functions for setting or obtaining current display settings. */
void ODScrnSetBoundary(BYTE btLeft, BYTE btTop, BYTE btRight, BYTE btBottom);
void ODScrnSetCursorPos(BYTE btColumn, BYTE btRow);
void ODScrnSetAttribute(BYTE btAttribute);
void ODScrnEnableScrolling(BOOL bEnable);
void ODScrnEnableCaret(BOOL bEnable);
void ODScrnGetTextInfo(tODScrnTextInfo *pTextInfo);
/* Functions for displaying OpenDoors message window. */
void *ODScrnShowMessage(char *pszText, int nFlags);
void ODScrnRemoveMessage(void *pMessageInfo);
/* Additional local output functions for text mode based versions. */
#ifdef OD_TEXTMODE
void *ODScrnCreateWindow(BYTE btLeft, BYTE btTop, BYTE btRight,
BYTE btBottom, BYTE btAttribute, char *pszTitle, BYTE btTitleAttribute);
void ODScrnDestroyWindow(void *pWindow);
void ODScrnLocalInput(BYTE btLeft, BYTE btRow, char *pszString,
BYTE btMaxChars);
#endif /* OD_TEXTMODE */
/* Functions for local screen window under Win32 version. */
#ifdef ODPLAT_WIN32
tODResult ODScrnStartWindow(HANDLE hInstance, tODThreadHandle *phScreenThread,
HWND hwndFrame);
void ODScrnSetFocusToWindow(void);
void ODScrnAdjustWindows(void);
#endif /* ODPLAT_WIN32 */
#endif /* _INC_ODSCRN */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,226 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODStand.c
*
* Description: Implements the OpenDoors standard (default) personality.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Oct 13, 1994 6.00 BP New file header format.
* Dec 09, 1994 6.00 BP Standardized coding style.
* Nov 13, 1995 6.00 BP 32-bit portability.
* Nov 14, 1995 6.00 BP Added include of odscrn.h.
* Nov 16, 1995 6.00 BP Removed oddoor.h, added odcore.h.
* Dec 22, 1995 6.00 BP Added od_connect_speed.
* Dec 24, 1995 6.00 BP Fixed black square at pos 25x80.
* Dec 30, 1995 6.00 BP Added ODCALL for calling convention.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
* Aug 10, 2003 6.23 SH *nix support
*/
#define BUILDING_OPENDOORS
#include <stdio.h>
#include "OpenDoor.h"
#include "ODCore.h"
#include "ODGen.h"
#include "ODScrn.h"
#include "ODInEx.h"
/* ----------------------------------------------------------------------------
* pdef_opendoors()
*
* Personality function for the OpenDoors standard status line / function key
* personality.
*
* Parameters: btOperation - Indicates personality operation to be performed.
*
* Return: void
*/
ODAPIDEF void ODCALL pdef_opendoors(BYTE btOperation)
{
switch(btOperation)
{
case PEROP_DISPLAY1:
/* Display standard status line. */
ODScrnSetAttribute(0x70);
ODScrnSetCursorPos(1, 24);
ODScrnDisplayString(od_control.od_status_line[0]);
ODScrnSetCursorPos(1, 24);
ODScrnPrintf(od_control.od_status_line[1], od_control.user_name,
od_control.user_location, od_control.od_connect_speed);
ODScrnSetCursorPos(77, 24);
if(od_control.od_node < 1000)
{
ODScrnPrintf("%d]", od_control.od_node);
}
else
{
ODScrnDisplayString("?]");
}
ODScrnSetCursorPos(1,25);
ODScrnDisplayString(od_control.od_status_line[2]);
ODScrnPutText(80, 25, 80, 25, abtGreyBlock);
ODScrnSetCursorPos(11,25);
ODScrnPrintf("%u",od_control.user_security);
ODScrnSetCursorPos(24,25);
ODScrnPrintf(od_control.od_time_left,od_control.user_timelimit);
if(od_control.user_ansi)
{
ODScrnSetCursorPos(40,25);
ODScrnDisplayString("[ANSI]");
}
if(od_control.user_avatar)
{
ODScrnSetCursorPos(47,25);
ODScrnDisplayString("[AVT]");
}
if(od_control.sysop_next)
{
ODScrnSetCursorPos(35,25);
ODScrnDisplayString(od_control.od_sysop_next);
}
if(od_control.user_wantchat)
{
ODScrnSetCursorPos(57,25);
ODScrnSetAttribute(0xf0);
ODScrnDisplayString(od_control.od_want_chat);
}
if(!od_control.od_user_keyboard_on)
{
ODScrnSetCursorPos(58,24);
ODScrnSetAttribute(0xf0);
ODScrnDisplayString(od_control.od_no_keyboard);
}
break;
case PEROP_DISPLAY8:
/* Display help status line. */
ODScrnSetAttribute(0x70);
ODScrnPutText(80, 25, 80, 25, abtGreyBlock);
ODScrnSetCursorPos(1,24);
ODScrnDisplayString(od_control.od_help_text);
ODScrnSetCursorPos(1,25);
/* Display copyright inforomation. */
if(bUserFull)/**/
{
ODScrnDisplayString(od_control.od_help_text2);
}
else
{
ODScrnDisplayString(OD_VER_UNREG_STAT);
}
break;
case PEROP_UPDATE1:
/* Update primary status line. */
ODScrnSetAttribute(0x70);
/* Update user's time limit. */
ODScrnSetCursorPos(24,25);
ODScrnPrintf(od_control.od_time_left,od_control.user_timelimit);
/* Update "sysop next" setting. */
ODScrnSetCursorPos(35,25);
if(od_control.sysop_next)
{
ODScrnDisplayString(od_control.od_sysop_next);
}
else
{
ODScrnDisplayString(" ");
}
/* Update ANSI mode indicator. */
if(od_control.user_ansi)
{
ODScrnDisplayString("[ANSI] ");
}
else
{
ODScrnDisplayString(" ");
}
/* Update AVATAR mode indicator. */
if(od_control.user_avatar)
{
ODScrnDisplayString("[AVT] ");
}
else
{
ODScrnDisplayString(" ");
}
/* Update keyboard-off indicator. */
ODScrnSetCursorPos(58,24);
if(od_control.od_user_keyboard_on)
{
ODScrnDisplayString(" ");
}
else
{
ODScrnSetAttribute(0xf0);
ODScrnDisplayString(od_control.od_no_keyboard);
}
/* Update want-chat indicator. */
ODScrnSetCursorPos(57,25);
if(od_control.user_wantchat)
{
ODScrnSetAttribute(0xf0);
ODScrnDisplayString(od_control.od_want_chat);
}
else
{
ODScrnDisplayString(" ");
}
break;
case PEROP_INITIALIZE:
od_control.key_hangup=0x2300;
od_control.key_drop2bbs=0x2000;
od_control.key_dosshell=0x2400;
od_control.key_chat=0x2e00;
od_control.key_sysopnext=0x3100;
od_control.key_lockout=0x2600;
od_control.key_status[0]=0x3b00;
od_control.key_status[1]=0x0000;
od_control.key_status[2]=0x0000;
od_control.key_status[3]=0x0000;
od_control.key_status[4]=0x0000;
od_control.key_status[5]=0x0000;
od_control.key_status[6]=0x0000;
od_control.key_status[7]=0x4300;
od_control.key_status[8]=0x4400;
od_control.key_keyboardoff=0x2500;
od_control.key_moretime=0x4800;
od_control.key_lesstime=0x5000;
od_control.od_page_statusline=-1;
break;
}
}

View File

@ -0,0 +1,197 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODStat.c
*
* Description: Helper functions used by various built-in personalities.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Oct 13, 1994 6.00 BP New file header format.
* Dec 09, 1994 6.00 BP Standardized coding style.
* Jul 18, 1995 6.00 BP Fix ODStatGetUserAge() bug.
* Nov 13, 1995 6.00 BP 32-bit portability.
* Nov 13, 1995 6.00 BP Created odstat.h.
* Nov 16, 1995 6.00 BP Removed oddoor.h, added odcore.h.
* Jan 12, 1996 6.00 BP Added ODStatStartArrowUse(), etc.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
* Mar 13, 1996 6.10 BP bOnlyShiftArrow -> nArrowUseCount.
* Mar 19, 1996 6.10 BP MSVC15 source-level compatibility.
* Aug 10, 2003 6.23 SH *nix support
*/
#define BUILDING_OPENDOORS
#include <string.h>
#include <ctype.h>
#include <stddef.h>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include "OpenDoor.h"
#include "ODCore.h"
#include "ODGen.h"
#include "ODStat.h"
#include "ODKrnl.h"
/* Global working string available to all personalities for status line */
/* generation. */
char szStatusText[80];
/* ----------------------------------------------------------------------------
* ODStatAddKey()
*
* Adds another hot key to the array of custom local keys.
*
* Parameters: wKeyCode - IBM scan-code/ASCII-code style key identification
* code to add.
*
* Return: void
*/
void ODStatAddKey(WORD wKeyCode)
{
if(od_control.od_num_keys < 16)
od_control.od_hot_key[od_control.od_num_keys++] = wKeyCode;
}
/* ----------------------------------------------------------------------------
* ODStatRemoveKey()
*
* Removes a custom sysop hotkey that was previously added with ODStatAddKey().
*
* Parameters: wKeyCode - The scan code / ASCII code key identification code
* to remove.
*
* Return: void
*/
void ODStatRemoveKey(WORD wKeyCode)
{
INT nCount;
for(nCount = 0; nCount < od_control.od_num_keys; ++nCount)
if((WORD)od_control.od_hot_key[nCount] == wKeyCode)
{
if(nCount != od_control.od_num_keys - 1)
{
od_control.od_hot_key[nCount] =
od_control.od_hot_key[od_control.od_num_keys-1];
}
--od_control.od_num_keys;
return;
}
}
/* ----------------------------------------------------------------------------
* ODStatGetUserAge()
*
* Generates a string containing the age, in years, of the current
* user, based on the current date and the user's birthday.
*
* Parameters: pszAge - Pointer to a string where user's age should be stored.
*
* Return: void
*/
void ODStatGetUserAge(char *pszAge)
{
INT nAge;
INT n;
time_t Time;
struct tm *TimeBlock;
if(od_control.od_info_type==RA2EXITINFO || od_control.od_info_type==DOORSYS_WILDCAT)
{
nAge = atoi(od_control.user_birthday) - 1;
if(strlen(od_control.user_birthday) == 8 && nAge <= 11)
{
if(od_control.user_birthday[6] >= '0'
&& od_control.user_birthday[6] <= '9'
&& od_control.user_birthday[7] >= '0'
&& od_control.user_birthday[7] <= '9')
{
if(od_control.user_birthday[3] >= '0'
&& od_control.user_birthday[3] <= '3'
&& od_control.user_birthday[4] >= '0'
&& od_control.user_birthday[4] <= '9')
{
Time = time(NULL);
TimeBlock = localtime(&Time);
n = (TimeBlock->tm_year % 100)
- atoi((char *)od_control.user_birthday + 6);
if(n < 0) nAge = n + 100; else nAge = n;
n = atoi(od_control.user_birthday) - 1;
if(TimeBlock->tm_mon < n)
--nAge;
else if(TimeBlock->tm_mon == n)
{
n=atoi((char *)od_control.user_birthday + 3);
if(TimeBlock->tm_mday < n) --nAge;
}
sprintf(pszAge, "%d", nAge);
return;
}
}
}
}
strcpy(pszAge, "?");
}
/* ----------------------------------------------------------------------------
* ODStatStartArrowUse()
*
* Called by OpenDoors when it needs to use the arrow keys, and so they
* shouldn't be used by the status line.
*
* Parameters: None
*
* Return: void
*/
void ODStatStartArrowUse(void)
{
++nArrowUseCount;
}
/* ----------------------------------------------------------------------------
* ODStatEndArrowUse()
*
* Called by OpenDoors when it no longer needs to use the arrow keys, and so
* they can again be used by the status line.
*
* Parameters: None
*
* Return: void
*/
void ODStatEndArrowUse(void)
{
ASSERT(nArrowUseCount > 0);
--nArrowUseCount;
}

View File

@ -0,0 +1,49 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODStat.h
*
* Description: Public functions provided by the odstat.c module, for status
* line functions shared among personalities.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Nov 13, 1995 6.00 BP Created.
* Jan 12, 1996 6.00 BP Added ODStatStartArrowUse(), etc.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
*/
#ifndef _INC_ODSTAT
#define _INC_ODSTAT
/* Global working string available to all personalities for status line */
/* generation. */
extern char szStatusText[80];
/* Public status line function prototypes. */
void ODStatAddKey(WORD wKeyCode);
void ODStatRemoveKey(WORD wKeyCode);
void ODStatGetUserAge(char *pszAge);
void ODStatStartArrowUse(void);
void ODStatEndArrowUse(void);
#endif /* _INC_ODSTAT */

View File

@ -0,0 +1,55 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODStr.c
*
* Description: Functions used to mainuplate strings
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Aug 10, 2003 6.23 SH *nix support
*/
#include <ctype.h>
#include "OpenDoor.h"
#ifdef ODPLAT_NIX
#include <string.h>
char *
od_strlwr(char *str)
{
char *p;
for(p=str;*p;p++)
*p=tolower(*p);
return(str);
}
char *
od_strupr(char *str)
{
char *p;
for(p=str;*p;p++)
*p=toupper(*p);
return(str);
}
#endif

View File

@ -0,0 +1,42 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODStr.h
*
* Description: Functions used to maipulate strings
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Aug 10, 2003 6.23 SH Initial rev.
*/
#include "OpenDoor.h"
#ifndef _INC_ODSTR
#define _INC_ODSTR
#ifdef ODPLAT_NIX
#define strnicmp strncasecmp
#define stricmp strcasecmp
#define strlwr(x) od_strlwr(x)
#define strupr(x) od_strupr(x)
char *od_strlwr(char *str);
char *od_strupr(char *str);
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,68 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODSwap.h
*
* Description: Provides memory swapping, spawning and certain other low-
* level assembly routines needed by OpenDoors. This file is only
* applicable when building the MS-DOS version of OpenDoors.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Nov 25, 1995 6.00 BP Created.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
*/
#ifndef _INC_ODSWAP
#define _INC_ODSWAP
#ifdef ODPLAT_DOS
/* Data types. */
typedef struct _vector
{
char number; /* vector number */
char flag; /* 0-CURRENT, 1-IRET, 2-free, 3-end */
unsigned int vseg; /* vector segment */
unsigned int voff; /* vector offset */
} VECTOR;
/* Global variables. */
extern char **environ;
/* Public functions. */
int _chkems(char *, int *);
int _create(char *, int *);
int _dskspace(int, unsigned int *, unsigned int *);
int _getcd(int, char *);
int _getdrv(void);
int _getems(int, int *);
int _getrc(void);
void _getvect(int, unsigned int *, unsigned int *);
int _restmap(char *);
int _savemap(char *);
void _setdrvcd(int, char * );
void _setvect(VECTOR *);
int _xsize(unsigned int, long *, long *);
int _xspawn(char *, char *, char *, VECTOR *, int, int, char *, int);
#endif /* ODPLAT_DOS */
#endif /* _INC_ODSWAP */

View File

@ -0,0 +1,70 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODTypes.c
*
* Description: Defines special data types used by OpenDoors.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Oct 15, 1994 6.00 BP Created.
* Jan 30, 1996 6.00 BP Added kODRCTimeout.
* Feb 08, 1996 6.00 BP Added kODRCSafeFailure.
* Feb 08, 1996 6.00 BP Added kODRCUnrecoverableFailure.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
*/
#ifndef _INC_ODTYPES
#define _INC_ODTYPES
/* Generic handle data type. */
typedef void * tODHandle;
#define ODHANDLE2PTR(h, t) ((t *) h)
#define ODPTR2HANDLE(p, t) ((tODHandle) p)
/* OpenDoors function call result codes. */
typedef enum
{
kODRCSuccess,
kODRCGeneralFailure,
kODRCNoMemory,
kODRCNothingWaiting,
kODRCNoMatch,
kODRCEndOfFile,
kODRCNoPortAddress,
kODRCNoUART,
kODRCInvalidCall,
kODRCFileAccessError,
kODRCFilenameTooLong,
kODRCTimeout,
kODRCSafeFailure,
kODRCUnrecoverableFailure,
kODRCUnsupported
} tODResult;
/* Callback function types. */
#ifdef _MSC_VER
typedef void ODCALL OD_COMPONENT_CALLBACK(void);
typedef void ODCALL OD_PERSONALITY_CALLBACK(BYTE btOperation);
#else /* !_MSC_VER */
typedef void OD_COMPONENT_CALLBACK(void);
typedef void OD_PERSONALITY_CALLBACK(BYTE btOperation);
#endif /* !_MSC_VER */
#endif /* !_INC_ODTYPES */

View File

@ -0,0 +1,461 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODUtil.c
*
* Description: Implements the non-platform specific utility functions that
* are defined in odutil.h. Platform specific utility functions
* are implemented in odplat.c.
*
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Nov 01, 1994 6.00 BP Created.
* Dec 31, 1994 6.00 BP Added ODMakeFilename().
* Nov 13, 1995 6.00 BP 32-bit portability.
* Nov 23, 1995 6.00 BP Added ODDWordDivide().
* Nov 23, 1995 6.00 BP Added ODDStringHasTail().
* Nov 23, 1995 6.00 BP Added ODFileSize().
* Nov 24, 1995 6.00 BP ODMakeFilename(): handle empty path.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
* Mar 06, 1996 6.10 BP Added ODDWordMultiply().
* Aug 10, 2003 6.23 SH *nix support
*/
#define BUILDING_OPENDOORS
#include <string.h>
#include <stdio.h>
#include "OpenDoor.h"
#include "ODStr.h"
#include "ODUtil.h"
#include "ODGen.h"
/* ========================================================================= */
/* General string manipulation functions. */
/* ========================================================================= */
/* ----------------------------------------------------------------------------
* ODStringCopy()
*
* Safely copies one string to another. Unlike strncpy(), ODStringCopy()
* ensures that the destination string is always '\0' terminated.
*
* Parameters: pszDest - Pointer to destination string to which to copy
* characters.
*
* pszSource - Pointer to source string from which to copy
* characters.
*
* nSizeOfDest - Maximum number of characters to place in pszDest,
* INCLUDING the '\0' string terminator.
*
* Return: void
*/
void ODStringCopy(char *pszDest, CONST char *pszSource, INT nSizeofDest)
{
ASSERT(pszDest != NULL);
ASSERT(pszSource != NULL);
ASSERT(nSizeofDest > 0);
/* Copy at most the specified number of bytes from source to dest, using */
/* (presumably well optimized) strncpy(). */
strncpy(pszDest, pszSource, nSizeofDest);
/* Ensure that destination string is '\0' terminated. This will not */
/* already be the case if strlen(pszSource) >= nSizeofDest. */
pszDest[nSizeofDest - 1] = '\0';
}
/* ----------------------------------------------------------------------------
* ODStringCToPascal()
*
* Converts a string from C's zero-terminated string format to Pascal's
* length byte + string data format.
*
* Parameters: psPascalString - Pointer to the destination string.
*
* btMaxPascalLength - Size of the destination string, as declared
* in Pascal.
*
* pszCString - Pointer to the source string, in C format.
*
* Return: A pointer to psPascalString.
*/
char *ODStringCToPascal(char *psPascalString, BYTE btMaxPascalLength,
char *pszCString)
{
BYTE btCStringLength = strlen(pszCString);
ASSERT(psPascalString != NULL);
ASSERT(btMaxPascalLength > 0);
ASSERT(pszCString != NULL);
memcpy((char *)psPascalString + 1,
pszCString, *psPascalString = (btCStringLength < btMaxPascalLength)
? btCStringLength : btMaxPascalLength);
return(psPascalString);
}
/* ----------------------------------------------------------------------------
* ODStringPascalToC()
*
* Converts a string from Pascal's length byte + string data format to C's
* zero-terminated string format.
*
* Parameters: pszCString - Pointer to destination string.
*
* psPascalString - Pointer to Pascal format source string.
*
* btMaxLength - Length of C string.
*
* Return: A pointer to pszCString.
*/
char *ODStringPascalToC(char *pszCString, char *psPascalString,
BYTE btMaxLength)
{
ASSERT(pszCString != NULL);
ASSERT(psPascalString != NULL);
ASSERT(btMaxLength > 0);
if(*(BYTE *)psPascalString <= btMaxLength)
{
memcpy(pszCString, (char *)psPascalString + 1, *psPascalString);
pszCString[(int)psPascalString[0]] = '\0';
}
else
{
pszCString[0] = '\0';
}
return(pszCString);
}
/* ----------------------------------------------------------------------------
* ODStringHasTail()
*
* Determines whether a string ends in exactly the specified sequence of
* characters.
*
* Parameters: pszFullString - String to examine.
*
* pszTail - String to look for at the end of
* pszFullString.
*
* Return: TRUE if the pszFullString does end with pszTail, FALSE if
* it does not.
*/
BOOL ODStringHasTail(char *pszFullString, char *pszTail)
{
INT nTailLength = strlen(pszTail);
INT nFullStringLength = strlen(pszFullString);
ASSERT(pszFullString != NULL);
ASSERT(pszTail != NULL);
if(nFullStringLength < nTailLength)
{
return(FALSE);
}
return(stricmp(pszFullString + (nFullStringLength - nTailLength), pszTail) == 0);
}
/* ========================================================================= */
/* File-related functions. */
/* ========================================================================= */
/* ----------------------------------------------------------------------------
* ODMakeFilename()
*
* Generates a fully-qualified filename from a path and base filename.
*
* Parameters: pszOut - String to store generated filename in.
*
* pszPath - Directory name. May be the same as pszOut, or
* may be different.
*
* pszFilename - Base filename.
*
* nMaxOutSize - Size of pszOut. This value should be one more
* than the maximum number of characters to be
* stored in the output string.
*
* Return: kODRCSuccess on success, or an error code on failure.
*/
tODResult ODMakeFilename(char *pszOut, CONST char *pszPath,
CONST char *pszFilename, INT nMaxOutSize)
{
/* Validate parameters in debug mode */
ASSERT(pszPath != NULL);
ASSERT(pszFilename != NULL);
ASSERT(pszOut != NULL);
ASSERT(pszFilename != pszOut);
ASSERT(nMaxOutSize > 0);
/* Check that there is enough room in the destination string to hold */
/* both source strings plus possibly an additional \-seperator. */
if((INT)(strlen(pszPath) + strlen(pszFilename) + 1) > nMaxOutSize - 1)
{
return(kODRCFilenameTooLong);
}
/* Copy path to output filename, if the addresses are different. */
if(pszPath != pszOut)
{
strcpy(pszOut, pszPath);
}
/* Ensure there is a trailing backslash, if path was not empty. */
#ifdef ODPLAT_NIX
#else
if(pszOut[strlen(pszOut) - 1] != DIRSEP && strlen(pszOut) > 0)
{
strcat(pszOut, DIRSEP_STR);
}
#endif
/* Append base filename. */
strcat(pszOut, pszFilename);
return(kODRCSuccess);
}
/* ----------------------------------------------------------------------------
* ODFileSize()
*
* Determines the size of a currently open file.
*
* Parameters: pfFile - Pointer to an already open file to examine.
*
* Return: The size of the file. In the case of a file that is open in
* binary mode, this will be the file length in bytes.
*/
DWORD ODFileSize(FILE *pfFile)
{
DWORD dwOriginal;
DWORD dwFileSize;
ASSERT(pfFile != NULL);
dwOriginal = ftell(pfFile);
fseek(pfFile, 0L, SEEK_END);
dwFileSize = ftell(pfFile);
fseek(pfFile, dwOriginal, SEEK_SET);
return(dwFileSize);
}
/* ========================================================================= */
/* DWORD math functions. */
/* ========================================================================= */
/* ----------------------------------------------------------------------------
* ODDWordShiftLeft()
*
* Shifts a DWORD to the left by the specified number of bits.
*
* Parameters: dwValue - Value to be shifted.
*
* btDistance - Distance to shift dwValue by.
*
* Return: Result of the shift operation.
*/
DWORD ODDWordShiftLeft(DWORD dwValue, BYTE btDistance)
{
WORD wUpper;
WORD wLower;
wLower = (WORD)dwValue;
wUpper = *(WORD *)(((BYTE *)(&dwValue)) + 2);
while(btDistance--)
{
wUpper <<= 1;
wUpper |= (wLower & 0x8000) >> 15;
wLower <<= 1;
}
dwValue = wLower;
*(WORD *)(((BYTE *)(&dwValue)) + 2) = wUpper;
return(dwValue);
}
/* ----------------------------------------------------------------------------
* ODDWordShiftRight()
*
* Shifts a DWORD to the right by the specified number of bits.
*
* Parameters: dwValue - Value to be shifted.
*
* btDistance - Distance to shift dwValue by.
*
* Return: Result of the shift operation.
*/
DWORD ODDWordShiftRight(DWORD dwValue, BYTE btDistance)
{
WORD wUpper;
WORD wLower;
wLower = (WORD)dwValue;
wUpper = *(WORD *)(((BYTE *)(&dwValue)) + 2);
while(btDistance--)
{
wLower >>= 1;
wLower |= (wUpper & 0x0001) << 15;
wUpper >>= 1;
}
dwValue=wLower;
*(WORD *)(((BYTE *)(&dwValue)) + 2) = wUpper;
return(dwValue);
}
/* ----------------------------------------------------------------------------
* ODDWordDivide()
*
* Divides one DWORD by another DWORD, calculating the quotient and remainder.
*
* Parameters: pdwQuotient - Location where the quotient should be stored,
* or NULL if quotient is not required.
*
* pdwRemainder - Location where remainder should be stored,
* or NULL if remainder is not required.
*
* dwDividend - Dividend to be divided by divisor.
*
* dwDivisor - Divisor to divide dividend by.
*
* Return: TRUE on success or FALSE on failure.
*/
BOOL ODDWordDivide(DWORD *pdwQuotient, DWORD *pdwRemainder,
DWORD dwDividend, DWORD dwDivisor)
{
INT nTimes = 0;
DWORD dwQuotient;
DWORD dwRemainder;
/* Check for divide by zero in debug versions. */
ASSERT(dwDivisor != 0);
/* Check that divisor is not zero. (An attempt to divide by zero will */
/* put this algorithm into an infinite loop, rather than triggering */
/* a divide fault.) */
if(dwDivisor == 0L)
{
return(FALSE);
}
/* Initialize remainder to be entire dividend */
dwRemainder = dwDividend;
/* Initialize quotient to 0 */
dwQuotient = 0L;
/* Determine largest required multiple of divisor */
while(dwRemainder >= dwDivisor)
{
dwDivisor = ODDWordShiftLeft(dwDivisor, 1);
++nTimes;
}
/* Loop across for all multiples of divisor, beginning with the largest */
do
{
dwQuotient = ODDWordShiftLeft(dwQuotient, 1);
/* If current remainder is >= this multiple of the divisor */
if(dwRemainder >= dwDivisor)
{
/* Subtract the multiple of the divisor from the remainder */
dwRemainder -= dwDivisor;
/* The next bit of the quotient should be a 1 */
dwQuotient |= 1L;
}
/* Divide current multiple of divisor by two */
dwDivisor = ODDWordShiftRight(dwDivisor, 1);
/* Repeat for all multiples of the divisor */
} while(nTimes--);
/* If caller asked for quotient, then return it */
if(pdwQuotient != NULL)
{
*pdwQuotient = dwQuotient;
}
/* If caller asked for remainder, then return it */
if(pdwRemainder != NULL)
{
*pdwRemainder = dwRemainder;
}
return(TRUE);
}
/* ----------------------------------------------------------------------------
* ODDWordDivide()
*
* Multiplies one DWORD by another, returning the product. Multiplication
* is performed by using at most 32 additions.
*
* Parameters: dwMultiplicand - The multiplicand.
*
* dwMultiplier - The multiplier.
*
* Return: Result of the multiplication.
*/
DWORD ODDWordMultiply(DWORD dwMultiplicand, DWORD dwMultiplier)
{
DWORD dwResult = 0;
/* Loop while multiplier is not zero */
while(dwMultiplier != 0)
{
/* If least significant bit of multiplier is set */
if(dwMultiplier & 0x00000001)
{
/* Add multiplicand to product */
dwResult += dwMultiplicand;
}
/* Shift multiplicand left one bit */
dwMultiplicand = ODDWordShiftLeft(dwMultiplicand, 1);
/* Shift multiplier right one bit */
dwMultiplier = ODDWordShiftRight(dwMultiplier, 1);
}
/* Return the final result to the caller. */
return(dwResult);
}

View File

@ -0,0 +1,66 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODUtil.h
*
* Description: Contains prototypes and definitions for use by non-platform
* specific utility functions. These functions are implemented in
* odutil.c. Platform-specific utility functions are defined in
* odplat.h, and implemented in odplat.c.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Nov 01, 1994 6.00 BP Created.
* Dec 31, 1994 6.00 BP Added ODMakeFilename().
* Nov 13, 1995 6.00 BP 32-bit portability.
* Nov 23, 1995 6.00 BP Added ODDWordDivide().
* Nov 23, 1995 6.00 BP Added ODDStringHasTail().
* Nov 23, 1995 6.00 BP Added ODFileSize().
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
* Mar 06, 1996 6.10 BP Added ODDWordMultiply().
*/
#ifndef _INC_ODUTIL
#define _INC_ODUTIL
#include "ODGen.h"
#include "ODTypes.h"
#include "OpenDoor.h"
/* General string manipulation functions. */
void ODStringCopy(char *pszDest, CONST char *pszSource, INT nSizeofDest);
char *ODStringCToPascal(char *psPascalString, BYTE btMaxPascalLength,
char *pszCString);
char *ODStringPascalToC(char *pszCString, char *psPascalString,
BYTE btMaxLength);
BOOL ODStringHasTail(char *pszFullString, char *pszTail);
/* File-related functions. */
tODResult ODMakeFilename(char *pszOut, CONST char *pszPath,
CONST char *pszFilename, INT nMaxOutSize);
DWORD ODFileSize(FILE *pfFile);
/* DWORD math functions. */
DWORD ODDWordShiftLeft(DWORD dwValue, BYTE btDistance);
DWORD ODDWordShiftRight(DWORD dwValue, BYTE btDistance);
BOOL ODDWordDivide(DWORD *pdwQuotient, DWORD *pdwRemainder,
DWORD dwDividend, DWORD dwDivisor);
DWORD ODDWordMultiply(DWORD dwMultiplicand, DWORD dwMultiplier);
#endif /* !_INC_ODUTIL */

View File

@ -0,0 +1,270 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODWCat.c
*
* Description: Implements the Wildcat personality.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Oct 13, 1994 6.00 BP New file header format.
* Dec 09, 1994 6.00 BP Standardized coding style.
* Jul 18, 1995 6.00 BP Fix ODStatGetUserAge() bug.
* Nov 13, 1995 6.00 BP 32-bit portability.
* Nov 14, 1995 6.00 BP Added include of odscrn.h.
* Nov 16, 1995 6.00 BP Removed oddoor.h, added odcore.h.
* Dec 24, 1995 6.00 BP Fixed black square at pos 25x80.
* Dec 30, 1995 6.00 BP Added ODCALL for calling convention.
* Jan 03, 1996 6.00 BP Display connect speed with %lu.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
* Mar 19, 1996 6.10 BP MSVC15 source-level compatibility.
* Aug 10, 2003 6.23 SH *nix support
*/
#define BUILDING_OPENDOORS
#include <string.h>
#include <ctype.h>
#include <stddef.h>
#include <time.h>
#include <stdio.h>
#include "OpenDoor.h"
#include "ODGen.h"
#include "ODScrn.h"
#include "ODCore.h"
#include "ODStat.h"
#include "ODKrnl.h"
/* ----------------------------------------------------------------------------
* pdef_wildcat()
*
* Personality function for the Wildcat BBS-like status line / function key
* personality.
*
* Parameters: btOperation - Indicates personality operation to be performed.
*
* Return: void
*/
ODAPIDEF void ODCALL pdef_wildcat(BYTE btOperation)
{
BYTE btInfoType = od_control.od_info_type;
switch(btOperation)
{
case PEROP_DISPLAY1:
ODScrnSetAttribute(0x70);
ODScrnSetCursorPos(1,24);
ODScrnDisplayString(" Baud: ");
ODScrnSetCursorPos(1,25);
ODScrnDisplayString("Phone: Sec: Time Left: ");
ODScrnPutText(80, 25, 80, 25, abtGreyBlock);
ODScrnSetAttribute(0x71);
ODScrnSetCursorPos(1,24);
sprintf(szStatusText, "(%s), ", od_control.user_name,
od_control.user_location);
ODScrnPrintf("%34.34s", szStatusText);
ODScrnSetCursorPos(43, 24);
ODScrnPrintf("%lu", od_control.od_connect_speed);
ODScrnSetCursorPos(8,25);
if(od_control.od_extended_info || btInfoType==SFDOORSDAT || btInfoType==DOORSYS_GAP || btInfoType==DOORSYS_WILDCAT)
{
ODScrnDisplayString(od_control.user_homephone);
}
if(btInfoType==RA1EXITINFO || btInfoType==RA2EXITINFO || btInfoType==DOORSYS_WILDCAT)
{
char szUserAge[7];
ODScrnSetCursorPos(28,25);
ODScrnSetAttribute(0x70);
ODScrnDisplayString("Age: ");
ODScrnSetAttribute(0x71);
ODStatGetUserAge(szUserAge);
ODScrnDisplayString(szUserAge);
}
ODScrnSetCursorPos(43,25);
ODScrnPrintf("%u",od_control.user_security);
if(btInfoType==RA1EXITINFO || btInfoType==RA2EXITINFO || btInfoType==DOORSYS_WILDCAT)
{
if(strlen(od_control.user_firstcall)==8)
{
ODScrnSetCursorPos(49,25);
ODScrnSetAttribute(0x70);
ODScrnDisplayString("Since: ");
ODScrnSetAttribute(0x71);
ODScrnDisplayChar(od_control.user_firstcall[0]);
ODScrnDisplayChar(od_control.user_firstcall[1]);
ODScrnDisplayChar('/');
ODScrnDisplayChar(od_control.user_firstcall[6]);
ODScrnDisplayChar(od_control.user_firstcall[7]);
}
}
case PEROP_UPDATE1:
ODScrnSetAttribute(0x71);
ODScrnSetCursorPos(74,25);
if(od_control.user_timelimit<=9)
{
ODScrnPrintf(" %d",od_control.user_timelimit);
}
else if(od_control.user_timelimit<=99)
{
ODScrnPrintf(" %d",od_control.user_timelimit);
}
else if(od_control.user_timelimit<=999)
{
ODScrnPrintf(" %d",od_control.user_timelimit);
}
else
{
ODScrnPrintf("%d",od_control.user_timelimit);
}
ODScrnSetAttribute(0x70);
ODScrnSetCursorPos(56,24);
if(od_control.od_okaytopage==TRUE)
ODScrnDisplayString("Page Bell ");
else
ODScrnDisplayString(" ");
if(od_control.od_user_keyboard_on)
ODScrnDisplayString("Kybd ");
else
ODScrnDisplayString(" ");
if(od_control.sysop_next)
ODScrnDisplayString("Local-Next");
else
ODScrnDisplayString(" ");
break;
case PEROP_INITIALIZE:
od_control.key_hangup=0x0000;
od_control.key_drop2bbs=0x4400;
od_control.key_dosshell=0x2000;
od_control.key_chat=0x4100;
od_control.key_sysopnext=0x3b00;
od_control.key_lockout=0x8100;
od_control.key_status[0]=0x0000;
od_control.key_status[1]=0x0000;
od_control.key_status[2]=0x0000;
od_control.key_status[3]=0x0000;
od_control.key_status[4]=0x0000;
od_control.key_status[5]=0x0000;
od_control.key_status[6]=0x0000;
od_control.key_status[7]=0x0000;
od_control.key_status[8]=0x0000;
od_control.key_keyboardoff=0x2500;
od_control.key_moretime=0x0000;
od_control.key_lesstime=0x0000;
od_control.od_page_statusline=-1;
ODStatAddKey(0x4200); /* Key to end chat */
ODStatAddKey(0x4800); /* Key to add five minutes */
ODStatAddKey(0x5000); /* key to subtract five minutes */
ODStatAddKey(0x7800); /* key to hangup */
ODStatAddKey(0x7900); /* key to hangup */
ODStatAddKey(0x7a00); /* key to hangup */
ODStatAddKey(0x7b00); /* key to hangup */
ODStatAddKey(0x7c00); /* key to hangup */
ODStatAddKey(0x7d00); /* key to hangup */
ODStatAddKey(0x7e00); /* key to hangup */
ODStatAddKey(0x7f00); /* key to hangup */
ODStatAddKey(0x8000); /* key to hangup */
ODStatAddKey(0x3f00); /* key to toggle bell */
ODStatAddKey(0x3e00); /* key to toggle bell */
break;
case PEROP_CUSTOMKEY:
switch((WORD)od_control.od_last_hot)
{
case 0x4200:
od_control.od_chat_active = FALSE;
break;
case 0x4800:
if(od_control.user_timelimit <= 1435)
{
od_control.user_timelimit += 5;
bForceStatusUpdate = TRUE;
CALL_KERNEL_IF_NEEDED();
}
break;
case 0x5000:
od_control.user_timelimit -= 5;
bForceStatusUpdate = TRUE;
CALL_KERNEL_IF_NEEDED();
break;
case 0x7800:
case 0x7900:
case 0x7a00:
case 0x7b00:
case 0x7c00:
case 0x7d00:
case 0x7e00:
case 0x7f00:
case 0x8000:
od_exit(2,TRUE);
break;
case 0x3f00:
case 0x3e00:
if(od_control.od_okaytopage!=TRUE)
{
od_control.od_okaytopage=TRUE;
}
else
{
od_control.od_okaytopage=FALSE;
}
bForceStatusUpdate = TRUE;
CALL_KERNEL_IF_NEEDED();
break;
default:
return;
}
od_control.od_last_hot=0;
break;
case PEROP_DEINITIALIZE:
ODStatRemoveKey(0x4200);
ODStatRemoveKey(0x4800);
ODStatRemoveKey(0x5000);
ODStatRemoveKey(0x7800);
ODStatRemoveKey(0x7900);
ODStatRemoveKey(0x7a00);
ODStatRemoveKey(0x7b00);
ODStatRemoveKey(0x7c00);
ODStatRemoveKey(0x7d00);
ODStatRemoveKey(0x7e00);
ODStatRemoveKey(0x7f00);
ODStatRemoveKey(0x8000);
ODStatRemoveKey(0x3e00);
ODStatRemoveKey(0x3f00);
break;
}
}

View File

@ -0,0 +1,319 @@
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODWin.c
*
* Description: Implements the od_window_...() functions for creating
* and removing text-mode windows.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Oct 13, 1994 6.00 BP New file header format.
* Nov 01, 1994 6.00 BP Include stdlib.h for malloc prototype.
* Dec 09, 1994 6.00 BP Standardized coding style.
* Dec 12, 1994 6.00 BP Set od_error on window remove failure.
* Aug 19, 1995 6.00 BP 32-bit portability.
* Nov 16, 1995 6.00 BP Removed oddoor.h, added odcore.h.
* Dec 12, 1995 6.00 BP Added entry, exit and kernel macros.
* Dec 30, 1995 6.00 BP Added ODCALL for calling convention.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
* Aug 10, 2003 6.23 SH *nix support
*/
#define BUILDING_OPENDOORS
#include <string.h>
#include <stdlib.h>
#include "OpenDoor.h"
#include "ODGen.h"
#include "ODCore.h"
#include "ODKrnl.h"
/* ----------------------------------------------------------------------------
* od_window_create()
*
* Creates a window on the screen, storing information on the original screen
* contents "under" the window in order to restore the screen after the window
* is removed. A window that is created with this function must be destroyed
* by od_window_remove() in order to free up memory that is allocated by this
* function.
*
* Parameters: nLeft - 1-based column number of left edge of window.
*
* nTop - 1-based row number of top edge of window.
*
* nRight - 1-based column number of right edge of window.
*
* nBottom - 1-based row number of bottom edge of window.
*
* pszTitle - Pointer to a string containing title for window.
* If this string is empty, no title is displayed.
*
* btBoarderCol - Colour of window boarder.
*
* btTitleCol - Colour of window title.
*
* btInsideCol - Colour of rest of window.
*
* nReserved - Should always be 0 for this version.
*
* Return: Pointer to window description buffer (which must later be
* passed to od_window_remove(), or NULL on failure.
*/
ODAPIDEF void * ODCALL od_window_create(INT nLeft, INT nTop, INT nRight,
INT nBottom, char *pszTitle, BYTE btBorderCol, BYTE btTitleCol,
BYTE btInsideCol, INT nReserved)
{
BYTE btLine;
BYTE btBetweenSize;
void *pBuffer;
BYTE btTitleSize;
BYTE btRemaining;
/* Log function entry if running in trace mode. */
TRACE(TRACE_API, "od_window_create()");
/* Ensure that OpenDoors has been initialized */
if(!bODInitialized) od_init();
OD_API_ENTRY();
nReserved &= 0x00;
btBetweenSize = (nRight - nLeft) - 1;
/* Setup od_box_chars appropriately. */
if(od_control.od_box_chars[BOX_BOTTOM]==0)
{
od_control.od_box_chars[BOX_BOTTOM] = od_control.od_box_chars[BOX_TOP];
}
if(od_control.od_box_chars[BOX_RIGHT]==0)
{
od_control.od_box_chars[BOX_RIGHT] = od_control.od_box_chars[BOX_LEFT];
}
/* Ensure that the current display mode can support the capabilities */
/* required to display and remove windows. */
if(!(od_control.user_ansi || od_control.user_avatar))
{
od_control.od_error = ERR_NOGRAPHICS;
OD_API_EXIT();
return(NULL);
}
/* Validate parameters. */
if(nLeft < 1 || nTop < 1 || nRight > 80 || nBottom > 25 || nRight-nLeft < 2
|| nBottom-nTop < 2)
{
od_control.od_error = ERR_PARAMETER;
OD_API_EXIT();
return(NULL);
}
/* Allocate a buffer large enough to hold all window information. */
if((pBuffer = malloc((nRight - nLeft + 1) * 2 + (nBottom - nTop + 1) * 160
+ 4)) == NULL)
{
od_control.od_error = ERR_MEMORY;
OD_API_EXIT();
return(NULL);
}
/* Store current contents of screen where window will be drawn. */
if(!od_gettext(nLeft, nTop, nRight, nBottom, (char *)pBuffer+4))
{
free(pBuffer);
/* Note: od_control.od_error code has been set by od_gettext(). */
OD_API_EXIT();
return(NULL);
}
/* Store window information in buffer. */
((char *)pBuffer)[0]=nLeft;
((char *)pBuffer)[1]=nTop;
((char *)pBuffer)[2]=nRight;
((char *)pBuffer)[3]=nBottom;
/* Determine number of characters of title to display. */
if(pszTitle==NULL)
{
btTitleSize = 0;
}
else
{
if((btTitleSize = strlen(pszTitle)) > (btBetweenSize - 4))
{
btTitleSize = btBetweenSize - 4;
}
}
/* Move to position of window's top corner, prepare to begin drawing the */
/* window. */
od_set_cursor(nTop,nLeft);
od_set_attrib(btBorderCol);
/* Display corner character. */
od_putch(od_control.od_box_chars[BOX_UPPERLEFT]);
/* If there is no title, display top line all in one piece. */
if(btTitleSize == 0)
{
/* Display top line. */
od_repeat(od_control.od_box_chars[BOX_TOP],btBetweenSize);
}
else
{
/* If there is a title, display the top line with a title centered in */
/* it. */
od_repeat(od_control.od_box_chars[BOX_TOP],btRemaining =
((btBetweenSize - btTitleSize - 2) / 2));
od_set_attrib(btTitleCol);
od_putch(' ');
od_disp(pszTitle,btTitleSize,TRUE);
od_putch(' ');
od_set_attrib(btBorderCol);
od_repeat(od_control.od_box_chars[BOX_TOP],
(BYTE)(btBetweenSize - btRemaining - btTitleSize - 2));
}
/* Display top right corner character. */
od_putch(od_control.od_box_chars[BOX_UPPERRIGHT]);
/* If AVATAR mode is available. */
if(od_control.user_avatar)
{
/* Display first left verticle line. */
od_set_cursor(nTop + 1, nLeft);
od_putch(od_control.od_box_chars[BOX_LEFT]);
/* Fill in center of window with AVATAR clear area control sequence. */
od_emulate(22);
od_emulate(12);
od_emulate(btInsideCol);
od_emulate((BYTE)((nBottom - nTop) - 1));
od_emulate(btBetweenSize);
od_set_attrib(btBorderCol);
od_set_cursor(nTop + 1 , nRight);
/* Display first right verticle line. */
od_putch(od_control.od_box_chars[BOX_RIGHT]);
/* Display remaining verticle lines. */
for(btLine=nTop+2;btLine<nBottom;++btLine)
{
/* Move to line start and display left line character. */
od_set_cursor(btLine,nLeft);
od_putch(od_control.od_box_chars[BOX_LEFT]);
/* Move to line start and display right line character. */
od_set_cursor(btLine,nRight);
od_putch(od_control.od_box_chars[BOX_RIGHT]);
}
}
/* If AVATAR mode is not available. */
else
{
/* Loop through middle lines of window. */
for(btLine=nTop+1;btLine<nBottom;++btLine)
{
/* Move to line start and display left line character. */
od_set_cursor(btLine,nLeft);
od_putch(od_control.od_box_chars[BOX_LEFT]);
/* Set window colour. */
od_set_attrib(btInsideCol);
/* display blank area between left and right vertical lines. */
od_repeat(' ',btBetweenSize);
/* Set border colour. */
od_set_attrib(btBorderCol);
/* Display right line. */
od_putch(od_control.od_box_chars[BOX_RIGHT]);
}
}
/* Display bottom border of window */
od_set_cursor(nBottom,nLeft);
od_putch(od_control.od_box_chars[BOX_LOWERLEFT]);
od_repeat(od_control.od_box_chars[BOX_BOTTOM],btBetweenSize);
od_putch(od_control.od_box_chars[BOX_LOWERRIGHT]);
/* Return a pointer to the window information buffer. */
OD_API_EXIT();
return(pBuffer);
}
/* ----------------------------------------------------------------------------
* od_window_remove()
*
* Removes window from the screen, restoring the screen contents that where
* in the window area when the window was first created.
*
* Parameters: pWinInfo - Pointer to buffer returned by od_window_create().
* This buffer is deallocated before od_window_remove()
* returns.
*
* Return: TRUE on success, or FALSE on failure.
*/
ODAPIDEF BOOL ODCALL od_window_remove(void *pWinInfo)
{
/* Log function entry if running in trace mode */
TRACE(TRACE_API, "od_window_remove()");
/* Ensure that OpenDoors has been initialized */
if(!bODInitialized) od_init();
OD_API_ENTRY();
if(pWinInfo == NULL)
{
/* Set error code and return with failure. */
od_control.od_error = ERR_PARAMETER;
OD_API_EXIT();
return(FALSE);
}
if(!od_puttext(((char *)pWinInfo)[0], ((char *)pWinInfo)[1], ((char *)pWinInfo)[2], ((char *)pWinInfo)[3], (char *)pWinInfo + 4))
{
/* Deallocate memory assigned to window information structure. */
free(pWinInfo);
/* Note: od_control.od_error code has been set by od_puttext(). */
/* Return with failure. */
OD_API_EXIT();
return(FALSE);
}
/* Deallocate memory assigned to window information structure. */
free(pWinInfo);
/* Return with success. */
OD_API_EXIT();
return(TRUE);
}

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,99 @@
; OpenDoors Online Software Programming Toolkit
; (C) Copyright 1991 - 1999 by Brian Pirie.
;
; Oct-2001 door32.sys/socket modifications by Rob Swindell (www.synchro.net)
;
; This library is free software; you can redistribute it and/or
; modify it under the terms of the GNU Lesser General Public
; License as published by the Free Software Foundation; either
; version 2 of the License, or (at your option) any later version.
;
; This library is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
; Lesser General Public License for more details.
;
; You should have received a copy of the GNU Lesser General Public
; License along with this library; if not, write to the Free Software
; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
;
;
; File: OpenDoors.def
;
; Description: Module definition file for the OpenDoors Win32 DLL.
;
; Revisions: Date Ver Who Change
; ---------------------------------------------------------------
; Dec 12, 1995 6.00 BP Created.
; Jan 11, 1996 6.00 BP Added exports for undecorated names.
; Feb 19, 1996 6.00 BP Changed version number to 6.00.
; Mar 03, 1996 6.10 BP Begin version 6.10.
; Mar 03, 1996 6.10 BP Added od_get_cursor.
; Mar 21, 1996 6.10 BP Added od_control_get().
; Oct 19, 2001 6.20 RS Added door32.sys and socket support.
LIBRARY ODOORS62
DESCRIPTION "OpenDoors"
VERSION 6.2
EXPORTS
ODConfigInit=_ODConfigInit@0
ODLogEnable=_ODLogEnable@0
ODMPSEnable=_ODMPSEnable@0
od_add_personality=_od_add_personality@16
od_autodetect=_od_autodetect@4
od_carrier=_od_carrier@0
od_chat=_od_chat@0
od_clear_keybuffer=_od_clear_keybuffer@0
od_clr_line=_od_clr_line@0
od_clr_scr=_od_clr_scr@0
od_color_config=_od_color_config@4
od_control_get=_od_control_get@0
od_disp=_od_disp@12
od_disp_emu=_od_disp_emu@8
od_disp_str=_od_disp_str@4
od_draw_box=_od_draw_box@16
od_edit_str=_od_edit_str@32
od_emulate=_od_emulate@4
od_exit=_od_exit@8
od_get_answer=_od_get_answer@4
od_get_cursor=_od_get_cursor@8
od_get_input=_od_get_input@12
od_get_key=_od_get_key@4
od_gettext=_od_gettext@20
od_hotkey_menu=_od_hotkey_menu@12
od_init=_od_init@0
od_input_str=_od_input_str@16
od_kernel=_od_kernel@0
od_key_pending=_od_key_pending@0
od_list_files=_od_list_files@4
od_log_open=_od_log_open@0
od_log_write=_od_log_write@4
od_multiline_edit=_od_multiline_edit@12
od_page=_od_page@0
od_parse_cmd_line=_od_parse_cmd_line@4
od_popup_menu=_od_popup_menu@24
_od_printf=od_printf
od_printf=od_printf
od_putch=_od_putch@4
od_puttext=_od_puttext@20
od_repeat=_od_repeat@8
od_restore_screen=_od_restore_screen@4
od_save_screen=_od_save_screen@4
od_scroll=_od_scroll@24
od_send_file=_od_send_file@4
od_set_attrib=_od_set_attrib@4
od_set_color=_od_set_color@8
od_set_cursor=_od_set_cursor@8
od_set_dtr=_od_set_dtr@4
od_set_personality=_od_set_personality@4
od_set_statusline=_od_set_statusline@4
od_sleep=_od_sleep@4
od_spawn=_od_spawn@4
od_spawnvpe=_od_spawnvpe@16
od_window_create=_od_window_create@36
od_window_remove=_od_window_remove@4
pdef_opendoors=_pdef_opendoors@4
pdef_pcboard=_pdef_pcboard@4
pdef_ra=_pdef_ra@4
pdef_wildcat=_pdef_wildcat@4
_od_control=od_control DATA
od_control=od_control DATA

File diff suppressed because it is too large Load Diff

View File

View File

@ -0,0 +1,36 @@
Features/Changes which will break the API and so must go into v7
----------------------------------------------------------------
- Do not pack the od_control structure in memory. This is plain silly.
- Do not use the BOOL type in od_control or in any of the public functions.
Using it causes problems with stuff that defines a BOOL as a different
size. For example, xpdev uses int as a BOOL whereas OpenDoors uses a char.
- Support telnet IAC escaping, add an item to the od_control struct to
keep track of the current status of IAC escapes.
- Fix up the local display for Win32. It's horribly slow currently.
Possibly just dust of the DOS stuff and use ciolib?
- Make output functions take an optional position and attribute to cut down
on small send()s.
- Audit for small send()s in general.
- Possibly improve the output thread and make *nix multi-threaded for block
buffering ala Synchronet.
- Change to 24-line default. This means fixing the personalities, and the
screen stuff.
- Autodetect if passed handle is a socket (Like I did for MyCroft doors)
- We need some non-socket way of dealing with I/O for Win32. Something that
operates along the lines of stdio on *nix. When BBSs commonly start doing
SSH, is the door supposed to do SSH also? A local socket would work, but it
seems like the Wrong Thing. The main reason stdio is out is that there's no
standard way of passing hangup info etc.
- Check the timestamp on the dropfile... do not use an old one! Add and
od_control variable to prevent this behaviour.
- Add a bunch of status-line specific functions to allow new personalities:
od_status_set_cursor()
od_status_set_attrib()
od_status_puttext()
od_status_gettext()
od_status_printf()
od_status_disp_str()
od_status_putch()
od_status_addkey()
od_status_delkey()
- OD_DISP_EMU() has problems with ANSI music (of course)

Binary file not shown.

After

Width:  |  Height:  |  Size: 838 B

View File

@ -0,0 +1,7 @@
make -fDOS.mak -DTARGET=s > out.txt
make -fDOS.mak -DTARGET=c >> out.txt
make -fDOS.mak -DTARGET=m >> out.txt
make -fDOS.mak -DTARGET=l >> out.txt
make -fDOS.mak -DTARGET=h >> out.txt
set INCLUDE=c:\msdev\include;c:\msdev\mfc\include
nmake -fWin32.mak >> out.txt

View File

@ -0,0 +1,5 @@
make -fDOS.mak -DTARGET=s > out.txt
make -fDOS.mak -DTARGET=c >> out.txt
make -fDOS.mak -DTARGET=m >> out.txt
make -fDOS.mak -DTARGET=l >> out.txt
make -fDOS.mak -DTARGET=h >> out.txt

View File

@ -0,0 +1,346 @@
/* EX_CHAT.C - Example of a multi-window full-screen chat program written */
/* with OpenDoors. See manual for instructions on how to compile */
/* a program using OpenDoors. */
/* */
/* This program shows how to do the following: */
/* */
/* - Replace the standard OpenDoors chat mode with your own */
/* chat mode implementation. See instructions below. */
/* - How to scroll a portion of the screen, leaving the rest */
/* of the screen unaltered. */
/* - How to determine whether input came from the local or */
/* remote keyboard. */
/* - How to display a popup window with a message in it when */
/* the sysop shells to DOS. (DOS version only.) */
/* - How to save and restore the entire contents of the */
/* screen. */
/* */
/* Conditional compilation directives allow this program to */
/* be compiled as a stand-alone chat door, or as a */
/* replacement chat mode to be integrated into any OpenDoors */
/* program. If STANDALONE is #defined, ex_chat.c will be */
/* compiled as a split-screen chat door that can be run like */
/* any door program. If STANDALONE is not #defined, the chat */
/* mode function will be compiled as a replacement chat mode */
/* for the chat mode built into OpenDoors. In this case, the */
/* demo mainline function simply displays a prompt, and will */
/* exit the door as soon as you press the [ENTER] key. While */
/* the program is running, if you invoke chat mode (press */
/* [ALT]-[C]), the current screen will be saved and the */
/* split-screen chat mode will be activated. When you press */
/* [ESC] the split-screen chat mode will end, and the */
/* original screen will be restored. To integrate this chat */
/* mode into your own program, you should simply set */
/* od_control.od_cbefore_chat to point to the */
/* fullscreen_chat function, as shown, and remove the mainline */
/* (main()/WinMain()) function from this file. The compile this */
/* file into your program after removing the #define STANDALONE */
/* line. */
/* Include required header files. */
#include "OpenDoor.h"
#include <string.h>
/* The following #define forces this code to compile as a stand-alone door */
/* program. If you wish to use this code to replace the standard OpenDoors */
/* chat mode in your own program, remove this #define. */
#define STANDALONE
/* Full-screen chat function prototypes. */
void fullscreen_chat(void);
void chat_new_line(void);
void display_shell_window(void);
void remove_shell_window(void);
/* The main() or WinMain() function: program execution begins here. */
#ifdef ODPLAT_WIN32
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
#else
int main(int argc, char *argv[])
#endif
{
/* Handle standard command-line options and perform other needed setup. */
#ifdef ODPLAT_WIN32
od_control.od_cmd_show = nCmdShow;
od_parse_cmd_line(lpszCmdLine);
#else
od_parse_cmd_line(argc, argv);
#endif
#ifdef STANDALONE /* If compiled as a stand-alone chat program */
od_init(); /* Initialize OpenDoors */
fullscreen_chat(); /* Invoke full-screen chat function */
#else /* If compiled as replacement for OpenDoors chat mode */
/* Setup OpenDoors to use our custom chat mode instead */
od_control.od_cbefore_chat=fullscreen_chat;
od_printf("Press [Enter] to exit door, or invoke chat mode.\n\r");
od_get_answer("\n\r");
#endif
od_exit(0, FALSE); /* Exit program. */
return(0);
}
/* FULL-SCREEN CHAT CUSTOMIZATION OPTIONS */
char window_colour[2]={0x0b,0x0c}; /* Text colour used for each person */
char bar_colour=0x70; /* Colour of window seperation bar */
char top_line[2]={13,1}; /* Specifies location of each window on screen */
char bottom_line[2]={23,11}; /* Line number of bottom of each window */
char bar_line=12; /* Line number of window seperation bar */
char scroll_distance=2; /* Distance to scroll window when required */
char shell_window_title=0x1a; /* Colour of title of DOS shell notice window */
char shell_window_boarder=0x1f; /* Colour of DOS shell window boarder */
char shell_window_text=0x1b; /* Colour of text in DOS shell window */
int cursor_window; /* FULL-SCREEN CHAT INTERNAL VARIABLES */
char current_word[2][81];
int word_length[2];
int cursor_col[2];
int cursor_line[2];
unsigned char key;
int old_chat_key;
void *shell_window;
char *before_shell_text;
char *after_shell_text;
#ifndef STANDALONE /* If compiled as replacement for OpenDoors chat mode */
char screen_buffer[4004];
#endif
/* FULL-SCREEN CHAT FUNCTION */
void fullscreen_chat(void)
{
cursor_window=0; /* Reset working variables */
word_length[0]=word_length[1]=0;
cursor_col[0]=cursor_col[1]=1;
cursor_line[0]=top_line[0];
cursor_line[1]=top_line[1];
/* If ANSI or AVATAR graphics mode is not available */
if(!od_control.user_ansi && !od_control.user_avatar)
{ /* Then use OpenDoor's line chat mode instead */
#ifdef STANDALONE /* If compiled as a stand-alone chat program */
od_chat();
#endif
return;
}
od_control.od_cbefore_shell=display_shell_window; /* Set shell settings */
od_control.od_cafter_shell=remove_shell_window;
before_shell_text=od_control.od_before_shell;
after_shell_text=od_control.od_after_shell;
od_control.od_before_shell=NULL;
od_control.od_after_shell=NULL;
od_control.od_chat_active=TRUE;
#ifdef STANDALONE /* If compiled as a stand-alone chat program */
old_chat_key=od_control.key_chat; /* Prevent internal chat mode from */
od_control.key_chat=0; /* being invoked */
#else /* If compiled as replacement for OpenDoors chat mode */
od_save_screen(screen_buffer); /* Save current screen contents. */
#endif
/* DRAW THE CHAT SCREEN */
od_set_attrib(window_colour[0]);
od_clr_scr(); /* Clear the screen */
od_set_cursor(bar_line,1); /* Draw window separation bar */
od_set_attrib(bar_colour);
od_clr_line();
od_set_cursor(bar_line,67);
od_printf("Ctrl-A: Clear");
od_set_cursor(bar_line,1);
od_printf(" Top : %-.28s Bottom : %-.28s ",
od_control.sysop_name, od_control.user_name);
od_set_cursor(top_line[0],1); /* Locate cursor where typing will begin */
od_set_attrib(window_colour[0]); /* Set appropriate text colour */
/* MAIN CHAT LOOP */
for(;;) /* (Repeats for each character typed) */
{
do
{
key=(char)od_get_key(FALSE); /* Get next keystroke from keyboard */
/* CHECK FOR SYSOP ABORT */
if((key==27 && od_control.od_last_input==1) /* If sysop pressed ESC */
|| !od_control.od_chat_active)
{
od_set_attrib(0x07); /* Reset display colour */
od_clr_scr(); /* Clear the screen */
od_control.od_cbefore_shell=NULL; /* Restore DOS shell settings */
od_control.od_cafter_shell=NULL;
od_control.od_before_shell=before_shell_text;
od_control.od_after_shell=after_shell_text;
#ifdef STANDALONE /* If compiled as a stand-alone chat program */
od_control.key_chat=old_chat_key;/* Re-enable internal chat mode */
#else /* If compiled as replacement for OpenDoors chat mode */
od_control.od_chat_active=FALSE; /* Turn off chat mode */
od_restore_screen(screen_buffer); /* Restore orignal screen */
#endif
return; /* Exit full-screen chat */
}
} while(key==0);
/* CHECK FOR NEW TYPIST */
if(od_control.od_last_input!=cursor_window)/* If new person typing now */
{ /* Switch cursor to appropriate window */
cursor_window=od_control.od_last_input; /* Set current typist */
/* Move cursor to new window */
od_set_cursor(cursor_line[cursor_window],cursor_col[cursor_window]);
od_set_attrib(window_colour[cursor_window]); /* Change text colour */
}
if(key==13 || key==10) /* IF USER PRESSED [ENTER] / [RETURN] */
{
word_length[cursor_window]=0; /* Enter constitutes end of word */
chat_new_line(); /* Move to next line */
}
else if(key==8) /* IF USER PRESS [BACKSPACE] */
{
if(cursor_col[cursor_window] > 1) /* If not at left of screen */
{
--cursor_col[cursor_window]; /* Move cursor back on character */
if(word_length[cursor_window] > 0) --word_length[cursor_window];
od_printf("\b \b"); /* Erase last character from screen */
}
}
else if(key==32) /* IF USER PRESSED [SPACE] */
{
word_length[cursor_window]=0; /* [Space] constitutes end of word */
if(cursor_col[cursor_window]==79) /* If at end of line */
chat_new_line(); /* Move cursor to next line */
else /* If not at end of line */
{
++cursor_col[cursor_window]; /* Increment cursor position */
od_putch(32); /* Display a space */
}
}
else if(key==1) /* IF USER PRESSED CLEAR WINDOW KEY */
{ /* Clear user's window */
od_scroll(1,top_line[cursor_window],79,bottom_line[cursor_window],
bottom_line[cursor_window]-top_line[cursor_window]+1,0);
word_length[cursor_window]=0; /* We are no longer composing a word */
cursor_col[cursor_window]=1; /* Reset cursor position */
cursor_line[cursor_window]=top_line[cursor_window];
od_set_cursor(cursor_line[cursor_window],cursor_col[cursor_window]);
}
else if(key>32) /* IF USER TYPED A PRINTABLE CHARACTER */
{ /* PERFORM WORD WRAP IF NECESSARY */
if(cursor_col[cursor_window]==79) /* If cursor is at end of line */
{
/* If there is a word to wrap */
if(word_length[cursor_window]>0 && word_length[cursor_window]<78)
{
/* Move cursor to beginning of word */
od_set_cursor(cursor_line[cursor_window],
cursor_col[cursor_window]-word_length[cursor_window]);
od_clr_line(); /* Erase word from current line */
chat_new_line(); /* Move cursor to next line */
/* Redisplay word */
od_disp(current_word[cursor_window],word_length[cursor_window],
TRUE);
cursor_col[cursor_window]+=word_length[cursor_window];
}
else /* If there is no word to "wrap" */
{
chat_new_line(); /* Move cursor to next line */
word_length[cursor_window]=0; /* Start a new word */
}
}
/* ADD CHARACTER TO CURRENT WORD */
/* If there is room for more character in word */
if(strlen(current_word[cursor_window])<79) /* Add new character */
current_word[cursor_window][word_length[cursor_window]++]=key;
/* DISPLAY NEWLY TYPED CHARACTER */
++cursor_col[cursor_window];
od_putch(key);
}
}
}
/* FUNCTION USED BY FULL-SCREEN CHAT TO START A NEW INPUT LINE */
void chat_new_line(void)
{ /* If cursor is at bottom of window */
if(cursor_line[cursor_window]==bottom_line[cursor_window])
{ /* Scroll window up one line on screen */
od_scroll(1,top_line[cursor_window],79, bottom_line[cursor_window],
scroll_distance, 0);
cursor_line[cursor_window]-=(scroll_distance - 1);
}
else /* If cursor is not at bottom of window */
{
++cursor_line[cursor_window]; /* Move cursor down one line */
}
/* Move cursor's position on screen */
od_set_cursor(cursor_line[cursor_window],cursor_col[cursor_window]=1);
od_set_attrib(window_colour[cursor_window]); /* Change text colour */
}
void display_shell_window(void)
{
if((shell_window=od_window_create(17,9,63,15,"DOS Shell",
shell_window_boarder, shell_window_title,
shell_window_text, 0))==NULL) return;
od_set_attrib(shell_window_text);
od_set_cursor(11,26);
od_printf("The Sysop has shelled to DOS");
od_set_cursor(13,21);
od_printf("He/She will return in a few moments...");
}
void remove_shell_window(void)
{
od_window_remove(shell_window);
od_set_cursor(cursor_line[cursor_window],cursor_col[cursor_window]);
od_set_attrib(window_colour[cursor_window]);
}

View File

@ -0,0 +1,578 @@
/* ex_diag.c - Diagnostic door program, written to test environment in which
* an OpenDooors door will run. Reads configuration settings from
* command line and configuration file, and displays diagnostic
* information on the local (and when possible, remote) screens.
*/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "OpenDoor.h"
/******************/
/* Wrapper macros */
/******************/
#if defined(__unix__)
#if !defined(stricmp)
#define stricmp(x,y) strcasecmp(x,y)
#define strnicmp(x,y,z) strncasecmp(x,y,z)
#endif
#endif
typedef enum
{
kParamLocal,
kParamBPS,
kParamPort,
kParamNode,
kParamHelp,
kParamPersonality,
kParamMaxTime,
kParamAddress,
kParamIRQ,
kParamNoFOSSIL,
kParamNoFIFO,
kParamDropFile,
kParamUserName,
kParamTimeLeft,
kParamSecurity,
kParamLocation,
kParamUnknown
} tCommandLineParameter;
char *BoolAsStr(int bValue);
void ParseStandardCommandLine(int nArgCount, char *papszArguments[]);
static void AdvanceToNextArg(int *pnCurrentArg, int nArgCount,
char *pszOption);
static void GetNextArgName(int *pnCurrentArg, int nArgCount,
char *papszArguments[], char *pszString,
int nStringSize);
static tCommandLineParameter GetCommandLineParameter(char *pszArgument);
int main(int argc, char *argv[])
{
char sz[80];
int n;
/* Parse command-line. */
ParseStandardCommandLine(argc, argv);
/* Initialize OpenDoors. */
od_init();
od_clr_scr();
od_printf("OpenDoors has been initialized.\n\r");
for(;;)
{
od_printf("\n\rPOST-INITIALIZATION DIAGNOSTIC INFORMATION:\n\r");
od_printf(" Running in REMOTE mode : %s\n\r",
BoolAsStr(od_control.baud));
od_printf(" Port <-> Modem BPS Rate : %lu\n\r", od_control.baud);
od_printf(" Serial Port Number : %d (COM%d:)\n\r", od_control.port,
od_control.port + 1);
od_printf(" Serial I/O Method : ");
switch(od_control.od_com_method)
{
case COM_FOSSIL:
od_printf("FOSSIL Driver\n\r");
break;
case COM_INTERNAL:
od_printf("OpenDoors Internal I/O Module\n\r");
break;
case COM_SOCKET:
od_printf("TCP Socket/Telnet\n\r");
break;
default:
od_printf("Unknown\n\r");
break;
}
od_printf(" Drop File Type : ");
switch(od_control.od_info_type)
{
case DORINFO1:
od_printf("DORINFO?.DEF\n\r");
break;
case EXITINFO:
od_printf("Basic EXITINFO.BBS & DORINFO1.DEF\n\r");
break;
case RA1EXITINFO:
od_printf("RA 1.x EXITINFO.BBS & DORINFO1.DEF\n\r");
break;
case CHAINTXT:
od_printf("CHAIN.TXT\n\r");
break;
case SFDOORSDAT:
od_printf("SFDOORS.DAT\n\r");
break;
case CALLINFO:
od_printf("CALLINFO.BBS\n\r");
break;
case DOORSYS_GAP:
od_printf("GAP style DOOR.SYS\n\r");
break;
case DOORSYS_DRWY:
od_printf("DoorWay DOOR.SYS\n\r");
break;
case QBBS275EXITINFO:
od_printf("QuickBBS 2.75+ EXITINFO.BBS\n\r");
break;
case CUSTOM:
od_printf("User-Defined Custom Format\n\r");
break;
case DOORSYS_WILDCAT:
od_printf("WildCat! DOOR.SYS\n\r");
break;
case RA2EXITINFO:
od_printf("RA 2.x+ EXITINFO.BBS & DORINFO1.DEF\n\r");
break;
case NO_DOOR_FILE:
od_printf("No Drop File in Use\n\r");
break;
case DOOR32SYS:
od_printf("Door32.sys\n\r");
break;
default:
od_printf("Unknown Type\n\r");
break;
}
od_printf(" ANSI Mode Available : %s\n\r",
BoolAsStr(od_control.user_ansi));
od_printf(" AVATAR Mode Available : %s\n\r",
BoolAsStr(od_control.user_avatar));
od_printf(" RIP Graphics Available : %s\n\r",
BoolAsStr(od_control.user_rip));
od_printf(" User's Time Limit : %d\n\r", od_control.user_timelimit);
od_printf(" User's Full Name : %s\n\r", od_control.user_name);
od_printf("\n\rChoose Option: [E]xit, [T]yping Test,");
if(od_control.od_com_method == COM_INTERNAL)
{
od_printf(" [I]nternal I/O Diags,");
}
od_printf("\n\r");
od_printf(" [A]utodetect ANSI/RIP, [R]e-Display, [D]isplay Tests\n\r");
n=od_get_answer("eitard");
switch(n)
{
case 'e':
od_clr_scr();
od_printf("\n\rExit - Are You Sure (Y/N)? ");
if(od_get_answer("yn") == 'y')
{
return(0);
}
break;
case 'i':
od_clr_scr();
od_printf("INTERNAL SERIAL I/O DIAGNOSTIC INFORMATION:\n\r");
od_printf(" Serial Port Base Address : %x\n\r",
od_control.od_com_address);
od_printf(" IRQ Line Number : %d\n\r",
od_control.od_com_irq);
od_printf(" Receive Buffer Size : %d\n\r",
od_control.od_com_rx_buf);
od_printf(" Transmit Buffer Size : %d\n\r",
od_control.od_com_tx_buf);
od_printf(" Use FIFO Buffer, if avail : %s\n\r",
BoolAsStr(!od_control.od_com_no_fifo));
od_printf(" FIFO Trigger Size : %d\n\r",
od_control.od_com_fifo_trigger);
od_printf("\n\rPress [ENTER] to return.\n\r");
od_get_answer("\n\r");
break;
case 't':
od_clr_scr();
od_printf("\n\rTyping Test - Type any text below:\n\r");
od_printf("[------------------------------------------------------"
"-----------------------]\n\r");
od_input_str(sz, 79, 0, 255);
od_printf("\n\rEntered Text:\n\r%s\n\r", sz);
od_printf("\n\rPress [ENTER] to return.\n\r");
od_get_answer("\n\r");
break;
case 'a':
od_clr_scr();
od_printf("\n\rAutodetecting ANSI/RIP mode ...\n\r");
od_printf("(Detected modes will be turned on.)\n\r");
od_autodetect(0);
od_printf("\n\rDone, press [ENTER] to return.\n\r");
od_get_answer("\n\r");
break;
case 'd':
od_clr_scr();
od_printf("CLEAR SCREEN TEST\n\r");
od_printf("About to test clear screen. The screen should\n\r");
od_printf("be cleared before the next test if screen\n\r");
od_printf("clearing is enabled.\n\r");
od_printf("\n\rPress [ENTER] to perform test.\n\r");
od_get_answer("\n\r");
od_clr_scr();
od_printf("CARRIAGE RETURN TEST:\n\r");
od_printf("This should not be visible\r");
od_printf("This should cover it up...\n\r\n\r");
od_printf("The text \"This should not be visible\" will\n\r");
od_printf("appear above if this test failed.\n\r");
od_printf("\n\rPress [ENTER] to perform next test.\n\r");
od_get_answer("\n\r");
od_clr_scr();
od_printf("COLOR TEST:\n\r\n\r");
for(n = 0; n < 256; ++n)
{
od_set_attrib(n);
od_printf("%x", n % 16);
if(n % 32 == 31)
{
od_set_attrib(0x07);
od_printf("\n\r");
}
}
od_printf("\n\rIf ANSI or AVATAR modes are available, the\n\r");
od_printf("above test pattern should print in color.\n\r");
od_printf("\n\rPress [ENTER] to perform next test.\n\r");
od_get_answer("\n\r");
od_clr_scr();
od_printf("CURSOR POSITIONING TEST:\n\r");
for(n = 15; n > 2; --n)
{
od_set_cursor(n, n);
od_printf("\\");
}
for(n = 15; n > 2; --n)
{
od_set_cursor(n, 17 - n);
od_printf("/");
}
od_set_cursor(17, 1);
od_printf("If ANSI or AVATAR modes are available, a large X\n\r");
od_printf("should appear on lines 3 to 15.\n\r");
od_printf("\n\rPress [ENTER] to return.\n\r");
od_get_answer("\n\r");
break;
}
od_clr_scr();
}
/* Return with success. */
return(0);
}
char *BoolAsStr(int bValue)
{
return(bValue ? "Yes (TRUE)" : "No (FALSE)");
}
void ParseStandardCommandLine(int nArgCount, char *papszArguments[])
{
char *pszCurrentArg;
int nCurrentArg;
for(nCurrentArg = 1; nCurrentArg < nArgCount; ++nCurrentArg)
{
pszCurrentArg = papszArguments[nCurrentArg];
switch(GetCommandLineParameter(pszCurrentArg))
{
case kParamLocal:
od_control.od_force_local = TRUE;
break;
case kParamBPS:
AdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
od_control.baud = atol(papszArguments[nCurrentArg]);
break;
case kParamPort:
AdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
od_control.port = atoi(papszArguments[nCurrentArg]);
break;
case kParamHelp:
printf("AVALIABLE COMMAND LINE PARAMETERS:\n");
printf(" -L or -LOCAL - Causes door to operate in local mode, without requiring a\n");
printf(" door information (drop) file.\n");
printf(" -DROPFILE x - Door information file directory or directory+filename.\n");
printf(" -N x or -NODE x - Sets the node number to use.\n");
printf(" -B x or -BPS x - Sets the serial port <---> modem bps (baud) rate to use.\n");
printf(" -P x or -PORT x - Sets the serial port to use, were 0=COM1, 1=COM2, etc.\n");
printf(" -ADDRESS x - Sets serial port address in decimal NOT hexidecimal\n");
printf(" (only has effect if FOSSIL driver is not being used).\n");
printf(" -IRQ x - Sets the serial port IRQ line (only has effect if FOSSIL\n");
printf(" driver is not being used).\n");
printf(" -NOFOSSIL - Disables use of FOSSIL driver, even if available.\n");
printf(" -NOFIFO - Disables use of 16550 FIFO buffers (only if FOSSIL driver\n");
printf(" is not being used).\n");
printf(" -PERSONALITY x - Sets the sysop status line / function key personality to\n");
printf(" use - one of Standard, PCBoard, RemoteAccess or Wildcat.\n");
printf(" -MAXTIME x - Sets the maximum number of minutes that any user will be\n");
printf(" permitted to access the door.\n");
printf(" -USERNAME x - Name of user who is currently online.\n");
printf(" -TIMELEFT x - User's time remaining online.\n");
printf(" -SECURITY x - User's security level.\n");
printf(" -LOCATION x - Location from which user is calling.\n");
printf(" -?, -H or -HELP - Displays command-line help and exits.\n");
exit(1);
break;
case kParamNode:
AdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
od_control.od_node = atoi(papszArguments[nCurrentArg]);
break;
case kParamPersonality:
AdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
if(stricmp(papszArguments[nCurrentArg], "Standard") == 0)
{
od_control.od_default_personality = PER_OPENDOORS;
}
else if(stricmp(papszArguments[nCurrentArg], "PCBoard") == 0)
{
od_control.od_default_personality = PER_PCBOARD;
}
else if(stricmp(papszArguments[nCurrentArg], "RemoteAccess") == 0)
{
od_control.od_default_personality = PER_RA;
}
else if(stricmp(papszArguments[nCurrentArg], "Wildcat") == 0)
{
od_control.od_default_personality = PER_WILDCAT;
}
else
{
printf("Unknown personality: %s\n", papszArguments[nCurrentArg]);
exit(1);
}
break;
case kParamMaxTime:
AdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
od_control.od_maxtime = atoi(papszArguments[nCurrentArg]);
break;
case kParamAddress:
AdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
od_control.od_com_address = atoi(papszArguments[nCurrentArg]);
break;
case kParamIRQ:
AdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
od_control.od_com_irq = atoi(papszArguments[nCurrentArg]);
break;
case kParamNoFOSSIL:
od_control.od_no_fossil = TRUE;
break;
case kParamNoFIFO:
od_control.od_com_no_fifo = TRUE;
break;
case kParamDropFile:
AdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
strncpy(od_control.info_path, papszArguments[nCurrentArg],
sizeof(od_control.info_path) - 1);
od_control.info_path[sizeof(od_control.info_path) - 1] = '\0';
break;
case kParamUserName:
GetNextArgName(&nCurrentArg, nArgCount, papszArguments,
od_control.user_name, sizeof(od_control.user_name));
break;
case kParamTimeLeft:
AdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
od_control.user_timelimit = atoi(papszArguments[nCurrentArg]);
break;
case kParamSecurity:
AdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
od_control.user_security = atoi(papszArguments[nCurrentArg]);
break;
case kParamLocation:
GetNextArgName(&nCurrentArg, nArgCount, papszArguments,
od_control.user_location, sizeof(od_control.user_location));
break;
default:
printf("Unrecognized command line option: %s\n", pszCurrentArg);
exit(1);
break;
}
}
}
static void AdvanceToNextArg(int *pnCurrentArg, int nArgCount, char *pszOption)
{
if(++*pnCurrentArg >= nArgCount)
{
printf("Missing parameter for option: %s\n", pszOption);
exit(1);
}
}
static void GetNextArgName(int *pnCurrentArg, int nArgCount,
char *papszArguments[], char *pszString,
int nStringSize)
{
int bFirst = TRUE;
if((*pnCurrentArg) + 1 >= nArgCount)
{
printf("Missing parameter for option: %s\n",
papszArguments[(*pnCurrentArg) - 1]);
exit(1);
}
pszString[0] = '\0';
while(++*pnCurrentArg < nArgCount)
{
if(GetCommandLineParameter(papszArguments[*pnCurrentArg])
!= kParamUnknown)
{
--*pnCurrentArg;
break;
}
if(strlen(pszString) >= nStringSize - 1)
{
break;
}
if(!bFirst)
{
strcat(pszString, " ");
}
strncat(pszString, papszArguments[*pnCurrentArg],
strlen(pszString) - nStringSize - 1);
pszString[nStringSize - 1] = '\0';
bFirst = FALSE;
}
}
static tCommandLineParameter GetCommandLineParameter(char *pszArgument)
{
if(*pszArgument == '-' || *pszArgument == '/')
{
++pszArgument;
}
if(stricmp(pszArgument, "L") == 0
|| stricmp(pszArgument, "LOCAL") == 0)
{
return(kParamLocal);
}
else if(stricmp(pszArgument, "B") == 0
|| stricmp(pszArgument, "BPS") == 0
|| stricmp(pszArgument, "BAUD") == 0)
{
return(kParamBPS);
}
else if(stricmp(pszArgument, "P") == 0
|| stricmp(pszArgument, "PORT") == 0)
{
return(kParamPort);
}
else if(stricmp(pszArgument, "N") == 0
|| stricmp(pszArgument, "NODE") == 0)
{
return(kParamNode);
}
else if(stricmp(pszArgument, "?") == 0
|| stricmp(pszArgument, "H") == 0
|| stricmp(pszArgument, "HELP") == 0)
{
return(kParamHelp);
}
else if(stricmp(pszArgument, "PERSONALITY") == 0)
{
return(kParamPersonality);
}
else if(stricmp(pszArgument, "MAXTIME") == 0)
{
return(kParamMaxTime);
}
else if(stricmp(pszArgument, "ADDRESS") == 0)
{
return(kParamAddress);
}
else if(stricmp(pszArgument, "IRQ") == 0)
{
return(kParamIRQ);
}
else if(stricmp(pszArgument, "NOFOSSIL") == 0)
{
return(kParamNoFOSSIL);
}
else if(stricmp(pszArgument, "NOFIFO") == 0)
{
return(kParamNoFIFO);
}
else if(stricmp(pszArgument, "DROPFILE") == 0)
{
return(kParamDropFile);
}
else if(stricmp(pszArgument, "USERNAME") == 0)
{
return(kParamUserName);
}
else if(stricmp(pszArgument, "TIMELEFT") == 0)
{
return(kParamTimeLeft);
}
else if(stricmp(pszArgument, "SECURITY") == 0)
{
return(kParamSecurity);
}
else if(stricmp(pszArgument, "LOCATION") == 0)
{
return(kParamLocation);
}
else
{
return(kParamUnknown);
}
}
void NoDoorFileHandler(void)
{
/* Alter OpenDoors behaviour, so that we proceed with defaults if */
/* no door information file is available, rather than exiting with */
/* an error. Set od_no_file_func to point to this function. */
if(strlen(od_control.user_name) == 0)
{
strcpy(od_control.user_name, "Unknown User");
}
if(strlen(od_control.user_location) == 0)
{
strcpy(od_control.user_location, "Unknown Location");
}
if(od_control.user_timelimit == 0)
{
od_control.user_timelimit = 30;
}
od_control.od_info_type = CUSTOM;
}

View File

@ -0,0 +1,42 @@
/* EX_HELLO.C - Example of a trivial OpenDoors program. Demonstrates */
/* just how simple a fully functional door program can be. Also */
/* shows all the basic elements required by any program using */
/* OpenDoors. See manual for instructions on how to compile */
/* this program. */
/* */
/* This program shows how to do the following: */
/* */
/* - #include the OpenDoors header file, opendoor.h. */
/* - Create a mainline function that can be compiled under */
/* both DOS and Windows versions of OpenDoors. */
/* - How to display text on multiple lines. */
/* - How to wait for a single key to be pressed. */
/* - How to properly exit a program that uses OpenDoors. */
/* The opendoor.h file must be included by any program using OpenDoors. */
#include "OpenDoor.h"
/* The main() or WinMain() function: program execution begins here. */
#ifdef ODPLAT_WIN32
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
#else
int main(int argc, char *argv[])
#endif
{
/* Display a message. */
od_printf("Hello world! This is a very simple OpenDoors program.\n\r");
od_printf("Press any key to return to the BBS!\n\r");
/* Wait for user to press a key. */
od_get_key(TRUE);
/* Exit door program, returning to the BBS. */
od_exit(0, FALSE);
return(0);
}

View File

@ -0,0 +1,153 @@
/* EX_MUSIC.C - Example program plays "Happy Birthday" to the remote user, */
/* if possible. See the manual for instructions on how to */
/* compile this program. */
/* */
/* This program shows how to do the following: */
/* */
/* - Demonstrates how to play sounds effects or music on a */
/* remote terminal program that supports the so-called */
/* "ANSI music" standard. */
/* - Shows how to send text to the remote system without it */
/* being displayed on the local screen. */
/* The opendoor.h file must be included by any program using OpenDoors. */
#include "OpenDoor.h"
#include <string.h>
/* Functions for playing "ANSI music" and testing "ANSI music" capabilities. */
void PlayANSISound(char *pszSounds);
char TestSound(void);
/* Variable indicates whether or not sound is on */
char bSoundEnabled = TRUE;
/* The main() or WinMain() function: program execution begins here. */
#ifdef ODPLAT_WIN32
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
#else
int main(int argc, char *argv[])
#endif
{
/* Handle standard command-line options and perform other needed setup. */
#ifdef ODPLAT_WIN32
od_control.od_cmd_show = nCmdShow;
od_parse_cmd_line(lpszCmdLine);
#else
od_parse_cmd_line(argc, argv);
#endif
/* Display introductory message. */
od_printf("This is a simple door program that will play the song Happy Birthday\n\r");
od_printf("tune on the remote system, if the user's terminal program supports ANSI\n\r");
od_printf("music. Music is not played on the local speaker, as BBS system operators\n\r");
od_printf("do not wish to have the BBS computer making sounds at any time of the day\n\r");
od_printf("or night. However, the program can easily be modified to also echo sound to\n\r");
od_printf("the local speaker.\n\r\n\r");
/* Test whether user's terminal supports "ANSI music". */
TestSound();
/* Send birthday greetings to the remote user. */
/* Clear the screen. */
od_clr_scr();
/* Display a message. */
od_printf("\n\rHappy Birthday!\n\r");
/* If "ANSI music" is available, play "Happy Birthday". */
PlayANSISound("MBT120L4MFMNO4C8C8DCFE2C8C8DCGF2C8C8O5CO4AFED2T90B-8B-8AFGF2");
/* Reset sound after finished playing. */
PlayANSISound("00m");
/* Wait for user to press a key before returning to the BBS. */
od_printf("\n\rPress any key to return to BBS...\n\r");
od_get_key(TRUE);
od_exit(0, FALSE);
return(0);
}
/* Function to test whether the user's terminal program supports ANSI music. */
/* You can either do this every time the user uses your program, or only the */
/* first time they use the program, saving the result in a data file. */
char TestSound(void)
{
/* Variable to store user's response to question. */
char chResponse;
/* Display description of test to user. */
od_printf("We need to know whether or not your terminal program supports ANSI music.\n\r");
od_printf("In order to test this, we will send a short ANSI music sequence. We will then\n\r");
od_printf("ask whether or not you heard any sound.\n\r");
od_printf("Press any key to begin this test... ");
/* Wait for user to press a key to begin. */
od_get_key(TRUE);
od_printf("\n\r\n\r");
/* Temporarily enable sound. */
bSoundEnabled = TRUE;
/* Send sound test sequence. */
PlayANSISound("MBT120L4MFMNO4C8C8DC");
/* Reset sound after finished test. */
PlayANSISound("00m");
/* Clear screen and ask whether user heard the sound. */
od_clr_scr();
od_printf("Did you just hear sound from your speaker? (Y/n)");
chResponse = od_get_answer("YN");
/* Set ANSI music on/off according to user's response. */
bSoundEnabled = (chResponse == 'Y');
return(bSoundEnabled);
}
/* Function to play "ANSI" music or sound effects. The play_sound() function
* can be called with a string of 0 to 250 characters. The caracters of the
* string define what sounds should be played on the remote speaker, as
* follows:
*
* A - G Musical Notes
* # or + Following A-G note means sharp
* - Following A-G note means flat
* < Move down one octave
* > Move up one octave
* . Period acts as dotted note (extend note duration by 3/2)
* MF Music Foreground (pause until finished playing music)
* MB Music Background (continue while music plays)
* MN Music note duration Normal (7/8 of interval between notes)
* MS Music note duration Staccato
* ML Music note duration Legato
* Ln Length of note (n=1-64, 1=whole note, 4=quarter note, etc)
* Pn Pause length (same n values as Ln above)
* Tn Tempo, n=notes/minute (n=32-255, default n=120)
* On Octave number (n=0-6, default n=4)
*/
void PlayANSISound(char *pszSounds)
{
/* Beginning of sound sequence. */
char szStartSound[255] = {27, '[', '\0'};
/* Abort if sound is not enabled. */
if(!bSoundEnabled) return;
/* Send sequence to start playing sound to remote system only. */
od_disp(szStartSound, strlen(szStartSound), FALSE);
/* Send the sounds codes to the remote system only. */
od_disp(pszSounds, strlen(pszSounds), FALSE);
}

View File

@ -0,0 +1,602 @@
/* EX_SKI.C - EX_SKI is a simple but addictive door game that is written */
/* using OpenDoors. In this action game, the player must control */
/* a skier through a downhill slalom course. The user may turn */
/* the skier left or right, and the game ends as soon as the */
/* player skis outside the marked course. The game begins at */
/* an easy level, but quickly becomes more and more difficult */
/* as the course to be navigated becomes more and more narrow. */
/* The game maintains a list of players with high scores, and */
/* this list may be viewed from the main menu. */
/* */
/* This program shows how to do the following: */
/* */
/* - Maintain a high-score file in a game, in a multi-node */
/* compatible manner. */
/* - How to use your own terminal control sequences. */
/* - How to perform reasonably percise timing under both DOS */
/* and Windows. */
/* Header file for the OpenDoors API */
#include "OpenDoor.h"
/* Other required C header files */
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <errno.h>
#include <stdlib.h>
#include "genwrap.h"
/* Hard-coded configurable constants - change these values to alter game */
#define HIGH_SCORES 15 /* Number of high scores in list */
#define INITIAL_COURSE_WIDTH 30 /* Initial width of ski course */
#define MINIMUM_COURSE_WIDTH 4 /* Minimum width of course */
#define DECREASE_WIDTH_AFTER 100 /* # of ticks before course narrows */
#define CHANGE_DIRECTION 10 /* % of ticks course changes direction */
#define MAX_NAME_SIZE 35 /* Maximum characters in player name */
#define WAIT_FOR_FILE 10 /* Time to wait for access to file */
#define SCORE_FILENAME "skigame.dat" /* Name of high score file */
/* High-score file format structure */
typedef struct
{
char szPlayerName[MAX_NAME_SIZE + 1];
DWORD lnHighScore;
time_t lnPlayDate;
} tHighScoreRecord;
typedef struct
{
tHighScoreRecord aRecord[HIGH_SCORES];
} tHighScoreFile;
/* Prototypes for functions defined and used in this file */
FILE *OpenAndReadHighScores(tHighScoreFile *pFileContents);
void CloseHighScores(FILE *pfHighScoreFile);
void WriteHighScores(FILE *pfHighScoreFile, tHighScoreFile *pFileContents);
FILE *OpenExclusiveFile(char *pszFileName, char *pszAccess, time_t Wait);
int FileExists(char *pszFileName);
void ShowHighScores(void);
void PlayGame(void);
void SpaceRight(int nColumns);
void MoveLeft(int nColumns);
int AddHighScore(tHighScoreFile *pHighScores, tHighScoreRecord *pScoreRecord);
/* The main() or WinMain() function: program execution begins here. */
#ifdef ODPLAT_WIN32
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
#else
int main(int argc, char *argv[])
#endif
{
char chMenuChoice;
#ifdef ODPLAT_WIN32
/* In Windows, pass in nCmdShow value to OpenDoors. */
od_control.od_cmd_show = nCmdShow;
#endif
/* Set program's name for use by OpenDoors. */
strcpy(od_control.od_prog_name, "Grand Slalom");
strcpy(od_control.od_prog_version, "Version 6.00");
strcpy(od_control.od_prog_copyright, "Copyright 1991-1996 by Brian Pirie");
/* Call the standard command-line parsing function. You will probably */
/* want to do this in most programs that you write using OpenDoors, as it */
/* automatically provides support for many standard command-line options */
/* that will make the use and setup of your program easer. For details, */
/* run the vote program with the /help command line option. */
#ifdef ODPLAT_WIN32
od_parse_cmd_line(lpszCmdLine);
#else
od_parse_cmd_line(argc, argv);
#endif
/* Loop until the user chooses to exit the door */
do
{
/* Clear the screen */
od_clr_scr();
/* Display program title */
od_printf("`bright white` Ûßß ÛßÜ ÛßÛ ÛÜ Û ÛßÜ Ûßß Û ÛßÛ Û ÛßÛ ÛßÛßÛ\n\r");
od_printf("`bright red`ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ`bright white`ÛßÛ`bright red`Ä`bright white`ÛßÜ`bright red`Ä`bright white`ÛßÛ`bright red`Ä`bright white`Û`bright red`Ä`bright white`ßÛ`bright red`Ä`bright white`Û");
od_printf("`bright red`Ä`bright white`Û`bright red`ÄÄÄ`bright white`ßßÛ`bright red`Ä`bright white`Û`bright red`ÄÄÄ`bright white`ÛßÛ`bright red`Ä`bright white`Û`bright red`ÄÄÄ`bright white`Û");
od_printf("`bright red`Ä`bright white`Û`bright red`Ä`bright white`Û`bright red`Ä`bright white`Û`bright red`Ä`bright white`Û`bright red`ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\n\r");
od_printf("`bright white` ßßß ß ß ß ß ß ß ßß ßßß ßßß ß ß ßßß ßßß ß ß ß\n\r\n\r");
/* Display instructions */
od_printf("`dark green`Prepare yourself for the challenge of Grand Slalom downhill skiing!\n\r\n\r");
od_printf("When `flashing dark green`playing`dark green` the game, press:\n\r");
od_printf("`dark green` [`bright green`Q`dark green`] key to ski left\n\r");
od_printf(" [`bright green`W`dark green`] key to ski right\n\r\n\r");
od_printf("All that you have to do is ski within the slalom course.\n\r");
od_printf("It may sound easy - but be warned - it gets harder as you go!\n\r");
od_printf("(Each time you hear the beep, the course becomes a bit narrower.)\n\r\n\r");
/* Get menu choice from user. */
od_printf("`bright white`Now, press [ENTER] to begin game, [H] to view High Scores, [E] to Exit: ");
chMenuChoice = od_get_answer("HE\n\r");
/* Perform appropriate action based on user's choice */
switch(chMenuChoice)
{
case '\n':
case '\r':
/* If user chooses to play the game */
PlayGame();
break;
case 'H':
/* If user chose to view high scores */
ShowHighScores();
break;
case 'E':
/* If user chose to return to BBS */
od_printf("\n\rGoodbye from SKIGAME!\n\r");
break;
}
} while(chMenuChoice != 'E');
/* Exit door at errorlevel 10, and do not hang up */
od_exit(10, FALSE);
return(1);
}
/* OpenAndReadHighScores() - Opens high score file and reads contents. If */
/* file does not exist, it is created. File is */
/* locked to serialize access by other nodes on */
/* this system. */
FILE *OpenAndReadHighScores(tHighScoreFile *pFileContents)
{
FILE *pfFile;
int iHighScore;
/* If high score file does not exist */
if(!FileExists(SCORE_FILENAME))
{
/* Open and create it */
pfFile = OpenExclusiveFile(SCORE_FILENAME, "wb", WAIT_FOR_FILE);
/* If open was successful */
if(pfFile != NULL)
{
/* Initialize new high score list */
for(iHighScore = 0; iHighScore < HIGH_SCORES; ++iHighScore)
{
pFileContents->aRecord[iHighScore].lnHighScore = 0L;
}
/* Write high score list to the file */
WriteHighScores(pfFile, pFileContents);
}
}
/* If high score file does exit */
else
{
/* Open the existing file */
pfFile = OpenExclusiveFile(SCORE_FILENAME, "r+b",
WAIT_FOR_FILE);
/* Read the contents of the file */
if(fread(pFileContents, sizeof(tHighScoreFile), 1, pfFile) != 1)
{
/* If unable to read file, then return with an error */
fclose(pfFile);
pfFile = NULL;
}
}
/* Return pointer to high score file, if avilable */
return(pfFile);
}
/* FileExists() - Returns TRUE if file exists, otherwise returns FALSE */
int FileExists(char *pszFileName)
{
/* Attempt to open the specified file for reading. */
FILE *pfFile = OpenExclusiveFile(pszFileName, "rb", WAIT_FOR_FILE);
if(pfFile != NULL)
{
/* If we are able to open the file, then close it and return */
/* indicating that it exists. */
fclose(pfFile);
return(TRUE);
}
else
{
/* If we are unable to open the file, we proceed as if the file */
/* doesn't exist (note that this may not always be a valid assumption) */
return(FALSE);
}
}
/* OpenExclusiveFile() - Opens a file for exclusive access, waiting if the */
/* file is not currently available. */
FILE *OpenExclusiveFile(char *pszFileName, char *pszAccess, time_t Wait)
{
FILE *pfFile;
time_t StartTime = time(NULL);
for(;;)
{
/* Attempt to open file */
pfFile = fopen(pszFileName, pszAccess);
/* If file was opened successfuly, then exit */
if(pfFile != NULL) break;
/* If open failed, but not due to access failure, then exit */
if(errno != EACCES) break;
/* If maximum time has elapsed, then exit */
if(StartTime + Wait < time(NULL)) break;
/* Give the OpenDoors kernel a chance to execute before trying again */
od_kernel();
}
/* Return pointer to file, if opened */
return(pfFile);
}
/* CloseHighScores() - Closes the high score file, allowing other nodes on */
/* system to access it. */
void CloseHighScores(FILE *pfHighScoreFile)
{
if(pfHighScoreFile != NULL)
{
fclose(pfHighScoreFile);
}
}
/* WriteHighScores() - Writes the information from pFileContents to the */
/* high score file. */
void WriteHighScores(FILE *pfHighScoreFile, tHighScoreFile *pFileContents)
{
if(pfHighScoreFile != NULL)
{
fseek(pfHighScoreFile, 0L, SEEK_SET);
fwrite(pFileContents, sizeof(tHighScoreFile), 1, pfHighScoreFile);
}
}
/* ShowHighScores() - Called From DoDoor() to display list of high scores */
void ShowHighScores(void)
{
FILE *pfFile;
tHighScoreFile HighScores;
int iHighScore;
struct tm *pTimeBlock;
char szTimeString[34];
/* Clear the screen */
od_clr_scr();
/* Attempt to read high scores from file */
pfFile = OpenAndReadHighScores(&HighScores);
CloseHighScores(pfFile);
if(pfFile == NULL)
{
/* If unable to open high score file, display an error message */
od_printf("`bright red`Unable to access high score file!\n\r");
}
else
{
/* Display header line */
od_printf("`bright green`Player Score "
"Record Date`dark green`\n\r");
od_printf("ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\n\r");
/* Display high scores */
for(iHighScore = 0; iHighScore < HIGH_SCORES; ++iHighScore)
{
/* Exit loop when we have reached the end of the high scores */
if(HighScores.aRecord[iHighScore].lnHighScore == 0L) break;
/* Get local time when player set the high score */
pTimeBlock = localtime(&HighScores.aRecord[iHighScore].lnPlayDate);
strftime(szTimeString, sizeof(szTimeString),
"%B %d, %Y at %I:%M%p", pTimeBlock);
/* Display next high score */
od_printf("%-32.32s %-8ld %s\n\r",
HighScores.aRecord[iHighScore].szPlayerName,
HighScores.aRecord[iHighScore].lnHighScore,
szTimeString);
}
}
/* Display footer line */
od_printf("ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\n\r\n\r");
/* Wait for user to press a key */
od_printf("`bright white`Press [ENTER]/[RETURN] to continue: ");
od_get_answer("\n\r");
}
/* PlayGame() - Called from DoDoor() when user chooses to play a game. */
void PlayGame(void)
{
int nLeftEdge = 1;
int nRightEdge = nLeftEdge + 1 + INITIAL_COURSE_WIDTH;
int nPlayerPos = nLeftEdge + 1 + (INITIAL_COURSE_WIDTH / 2);
long lnScore = 0;
int nDistanceSinceShrink = 0;
int bMovingRight = TRUE;
char cKeyPress;
tHighScoreRecord ScoreRecord;
FILE *pfFile;
tHighScoreFile HighScores;
int nBackup=0;
clock_t StartClock;
/* Clear the Screen */
od_set_color(L_WHITE, B_BLACK);
od_clr_scr();
/* Set current display colour to white */
od_set_attrib(L_WHITE);
/* Re-seed random number generator */
srand((unsigned int)time(NULL));
/* Loop until game is over */
for(;;)
{
StartClock = msclock();
/* Display current line */
if(od_control.user_ansi || od_control.user_avatar)
{
SpaceRight(nLeftEdge - 1);
od_set_color(L_WHITE, D_RED);
od_putch((char)223);
od_repeat((unsigned char)219,
(unsigned char)(nPlayerPos - nLeftEdge - 1));
od_putch((char)254);
od_repeat((unsigned char)219,
(unsigned char)(nRightEdge - nPlayerPos - 1));
od_putch((char)223);
nBackup = nRightEdge - nPlayerPos + 1;
}
else
{
/* If neither ANSI nor AVATAR modes are active, then display */
/* course using plain-ASCII. */
SpaceRight(nLeftEdge - 1);
od_putch((char)(bMovingRight ? '\\' : '/'));
SpaceRight(nPlayerPos - nLeftEdge - 1);
od_putch('o');
SpaceRight(nRightEdge - nPlayerPos - 1);
od_putch((char)(bMovingRight ? '\\' : '/'));
}
/* Loop for each key pressed by user */
while((cKeyPress = (char)od_get_key(FALSE)) != '\0')
{
if(cKeyPress == 'q' || cKeyPress == 'Q')
{
/* Move left */
--nPlayerPos;
}
else if(cKeyPress == 'w' || cKeyPress == 'W')
{
/* Move right */
++nPlayerPos;
}
}
/* Check whether course should turn */
if((rand() % 100) < CHANGE_DIRECTION)
{
bMovingRight = !bMovingRight;
}
else
{
/* If no change in direction, then position moves */
/* Adjust course position appropriately */
if(bMovingRight)
{
++nLeftEdge;
++nRightEdge;
}
else
{
--nLeftEdge;
--nRightEdge;
}
}
/* Check whether course size should shink */
if(++nDistanceSinceShrink >= DECREASE_WIDTH_AFTER)
{
/* Reset distance */
nDistanceSinceShrink = 0;
/* Randomly choose a side to shrink */
if((rand() % 100) < 50)
{
++nLeftEdge;
}
else
{
--nRightEdge;
}
/* Beep when we shrink the size. */
od_printf("\a");
}
/* Change course direction if it collides with edge of screen */
if(nLeftEdge < 1)
{
bMovingRight = TRUE;
++nLeftEdge;
++nRightEdge;
}
else if(nRightEdge > 79)
{
bMovingRight = FALSE;
--nLeftEdge;
--nRightEdge;
}
/* Check that player is still within the course */
if(nPlayerPos <= nLeftEdge || nPlayerPos >= nRightEdge)
{
/* Player has left course - game over! */
od_set_color(D_GREY, D_BLACK);
od_clr_scr();
od_printf("`bright red` !!! Game Over !!!\n\r\n\r");
od_printf("`dark green`You have veered off the course!\n\r\n\r");
od_printf("Your Score is: %ld\n\r", lnScore);
/* Create a score record */
ScoreRecord.lnHighScore = lnScore;
strncpy(ScoreRecord.szPlayerName, od_control.user_name, MAX_NAME_SIZE);
ScoreRecord.szPlayerName[MAX_NAME_SIZE] = '\0';
ScoreRecord.lnPlayDate = time(NULL);
/* Attempt to read high scores from file */
pfFile = OpenAndReadHighScores(&HighScores);
if(pfFile == NULL)
{
/* If unable to open high score file, display an error message */
od_printf("`bright red`Unable to access high score file!\n\r");
}
else
{
/* Check whether user made it to high score list */
if(AddHighScore(&HighScores, &ScoreRecord))
{
od_printf("Congratulations! You have made it to the high score list!\n\r");
/* If so, write the new high score list */
WriteHighScores(pfFile, &HighScores);
}
/* Close and unlock file */
CloseHighScores(pfFile);
}
/* Wait for user to press enter */
od_printf("`bright white`\n\rPress [ENTER]/[RETURN] to return to menu: ");
od_get_answer("\n\r");
return;
}
/* Delay for about 1/10th of a second, to add a constant delay after */
/* each line is displayed that does not depend on the connect speed. */
while(msclock() < StartClock + (((clock_t)MSCLOCKS_PER_SEC) / 10))
od_sleep(0);
/* Increase score */
++lnScore;
/* Replace skiier character with track character */
if(od_control.user_ansi)
{
MoveLeft(nBackup);
od_set_color(L_WHITE, D_GREY);
od_putch((char)178);
od_set_color(L_WHITE, B_BLACK);
}
/* Move to next line */
od_printf("\r\n");
}
}
/* SpaceRight() - Moves right the specified number of columns. In ANSI mode, */
/* uses the move cursor right control sequence. Otherwise, */
/* uses od_repeat(), which is optimized for ASCII and AVATAR */
/* modes. */
void SpaceRight(int nColumns)
{
char szSequence[6];
/* If we don't have a positive column count, then return immediately */
if(nColumns <= 0) return;
/* If operating in ANSI mode */
if(od_control.user_ansi)
{
/* Move cursor right using ESC[nC control sequence */
sprintf(szSequence, "\x1b[%02dC", nColumns);
od_disp_emu(szSequence, TRUE);
}
/* If not operating in ANSI mode */
else
{
od_repeat(' ', (unsigned char)nColumns);
}
}
/* MoveLeft() - Moves the cursor right the specified number of columns. */
/* Intended for use in ANSI mode only. */
void MoveLeft(int nColumns)
{
/* Move cursor left using ESC[nD control sequence */
char szSequence[6];
sprintf(szSequence, "\x1b[%02dD", nColumns);
od_disp_emu(szSequence, TRUE);
}
/* AddHighScore() - Adds a new score to the high score list, if it is high */
/* enough. Returns TRUE if score is added, FALSE otherwise. */
int AddHighScore(tHighScoreFile *pHighScores, tHighScoreRecord *pScoreRecord)
{
int iHighScore;
int iExistingScore;
/* Loop through each existing high score */
for(iHighScore = 0; iHighScore < HIGH_SCORES; ++iHighScore)
{
/* If new score is greater than or equal to this one, then its */
/* position has been found. */
if(pHighScores->aRecord[iHighScore].lnHighScore <=
pScoreRecord->lnHighScore)
{
/* Move remaining scores down one in list */
for(iExistingScore = HIGH_SCORES - 1; iExistingScore >= iHighScore + 1;
--iExistingScore)
{
pHighScores->aRecord[iExistingScore] =
pHighScores->aRecord[iExistingScore - 1];
}
/* Add new score to list */
pHighScores->aRecord[iHighScore] = *pScoreRecord;
/* Return with success */
return(TRUE);
}
}
/* Score did not make it to list */
return(FALSE);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
make -fDOS.mak -DTARGET=h > out.txt

View File

@ -0,0 +1,809 @@
OpenDoors Door Programming Toolkit History
------------------------------------------
This document describes the development history of the OpenDoors door
programming toolkit. This document is divided into two sections. The
first section provides a brief timeline of the OpenDoors releases since
version 1.00. The second section provides detailed information on the
changes and enhancements that were made for each version.
OPENDOORS TIME LINE
-------------------
VERSION RELEASE DATE HIGHLIGHTS
-------------------------------------------------------------------------------
1.00 Fall, 1990 Initial beta version
1.10 Winter, 1991 First public release
1.20 Spring, 1991 Minor enhancments, including RA 1.00 support
1.30 Spring, 1991 A Few bug fixes
1.40 Spring, 1991 Message customizability
2.00 Summer, 1991 AVATAR support, improved ANSI support
2.10 Summer, 1991 Added od_printf() and a new registration key system
2.20 Summer, 1991 Further customizability, DesqView support
2.30 Summer, 1991 Minor bug fix
3.00 Fall, 1991 Beta release, with RA system file support
3.10 Fall, 1991 Public release with bug fixes from 3.00
3.20 Winter, 1992 Support for enhanced FILES.BBS format
3.30 Winter, 1992 Further bug fiexes
3.40 May, 1992 Full locked-BPS rate support
4.00 July, 1992 New manual, inline colour setting with od_printf()
4.10 February, 1993 Configuration file and log file systems
5.00 September, 1994 Built-in serial I/O, multiple compiler support
DETAILED HISTORY OF OPENDOORS EVOLUTION
---------------------------------------
VERSION 1.00 Initial beta test version of the OpenDoors doordriver. Proved to
be very bug-free.
VERSION 1.10 First public release.
VERSION 1.20 Made several changes:
- Support for the new RemoteAccess 1.00 enhanced
exitinfo.bbs file, with many extra pieces of information.
- Added a Alt-K function key to allow the sysop to
temporarily disable the user's keyboard
- Added full support for turning on and off status line.
Status line has been changed slightly in format, and [F9]
help function key added.
- Improved sysop chat mode (added multi-colour and wordwrap)
- Fixed up shell-to-DOS to automatically shell to the
command processor specified in COMSPEC instead of always
using COMMAND.COM. OpenDoors now also returns to system to
the drive and directory it was in before DOS shell was
issued.
- Added support for the new RemoteAccess "sysop next" key.
VERSION 1.30 A few quick changes to perfect all the features of this version
before beginning major development work on OpenDoors 2.00. Fixed
two problems:
- The status line can no longer be turned back on by the
sysop using F1 - F9 keys when a door program has disable
the status line itself.
- A rather major problem was fixed for use of OpenDoors in
conjunction with RA 1.00. We accidentally forgot to save
some of the data that is unused in previous versions, but
is now used in the new version. This bug caused some
unexpected problems, including damage to the USERSXI.BBS
file.
VERSION 1.40 Another maintenance release. This version should now function
perfectly when used in conjunction with older versions of Turbo
C. Other changes in this version include:
- Better error recovery in the case that the door
information file has been damaged.
- OpenDoors was made more customizable, including allowing
the programmer to alter the various OpenDoors messages,
and provisions for user defined function keys for the
sysop. (ie, it is now possible for the programmer to make
Alt-Y another hotkey for the sysop)
VERSION 2.00 Another release, adding a number of new features, such as:
- Added support for AVATAR graphics. OpenDoors will
automatically detect the presence of AVATAR graphics mode
when running under Remote Access, and will allow your door
to toggle it when running under other BBS systems.
- Improved ANSI routines. Added some new functions, and
changed existing functions to send more efficient ANSI
codes in some circumstances.
- The "Sysop Next" key should now work correctly with RA
1.00 and later.
VERSION 2.10 Changes in this version include:
- Implementation of a registration key-code to allow
registered users to more easily upgrade to new versions.
- Added an od_printf() function for ease of formatted output
from within OpenDoors.
VERSION 2.20 More improvements, including:
- Fixing of some minor bugs, such as incorrect handling of
the path to DORINFO1.DEF/EXITINFO.BBS files.
- Added support for more customization, such as hooks for
functions that will be called before and after Shell to
DOS and sysop chat.
- OpenDoors is now DesqView aware. OpenDoors will
automatically detect the presence of DesqView, and uses
the DesqView `virtual screen buffer' for screen display if
present.
- A QuickBBS 2.75 compatibility problem has also been fixed.
VERSION 2.30 Fixed a small bug in the registration system.
VERSION 3.00 A major upgrade, released as a beta-test version, including the
following additions/changes:
- Eliminated many bugs.
- Added support for door information files from: WWIV, PC-
Board, Spitfire, WildCat, GAP, TriTel and others.
- Added .ASC/.ANS/.AVT file display support with automatic
interpretation of QBBS/SuperBBS/RA control characters.
- Added ALT-D key to drop the user back to the BBS without
hanging up.
- Added direct access to RA style configuration, file area,
message area, external protocols, event configuration,
caller history, users online, menu files, user base and
other system files.
- Added complete set of message base manipulation routines,
with full support for the RA 1.01 message base locking
scheme.
- The user manual has also been re-written in order to make
it easier to work with.
VERSION 3.10 The following bug fixes and changes have been made since the
release of the beta version, 3.00:
- Time fields in messages are now correctly formatted
- Corrected a bug in the od_set_attrib function where the
intensity setting would not correctly be transmitted to
the remote when using ANSI graphics.
- Fixed a bug in the re-writing of the DORINFO1.DEF which
cause sysop and user's last names to be corrupted.
- Registered users may now disable the display of copyright
and registration information when the door starts up.
VERSION 3.20 A few more changes and bug fixes were made since version 3.10,
including:
- Fixed the FILES.BBS lister to correctly support FILES.BBS
files located in directories other than the default dir,
and added page pausing to the FILES.BBS lister.
VERSION 3.30 The following changes and bug fixes were made since version 3.20:
- OpenDoors no longer re-writes the DORINFO1.DEF upon
exiting. No BBS's are known to actually make use of the
information changed in DORINFO1.DEF, and re-writing this
file was causing more troubles than it was worth.
- The od_msg_read_hdr() function's NEXT_MESSAGE command now
works correctly.
- Added an od_errno variable to assist in debugging of
programs written with the BBS file engine portion of
OpenDoors.
VERSION 3.40 A minor upgrade version, with the following changes:
- Fixed a compatibility problem with some locked baud rates.
Now, if OpenDoors receives a baud rate the door
information file that is not supported in the FOSSIL
definitions, it will continue without setting the baud
rate. (Whereas before, OpenDoors would report an error and
exit.)
- Made some changes to the manual, and included a utility to
remove the extended-ASCII characters from the manual to
ease printing on some printers.
VERSION 4.00 This version is a major overhaul of the entire OpenDoors package,
including a great many enhancements and additions. As of version
4.00, OpenDoors is available as two separate packages - the door
programming toolkit (this package), and the BBS interface package
(which is available separately) Among the major changes to
version 4.00 of the OpenDoors door programming toolkit are:
- A complete re-organization of the manual, including the
re-writing of a large portion of the manual. In order to
ease printing on some printers, the manual has been re-
formatted in order that it no longer contains extended
ASCII characters. More thorough documentation on the
OpenDoors functions and structures was written, along with
the addition of many more examples. Also added to the
manual are an index, glossary and other features intended
to make the reference manual an even more powerful and
flexible tool.
- Full support for the changes to RemoteAccess 1.10/1.11 has
been added for version 4.00. These include the addition of
some new fields stored in the EXITINFO.BBS door
information file, and proper adjusting of the user's time
remaining online. Version 4.00 also now has full support
for the new QuickBBS-specific EXITINFO.BBS file.
- All of the text displayed by OpenDoors is now fully
customizable using od_control structure variables. This
permits both greater door customization, and adds the
ability to write 100% non-English doors and programs.
- The OpenDoors status lines have been changed. OpenDoors
now provides additional user information through multiple
RemoteAccess-style status lines, accessible through the
F2, F3, etc. keys. Also, the status line may now be turned
off by using the F10 key, allowing the sysop to view all
25-lines of the information displayed by a door program. A
new function od_set_statusline(), permits program
selection of the current status line setting.
- OpenDoors now allows colour codes to be embedded in
od_printf() functions, to eliminate the need for long
chains of alternating od_disp_str(), od_set_colour() /
od_set_attrib() function calls.
- A new formatted input function, od_edit_str() has been
added for use in door programs running in ANSI or AVATAR
graphics mode. The od_edit_str() function features
advanced line editing capabilities which are normally
found only in non-door programs, such as inserting or
deleting text from the middle of a string, moving the
cursor with the arrow keys, and so on. The od_edit_str()
function also provides input formatting, allowing you to
force the user's input into any format you wish, from
phone number formats to date formats to username formats.
The od_edit_str() also provides special modes for
implementing features such as password input, field input
(where the user may move from one field to another using
arrow/tab keys), input field highlighting, editing
existing strings, auto-delete, and much more. The old
od_input_str() function still provides a subset of these
features which do not require ANSI or AVATAR graphics.
- New functions have been added to the door driver module of
OpenDoors. Among these, are an od_putch() function for
displaying one character at a time, and an od_spawn()
function, for easily executing other programs from within
OpenDoors. The od_spawn() function automatically saves the
contents of the current door screen, system drive and
directory, and provides a separate screen on which the
spawned-to program can execute. The od_draw_box() function
allows you to easily display windows in door programs,
using ANSI or AVATAR graphics codes. Also added is are
od_carrier(), od_set_statusline() and od_edit_str()
functions, mentioned elsewhere.
- More changes have been made in order to permit greater
customization and flexibility of OpenDoors. An
od_carrier() function has been added to detect the state
of the carrier detect signal in programs that disable
OpenDoor's internal carrier detection. Also, it is now
possible to shut down OpenDoors without exiting via the
od_exit() function.
- OpenDoors now yeilds the processor to other executing
tasks in multitasking environments (ie. DesqView), when
the door is inactive or waiting for input.
- The door driver function od_clr_scr() now only checks the
user's screen clearing setting if that information is
available from the door information file. If the
information is not available, the od_clr_scr() function
will always clear the screen.
- Many other small changes were also made for version 4.00.
Among these, you now have access to the user's reason for
chat and you can switch the pause and stop keys on and off
during listing of available files or displaying a text
file. Also, previous versions of OpenDoors would read the
user's information from the first door information file
found. Instead, version 4.00 now reads the most recently
created door information file. A bug in the od_clr_line()
function has also been fixed.
VERSION 4.10 A great deal of work has been done between version 4.00 and 4.10
of OpenDoors. This work falls into three major categories: bug
fixes, improved performance, and new features. In fact, enough
changes and improvements have been made that this version really
ought to be numbered 5.00. Below is a summary of the changes that
have occurred since version 4.00:
- Much of the door information file interfacing code has
been revamped, in order that OpenDoors now works correctly
with the newest versions of the BBS packages it supports.
OpenDoors now differentiates between three different
DOOR.SYS formats - the DoorWay format, the PC-Board / GAP
format, and the Wildcat format. Also, the SFDOORS.DAT code
has been fixed to correctly work with the newest version
of Spitfire.
- OpenDoors will now attempt to swap itself and your entire
door program to expanded memory or disk when the sysop
shells to DOS, or when you call one of the od_spawn...()
functions. Memory swapping may be configured in a number
of ways, or even disabled. The OpenDoors swapping code
adds only 2K to the door's .EXE file size.
- OpenDoors now includes a new od_spawnvpe() function. In
addition to the features of the "quick-spawn" od_spawn()
function, od_spawnvpe() also returns the errorlevel the
called program returned, allows you to alter the
environment passed to the child process, and uses the same
parameter format as the C spawnvpe() function. (see page
117)
- The od_page() function now checks the sysop paging hours,
set in the OpenDoors control structure. If the user
attempts to page the sysop outside of the defined paging
hours, he or she will be notified that the sysop is not
available.
- OpenDoors now includes a configuration file sub-system
that you may choose to include in your OpenDoors programs.
This sub-system automatically parses the configuration
file you specify, responding to any of the built-in
configuration commands, and passing configuration options
specific to your program back to you. With only a single
line of code on your part, this sub-system will allow
people running your program to configure many options such
as sysop paging hours, system directories, maximum time
within the door, etc. It also allows the sysop to provide
information that may not be supplied by their particular
BBS software, such as modem settings, the system's name
and so on. In addition to all these built in commands, you
can add your own configuration options, such as display
colours, registration key numbers and other information
needed by your program - without the need to write your
own configuration file parsing routines. (See page 76)
- OpenDoors now supports custom, sysop-defined door
information file (drop file) formats. By defining a custom
door information file format in the cofiguration file,
OpenDoors door programs can now be made to run directly
under BBS packages that use proprietary file formats that
are not directly supported by OpenDoors. (see page 78)
- In order to make doors written with OpenDoors even more
foolproof for the sysop to setup, an intelligent door
information file (drop file) locator has been added.
OpenDoors will automatically search for a door information
file in the directory specified by the configuration file,
the directory specified by your door's source code, the
current directory, and the directory pointed to by the
environment variables used by any of a number of BBS
packages.
- OpenDoors now includes a log file sub-system that you may
choose to include in your programs. The log file system
handles all access and formatting of the logfile, allowing
the programmer to make log file entries by simple function
calls such as od_write_log("User downloading file");.
Also, since the log file system is closely integrated with
the rest of OpenDoors, choosing to include the logfile
system in a program causes OpenDoors to automatically
output the most common logfile entries for events such as
the user paging sysop, the user hanging up, sysop chatting
with the user, user inactivity timeouts, and so on. (see
page 89)
- OpenDoors 4.00 would not always correctly turn on and off
high intensity or flashing colour attributes in ANSI mode.
The ANSI colour handling code has been reworked for
version 4.10, to eliminate these problems.
- An od_get_answer() function has been added, which can be
used to easily permit only certain keys to be pressed in
response to a prompt. For instance, to get a Yes/No
response from the user, use od_get_answer("YN"); (see page
66)
- A popular addition to OpenDoors 4.00 was the ability to
change the current display colour within od_printf()
format strings, using imbedded control characters.
However, the programmer was forced to use a rather cryptic
two-byte control sequence, where the second character of
the sequence contained an 8-bit colour attribute value. It
is now possible to change the display colour within
od_printf() by specifying the names of the desired
foreground and background colours, delimited by a set of
BACK-QUOTE (`) characters. For example:
od_printf("`Red` THIS TEXT IS RED `Blue` THIS TEXT IS BLUE");
od_printf("`Flashing bright green on dark green` AND THIS IS GREEN");
(see page 93)
- Version 4.10 would not correctly "freeze" the user's time
during DOS shell and sysop page operations, when the door
was operating under RemoteAccess 1.11. This has been
fixed.
- A new variable, od_spawn_freeze_time, has been added to
the OpenDoors control structure. When set to FALSE, the
user's time remaining continues to be deducted during the
execution of any of the od_spawn... functions. When set to
TRUE, the user's time remaining is frozen during the
execution of an od_spawn... function.
- The current directory is now correctly restored to its
original setting after the sysop returns from a DOS shell,
and after calls to the od_spawn... functions.
- A number of people were experiencing difficulty using the
od_edit_str() function in version 4.00. A number of
improvements to this function's logic have been made in an
attempt to make od_edit_str() more foolproof to use. Also,
a new flag setting, EDIT_FLAG_LEAVE_BLANK has been added.
However, there were a few reports of problems which we
were not able to reproduce. If you are still having
difficulty with this function, please carefully re-read
the section of the manual pertaining to it's use. In
particular, be sure that your difficulty is not resulting
from the flag settings you are using. If you still suspect
a bug in this function, please include with your bug
report the source code that is causing the problem.
- Page pausing within the od_send_file() and od_list_files()
(FILES.BBS listing routine) functions can now be disabled
and re-enabled by the programmer.
- The "Continue? [Y/n/=]" end of screen prompt and response
keys are now fully customizable.
- The od_list_files() FILES.BBS listing function now works
correctly in all memory models. The function has also been
fixed to correctly handle cases where the trailing
backslash is not supplied in the path parameter.
- The actual BBS line (node) number is now displayed on the
default status line, provided that this information is
supplied by the BBS software.
- It is now possible to detect whether keystrokes originated
from the remote or local keyboard. This is a feature that
is useful in some special applications, such as split-
screen sysop chat programs.
- Version 4.00 would not always correctly display the status
lines, if there was information missing from the
EXITINFO.BBS file. This has been fixed. In addition, the
"next event" information is now correctly displayed on the
status lines. Also, if the user's birthday is available,
their age will also be calculated and displayed on the
status line.
- If you temporarily disable inactivity timeouts, OpenDoors
will no longer automatically trigger and inactivity
timeout as soon as you re-enable this feature.
- A new function, od_hotkey_menu(), has been added to
facilitate displaying a menu with "hot keys". Like the
od_send_file() function, od_hotkey_menu() will display an
ASCII, ANSI or AVATAR file. However, od_hotkey_menu() also
allows you to pass a string listing possible hot keys. If
the user presses any of these keys while the menu is being
displayed, menu display will immediately cease, and the
function will return the key pressed by the user. (See
page 71)
- The od_send_file() (the ASCII/ANSI/AVATAR file display
routine) no longer sends the EOF character if it happens
to exist at the end of a file.
- In addition to the EZVote OpenDoors tutorial door, an
number of other example doors are now included in the
OpenDoors package.
- A few errors have been corrected in the documentation, and
additional information has been added about the new
features in this version.
VERSION 5.00 Version 5.00 represents several major steps forward for
OpenDoors. In addition to numerous bug fixes and minor
improvements, a number of major new features have been added to
this version. These include an optional multiple personality
system which allow the sysop to choose the status line and
function key style they prefer. This version also adds text-mode
support for RIP (Remote Imaging Protocol) graphics, and adds a
group of advanced ANSI/AVATAR/RIP functions for scrolling areas
of the screen, saving and restoring portions of the screen and
creating pop-up windows and menus. Also new in this version is
support for compilers other than Borland/Turbo C(++), such as
compilers from Microsoft. Version 5.00 also adds built-in
communications support, making the use of a FOSSIL driver
optional. Furthermore, direct support for additional BBS systems
has been added. The list below provides more detail of the
changes and new features in version 5.00:
- The nonstop key ([=]) now works correctly during
FILES.BBS listing.
- New door information file formats now supported include:
RA 2.00 EXITINFO.BBS.
- If the TASK environment variable is set, OpenDoors will
now use its value to determine the current node number.
- The od_control.od_spawn_freeze_time variable now works
correctly. Previously, the user's time would always be
frozen during od_spawn...() execution, regardless of the
value of this variable.
- A new feature known as the "Multiple Personality System"
has been added to this version. If you choose to include
the Multiple Personality System in a door, the sysop will
be able to specify which of a number of "personalities"
should be used. Each personality defines the statusline
appearance and function keys seen by the sysop, and has
no effect on the door's operation from the user's
standpoint. OpenDoors 5.00 includes personality
definitions for WildCat, RemoteAccess, PC-Board, and it's
own simplified RA style status lines. You can also define
your own personalities by writing a personality
definition function. If your choose not to include the
Multiple Personality System in a door, you will still be
able to define which single personality you wish
OpenDoors to use.
- This version of OpenDoors can be used with a larger
variety of compilers than where supported by the previous
version. OpenDoors 5.00 is known to work with all
versions of Turbo C, Turbo C++, Borland C++, Microsoft C,
Microsoft C++, Quick C and Visual C++. It should also
work with any other MS-DOS based ANSI C compiler that
supports the Microsoft/DOS .OBJect and .LIBrary file
formats.
- A new diagnostics feature has been added to OpenDoors,
which allows you to determine the reason for the most
recent OpenDoors function failure. When any OpenDoors
function returns a failure condition, it also sets the
new od_control.od_error variable to indicate the reason
for the failure.
- Added additional definitions to OPENDOOR.H, to map names
of OpenDoors functions and variables with the word
"colour" from the U.S. spelling "color". In other words,
both od_set_colour() and od_set_color() are now
recognized by OpenDoors.
- The od_list_files() now supports more intelligent path
specifications. If the parameter to od_list_files() is
NULL or empty, it will search for a FILES.BBS file in the
current directory. If a directory path is specified, it
will look for a FILES.BBS in that directory. If a full
directory and filename are specified, the specified
filename will be used in place of FILES.BBS.
- To save space, the compact memory model library is no
longer included in the normal OpenDoors package. The
compact memory model library is now available seperately.
- A new function, od_set_dtr(), has been added to allow the
DTR line to the modem to be manually controlled. This can
be useful in writing programs where you wish to force the
modem to hangup, such as a call-back verification door.
- Added additional support for various DOS multitasking
environments. OpenDoors is now specifically Microsoft
Windows aware. OpenDoors also now gives up time to other
waiting tasks when it is idle during chat mode.
- The od_edit_str() "M" mode now capitializes a character
following a dash '-' character.
- When transmitting more than one character at a time,
OpenDoors now uses the FOSSIL trasfer block function,
instead of multiple calls to the transfer character
function. This should help to improve performance over
high speed connections when running on slow PCs or under
multitasking environments.
- OpenDoors 4.10 would not correctly change the display
colour from high-intensity back to low-intensity. This
problem has been fixed.
- OpenDoors now recognizes DORINFO?.DEF filenames with
alphabetical identifiers (ie, DORINFOA.DEF thru
DORINFOZ.DEF) for nodes 10 thru 35.
- Improvements have been made to the logfile system. An
exit at errorlevel zero no longer causes garbage to be
written to the logfile. The logfile functions have been
made more reliable when operating under low stack
availability conditions. In the past, if a large number
of local variables where allocated on the stack, the
logfile functions would fail, often writing garbage to
the logfile. When the user pages the sysop for chat, the
user's reason for wishing a chat is also written to the
logfile.
- Support for text-mode RIP (Remote Imaging Protocol)
graphics has been added. Because this version of
OpenDoors always operates in DOS text-mode, none of the
graphics mode RIP features (such as drawing lines,
circles and displaying icons) will appear on the local
screen. Plans for a version of OpenDoors that will
operate in graphics mode and optionally display graphics
locally are currently under consideration. In this
version, RIP support includes a number of new features.
OpenDoors will now recognize the RIP setting passed in an
RA 2.00 EXITINFO.BBS file and WildCat DOOR.SYS file, and
also allows the RIP setting to be specified in a custom
door information file. The od_send_file() and
od_hotkey_menu() functions will now search for files with
.RIP, .AVT, .ANS and .ASC extensions. When displaying RIP
graphics to the remote user, a pop-up window appears on
the local screen, indicating to the sysop which file is
being displayed.
- A set of new functions have been added to permit advanced
screen manipulations. These functions include
od_gettext() and od_puttext() to save and restore
portions of the screen, and od_save_screen() and
od_restore_screen() to save and restore the entire
screen. od_scroll() can be used to scroll any portion of
the screen upwards or downwards. od_save_screen() and
od_restore_screen() will operate in any mode, but the
other functions require ANSI/AVATAR/RIP mode to be
available.
- Three additional functions, od_window_create(),
od_window_remove() and od_popup_menu(), have been added
to facilitate the creation of popup windows and menus.
When such a window or menu is removed from the screen,
the are of the screen "under" the window is returned to
it's original state. This allows you to create multiple
overlapping windows within a door program. The
od_popup_menu() function creates a popup window with a
menu from a simple menu definition string. The user can
select an option from this menu by pressing the key
associated with an option, or by moving a menu selection
bar using their arrow keys. These three functions require
an ANSI/AVATAR/RIP mode to be available.
- A new function, od_chat() has been added, to allow you to
explicitly invoke the OpenDoors chat mode from within
your program.
- A new setting variable, od_control.od_always_clear has
been added. When set to TRUE, od_clr_scr() will always
clear the screen, regardless of the user's screen
clearing setting. When set to FALE, od_clr_scr() will
only clear the screen if the user has screen clearing
enabled.
- It is now possible to configure the errorlevels OpenDoors
exits with under various circumstances, such as when the
user runs out of time remaining online. See the
od_control.od_errorlevel variable
- A new setting variable, od_control.od_force_local, can be
used to easily force OpenDoors to operate in local mode.
Using this variable you can easily add a command line
parameter such as "-local" to allow the sysop to force
your door to operate in local mode. When OpenDoors is
forced into local mode using this variable, it does not
look for a door information file, and uses default
settings for the user's name, etc.
- OPENDOOR.H now sets structure packing to single byte
alignment for the od_control structure when Borland and
Microsoft compilers are being used. In the past,
programmers using OpenDoors have experienced difficulties
the od_control structure when the compiler has been set
to use word packing.
- OpenDoors now closes the FOSSIL driver prior to
performing a spawn or sysop DOS shell. This allows doors
or other communications programs which use the FOSSIL
driver to be executed while the door's execution is
suspended.
- When used with a FOSSIL driver, OpenDoors normally
changes the BPS rate to that passed from the BBS (if the
BBS passes a valid FOSSIL BPS rate). This BPS rate
setting may now be disabled by setting the
DIS_BPS_SETTING bit of the od_control.od_disable
variable.
- A function hook has been added to allow you to install a
function to be called whenever od_kernel() executes
(od_control.od_ker_exec). Another function hook,
od_control.od_time_msg_func, can be installed to override
OpenDoor's time limit warning messages.
- A new array, od_control.od_hot_function, allows the you
to define functions to be called when any of the
programmer-defined sysop hotkeys have been pressed.
- A function hook, od_control.od_no_file_func, has been
added. This function will be called whenever OpenDoors is
unable to find or read a door information file. This
allows you to add your own door information file reader,
or to provide a local login prompt when no door
information file is present.
- Previously, OpenDoors would stop correctly updating the
user's remaining time at midnight when running under
certain BIOSes. This problem has been fixed.
- The current display colour attribute can now be accessed
through an control structure member,
od_control.od_cur_attrib.
- od_send_file() and od_hotkey_menu() no longer pause with
a "Continue?" prompt prematurely in files that have line
lengths greater than 254 characters.
- The local keyboard may now be disabled by setting the
DIS_LOCAL_INPUT bit of od_control.od_disable. This only
affects the sysop's input in circumstances that input is
also accepted from the remote user; this setting has no
effect on the sysop function keys.
A new function hook: -
void (*od_control.od_local_input)(int);
has been added. If set, this function will be called
whenever the sysop presses a non-sysop-function key on
the local keyboard.
- od_control.od_clear_on_exit now controls whether the
screen is cleared before shelling or executing
od_spawn...(), in addition to before OpenDoors shuts
down.
- od_page() now restores the original display colour before
returning.
- It is now possible to display an entire string of
characters with terminal emulation, using the new
function od_disp_emu().
- OpenDoors will now display a small popup window when
disconnecting the current connection.
- A new variable, od_control.od_in_buf_size, can now be set
prior to calling any OpenDoors function to set the size
of OpenDoors combined local/remote keyboard input buffer.
By default, this buffer is 256 bytes in size.
- Previously, there were a number of OpenDoors API
functions that would not correctly initialize OpenDoors
if they were the first function called in the program.
This has been fixed.
- To facilitate setting of bps rates up to 115,200,
od_control.baud is now an unsigned long.
- A new setting, od_control.od_no_ra_codes, has been added
to disable the use of RemoteAccess/QuickBBS control codes
by od_send_file()/od_hotkey_menu()/od_disp_emu(). The
RemoteAccess/QuickBBS ASCII 1 "pause for key" is also now
recognized.

View File

@ -0,0 +1,70 @@
Essentially, the OpenDoors Distribution Network is a list of "official"
OpenDoors distribution sites that will be distributed with future
versions of OpenDoors, and anyone is welcome to participate. The idea
behind the "OpenDoors distribution network" is simply to make it easier
for you, the OpenDoors programmer, to obtain OpenDoors updates. While
the newest version of OpenDoors is always available from the OpenDoors
Support BBS, and often from any system carrying the "Programmer's
Distribution Network", most OpenDoors programmers would find it useful
to know of a system closer to them where the newest version of OpenDoors
is always available. Although I would like to be able to send the newest
version of OpenDoors to any support site, the cost of doing so
unfortunately makes this impossible. However, it is likely that you
would pick up the newest version of OpenDoors when it is available
anyhow, so this shouldn't really make any difference. So, if you are
interested in becoming an official OpenDoors distribution site, simply
fill in the form below, and send it to me, either electronically or by
conventional mail at one of the addresses listed at the end of this
file.
Brian Pirie
OPENDOORS OFFICIAL DISTRIBUTION SITE APPLICATION FORM
-----------------------------------------------------
YOUR NAME : ________________________________________
(eg. Brian Pirie)
LOCATION : ________________________________________
(eg. Ottawa, Ontario, Canada)
DATA NUMBER(S) : ________________________________________
(eg. (613) 526-4466)
NETWORK ADDRESSES: ________________________________________
(eg. 1:243/8 in FidoNet)
MODEM TYPE: ________________________________________
(eg. 9600, V32bis, v42bis, HST)
OTHER INFORMATION: ________________________________________
________________________________________
(eg. Hours of BBS operation, file request hours,
guest login and password, etc.)
I CAN BE INFORMED OF NEW RELEASES BY:
____
| | - ***ROUTED*** FIDONET NETMAIL
|____|
____
| | - OPENDOORS SUPPORT CONFERENCE
|____|
____
| | - INTERNET EMAIL
|____|
____
| | - OTHER: ________________________________
|____|
FidoNet NetMail: 1:243/8
InterNet EMail: brian@bpecomm.ocunix.on.ca
OpenDoors BBS: +1 613 526 4466
Conventional mail: 1416 - 2201 Riverside Drive
Ottawa, Ontario
Canada
K1H 8K9

View File

@ -0,0 +1,170 @@
Below is a list of sites from which the newest version of OpenDoors is
available, as of July 11, 1993, sorted by country. If you would like
to join the list of official OpenDoors distribution systems, please see
the following message.
In addition to the sites listed below, the newest verion of OpenDoors
will likely be available from any system that carries "Programmer's
Distribution Network" files. Also, if you send a self-addressed
envelope, along with either a 3-1/2" or 5-1/4" (360K) diskette, and
$2.00 to cover postage, I would be happy to mail the newest version of
OpenDoors to you. My address is included in the list, below.
Also, the newest version of this file is always available for download
or file request from my system, with the filename OD_SITES.ZIP.
AUSTRALIA
---------
Sydney, Australia - Rosalyn Anderson
Data Number : +61 2 552 3255
Modem : 9600, v.32/PEP
Fidonet : 3:712/618
Intlnet : 58:2100/146
Comments : 24 hours - log on as "opendoors user" password "doors"
Sydney, Australia - Chris Patten
Data Number : +61 2 977 6820
Modem : 14400, v.32bis/v.42bis
Fidonet : 3:714/906
Comments : 24 hours, file request for nodelisted sysops
CANADA
------
Lancaster Park, Alberta, Canada - Thomas King
Data Number : +1 403 973 3856
Modem : 16800, v.32bis/HST/v.42bis
Fidonet : 1:342/49
IMEX : 89:701/513
Worldnet : 62:3200/50
Comments : Freq by Magic name ODOORS 23hrs/day
Guest Name "Visiting Sysop" PW is "PhoneBill"
Saint John, New Brunswick, Canada - George Hannah
Data Number : +1 506 652 7292
Modem : 14400, v.32bis/v.42bis
Fidonet : 1:255/7
Comments : Freq ODOORS, except during ZMH
Login as OPENDOORS password GUEST
Ottawa, Ontario, Canada - Brian Pirie
Data Number : +1 613 526 4466
Modem : 9600, v.32/v.42bis
Fidonet : 1:243/8
Internet : brian@bpecomm.ocunix.on.ca
Postal addr : Brian Pirie
1416 - 2201 Riverside Drive
Ottawa, Ontario
Canada
K1H 8K9
Comments : Freq and BBS available 24 hours / day to everyone
Mascouche, Quebec, Canada - Robert La Ferte
Data Number : +1 514 968 1709
Modem : 14400, v.32bis/v.42bis
Fidonet : 1:167/235
Comments : BBS opened 24 hours a day, 7 days/week,
file request OPENDOORS for the latest version
ITALY
-----
Trieste, Italy - Pietro Budicin
Data Number : +39 40 3783111
Modem : 14400, v.32bis/HST/v.42bis
Fidonet : 2:333/603
Comments : Freq ODOORS and BBS 24hrs/day
NEW ZEALAND
-----------
Paraparaumu, New Zealand - Phill Mckenna
Data Number : +64 4 298 4194
Modem : 14400, v.32bis/v.42bis
Fidonet : 3:771/180
Comments : 24 hour system, magic name ODOORS for file reuquest
Guest User account (no password required)
UNITED KINGDOM
--------------
Cambridge, United Kingdom - Marcel Cook
Data Number : +44 223 301487
Modem : 14400, v.32bis/v.42bis
Fidonet : 2:440/34
Comments : 24 hours for callers and F'REQs, instant registration.
Magic name OPENDOORS gets latest version.
Ipswich, Suffolk, United Kingdom - Mark Clark
Data Number : +44 473 692882
Modem : 14400, v.32bis/v.42bis
Fidonet : 2:440/107
Comments : 24 Hours/Freqs Instant Registration
Ipswich, Suffolk, United Kingdom - Mike Tatum
Data Number : +44 473 87450
Modem : 14400, v.32bis/v.42bis
Fidonet : 2:440/112
Comments : 23 hours a day,
Magic name of OPENDOORS to get latest version online.
Mildenhall, Suffolk, United Kingdom - Dale Elrod
Data Number : +44 638 718623
Modem : 16800, v.32bis/HST/v.42bis
Fidonet : 2:440/37
Comments : 23 hours a day,
magic name of OPENDOORS to get latest version online.
UNITED STATES
-------------
San Jose, California, USA - Darryl Perry
Data Number : +1 408 265 4660
Modem : 9600, v.32/v.42bis
Fidonet : 1:143/324
Comments : Freq the full filename only.
San Ramon, California, USA - Brent Johnson
Data Number : +1 510 830 4616
Modem : 14400, v.32bis/HST
Fidonet : 1:161/610
Comments : 23 hours, FREQ almost anytime if listed in nodelist.
Fort Myers, Florida, USA - Jeff Cochran
Data Number : +1 813 939 3009
Modem : 16800, v.32bis/HST/v.42bis
Fidonet : 1:371/26
Comments : Downloads available first call
Columbus, Georgia, USA - Scott Burkett
Data Number : +1 706 596 8126
Modem : 9600, v.32
Fidonet : 1:3613/12
Comments : 24 Hour Operation and FREQ's
Chicago, Illinois, USA - John Kristoff
Data Number : +1 312 587 8756
Modem : 16800, v.32bis/HST
Fidonet : 1:115/743
Comments : Freq avaiable, 24 hrs., GUEST account available
Baltimore, Maryland, USA - Mike Gurski
Data Number : +1 410 256 1979
Modem : 14400, v.32bis/v.42bis
Fidonet : 1:261/1062
Echonet : 50:5410/1062
Comments : 24 hour FREQs, unlisted systems welcome
Minneapolis, Minnesota, USA - Bing Wu
Data Number : +1 612 378 7783
Modem : 19200, v.32bis/ZYX/v.42bis
Fidonet : 1:282/1016
Comments : 24 hours a day, F'req anytime except ZMH
Muskogee, Oklahoma, USA - Vince Jacobs
Data Number : +1 918 687 1612
Modem : 14400, v.32bis/v.42bis
Fidonet : 1:3813/309
DoorNet : 75:7918/200
Comments : 24 Hours, FREQ hours anytime but ZMH,
Guest Log In as The Inspector, password Gadget

View File

@ -0,0 +1,447 @@
The
OPENDOORS TECH JOURNAL
Volume 93, Number 4 June 21st, 1993
"The Greatest Thing to happen to Journalism Since Real People"
This Issue: A Word from the Editor - Scott Burkett
The Open Door - Brian Pirie
The OPENDOORS Echo
Where's the Source? - John Kristoff
Opendoors Tech Corner - Dropfile Location Logic
Review: BFE v1.30.2à
OpendDoors Snippets!
OpenDoors Roll Call
OpenDoors Distribution Network Sites
OpenDoors Tech Journal Information
----------------------------------------------------------------------------
A Word from the Editor:
----------------------------------------------------------------------------
Another day, another fifty cents. Welcome once again to that info-filled,
free-as-can-be periodical dedicated to the proposition that all C-based door
libraries are not equal!
ODTJ is getting read worldwide. Yup. You know what that means? Aside from
the fact that it provides a wonderful forum for OD coders to share ideas and
information, it provides:
FREE ADVERTISING!
Man! With the distribution we are getting, ODTJ is the perfect place to
advertise that new door! I'll leave the rest up to you guys....
All in all this is a decent issue. It will probably be the last issue before
the 4.20 release of OpenDoors (it should be a doozy). On a side note, our
BBS (Under the Nile) is not running on a USR 14.4 Sportster. Too cool.
That's it. No more words of wisdom this month. No more ranting and raving
on and on about how RIP is inevitably gonna die.... :-)
Alles Klaar und spater!
----------------------------------------------------------------------------
THE OPEN DOOR - By Brian Pirie
----------------------------------------------------------------------------
** Editor's Note **
Has anyone seen this guy? Seriously, rumor has it that Brian is up to some-
thing *BIG*. Of course, once the rumors have been resolved, our readers will
be the first to know! Why? Because we have inquiring minds. Hrmpf! Look
for Brian next month....or the next month....or the.....ad infinitum.
----------------------------------------------------------------------------
OPENDOORS Echo!
----------------------------------------------------------------------------
OPENDOORS is an internationally distributed echo designed for discussion of
BBS door/utility programming, and in particular, Brian Pirie's OpenDoors C
Library!
The OPENDOORS Echo was created by a group of dedicated BBS door and utility
programmers and designers, in order to promote discussions on BBS utility
programming techniques, tasks, standards, and trends. This echo is not just
for BBS door authors! Discussion of practically any aspect of BBS programming
is encouraged. Brian Pirie, the author of OpenDoors is available for tech
support, as are his beta-testers.
The echo is not currently on the FidoNet backbone, but a feed is more than
likely available at your favorite ODN Support Site. Efforts are under way
to put OPENDOORS on the fido backbone...stay tuned!
----------------------------------------------------------------------------
Where's the Source?
----------------------------------------------------------------------------
By: John Kristoff, The Crossroads BBS (1:115/743)
There seems to be a problem with source code for BBS related utilities and
door programs being released. Why is this? I know we have BinkleyTerm,
Maximus and a handful of others, but how many door games do you see that come
with actual source code? I don't think I've seen any. In fact, the only
door program that I've seen the entire source for is Brian's RAVote.
Not that I expect the source code for TradeWars (even if I wanted it), but I
find it surprising that so many door programmers are so greedy. I started
teaching myself C because I'm sick of relying on other authors. I wouldn't
be surprised if many other small time programmers have done the same. I've
always thought that the BBS community, and computer networks in general, are
one of the most free, open and chaotic cultures our planet has ever seen.
So I can't understand why people request $10, $25 or more for a files list
generator, a simple voting booth door or those other 'dime a dozen' programs.
Don't get me wrong, I pay for quality software and I have at least a dozen
shareware programs registered. However, if I was to register every program
I've wanted to use for more than 30 days, I would be in the poor house.
There are just simply too many trivial programs in which I feel their price
isn't justified for lack of programmer committment, exhorborant price, or
just simply the value of the product. I'm not looking for a free ride, but
I am looking for quite a bit more respect from my fellow programmers. For
users, the hobby is relatively cheap, but for sysops, it's a different story.
Well, at least if you're honest. Us sysops have enough to worry about in
terms of phone bills, trouble users, hardware, updates and upgrades... and so
on.
I'm including a text, simliar to this message with all programs I write to
encourage the programmers for sysops to write free or cheap software. I plan
on releasing all my BBS related utilities and door programs as freeware or
public domain (even if that is all they're worth). It's my way of giving
something back to the community that has given me so much. I encourage you
to do the same, or at the very least, with some of your less popular programs.
John Kristoff
The Crossroads BBS
(312) 587-8756
Chicago, IL
FidoNet: 1:115/743
Internet: jkristof@mica.meddean.luc.edu
** Editor's response:
While I am somewhat in agreeance with John on this subject, I must also play
devil's advocate, and come to the aid of door writers who produce solid
products, often without the availability of source. Source code availability
for shareware products is simply not available, for obvious reasons. The
author(s) of the product cannot make source available, as potential customers
could simply recompile the source, and effectively use the software without
properly registering it with the author(s). In my own case, I choose not
to distribute source code for this reason. For smaller, freeware titles, I
suppose I never considered the fact that other programmers would want to
peek at my code. As far as price goes, I have a set $10 registration fee for
all of my door packages, a price which I consider to be extremely low for the
quality of my products.
Very interesting point, John...anyone out there have any feelings on this?
----------------------------------------------------------------------------
OpenDoors Tech Corner: Dropfile Location Logic
----------------------------------------------------------------------------
At this time, OpenDoors searches for the door information file (aka dropfile)
in the following order:
1.) First, if there was a custom door information file format
defined in the OpenDoors configuration file, OpenDoors will
begin by looking for this file. OpenDoors searches for the
custom information file in the following order:
A.) The path defined in the info_path variable
(which can be set by your door code and over-
ridden by the configuration file BBSDir setting)
B.) The directory which was the current default dir
at door startup time
C.) If any of the following environment variables
exist, OpenDoors will then search for the file
in the directories pointed to by these variables,
in the following order:
RA
QUICK
PCB
BBS
2.) If no custom door information file was found / defined,
OpenDoors will then search for door information files
corresponding to one of the built in formats. It will search
for these files in the same directories, and same order, as
it does for the custom door information file (A - C). Within
each directory, it will search for files with the following
filenames:
CHAIN.TXT
SFDOORS.DAT
DOOR.SYS
CALLINFO.BBS
DORINFO1.DEF
DORINFOx.DEF, where x is the node number
set by your program, if
x != 1.
As soon as it finds a directory containing one of these
filenames, OpenDoors will stop it's door information file
search phase. It then begins to decide what to do with what
it has found. If more than one of the above filenames was
found in the directory in question, OpenDoors will read the
file with the most recent date and time stamp. This is intended
to overcome abiguities that can arise when a door information
file conversion program is being used, and a number of
different door information files may still exist in the
directory. In such a case, it is assumed that the most recently
created file is the one that should be used. If more than one
file exist with an identical date and time, OpenDoors will use
the file that is closer to the beginning of the above list. (ie
they are listed in their order of priority)
Once OpenDoors has decided which file it is going to use, it
may have still more decision-making to do. In the case of
door information file names that correspond to more than one
format (such as DOOR.SYS), OpenDoors will examine the file
to determine which format it actually is. If a dorinfo?.def
file is found, OpenDoors will then also search for an
EXITINFO.BBS file. (An EXITINFO.BBS file is always acompanyed
by a DORINFO?.DEF file, as it does not include all the
information needed by even the most basic of doors). Again,
if an EXITINFO.BBS file is found, OpenDoors must determine
which of the many EXITINFO.BBS formats it is actually dealing
with.
This may all sound rather complicated, but it is a well thought-
out strategy that is intended to asure that the correct door
information file will be located and used in the vast majority
of cases. (and to think - it does all this in the blink of an
eye!)
----------------------------------------------------------------------------
REVIEW: BFE v1.30.2à
----------------------------------------------------------------------------
BFE v1.30.2à, the flexible BBS front end system from Cairo Research Labs is
now available! This is an alpha release of the upcoming 1.30 version of
BFE.
BFE is a BBS front-end system that was designed to provide sysops with a
method of running more than one BBS from the same line. In addition, it has
a wealth of other options available to put in on the front-end of your BBS,
such as allowing file transfers, ANSI/ASCII file viewing, shelling to DOS
from remote, running external programs and batch files, and much more!
BFE was designed to be called from a front-end mailer, such as Frontdoor or
Binkleyterm. Instead of spawning directly to the BBS system, it presents
a menu to the user, which details his immediate options. These options can
range from several different BBS systems, remote jobs, literally anything
you can think of! The BFE system can also be configured to be called
straight from your BBS software itself, in essence, running as a normal
door, using one of several popular BBS dropfile formats. Read onward....
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
ܳ Features ³
ÛÀÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
ßßßßßßßßßßßßßß
* Complete support for ANSI/ASCII/AVATAR users (Auto ANSI detect!)
* *TRUE* Multinode/Multiuser Compatibility!
* DESQview aware!
* Configurable for security concerns!
* Custom multi-level menus with item-level password protection!
* Complete carrier monitoring and timeout checking
* Use any of 11 standard dropfiles, or define custom ones!
* Run as a normal door or as a frontend! Dropfile not required!
* Complete BBS carousel - run multiple BBS systems
* ASCII/ANSI/AVATAR file support
* File transfer system with support for external protocols
* Run remote jobs, such as batch files, programs, other doors, etc.
* Remote OS shells!
* Built in chat mode
* Much more!
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
ܳ What's New in This Release? ³
ÛÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ o New * Change ! Fix
ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
o *Major* code cleanup and internal re-documenting and optimizing.
This will be done every periodically in order for the product to
continue to grow.
o New beta naming convention: MAJOR.MINOR.REV (Staging Level)
(i.e. this is 1.30.2à, v1.30, rev. 2, in alpha staging)
o Custom user input using the new PROMPT keyword! Now, you can
utilize custom input as the value for SECONDARY data fields for
*any* menu type in BFE!
o New keywords: NOPASSPARMS and PROCESS. These are used to directly
manipulate the way that BFE performs calls to external processes.
When used with the PROMPT keyword above, just about anything can
be called, in any order, with any arguments!
o The COLOVERRIDE option has been added, to allow each individual
menu option to use its own unique color. This overrides the global
DESCRIPCOL keyword in each .CTL file. (Thanks to Chris Koziol)
o Upload capability now in place! This involved changes to the
PROTOCOL.BFE file, and adding a new type "U" option.
! If BFE cannot locate ASCII/ANSI/AVATAR screens at display time,
it will log an error entry into the logfile, and will no longer
wait for a remote keystroke to continue. (Thanks to R. Guevarra)
o Generic File Transfer System now in place! The new system allows
the use of configurable external protocols (no more hardcoded DSZ!)
o WELCOMESCREEN option added, to provide a global intro screen to be
displayed upon entering the BFE system (shown once only). As with
all of the file display capabilities of BFE, the file can be in
ASCII, ANSI, or in AVATAR formats. BFE will display the one which
best fits the user's terminal settings.
o The "time to next event" option has been put back into the system,
and is now passed via a new "-t" switch. (i.e. -t60, -t%3, etc).
This value is passed to external procedures (Type "R").
* The "O" type (Remote OS Shell) now utilizes the COMSPEC environment
variable to locate the command processor. The command processor
was formerly specified in the SECONDARY field. Previously, if
this value was keyed in wrong, it resulted in BFE locking up
the system. Using COMSPEC should make this a bit cleaner.
o Still more documentation changes!
FREQ: BFE from: Under the Nile! 14.4/v.32 1:3613/12 (706) 596-8126
93K
Scott Burkett,
Cairo Research Labs
----------------------------------------------------------------------------
OPENDOORS SNIPPPPPPPPPETS!!!!!!
----------------------------------------------------------------------------
By: Mark Williamson, Software Solutions (1:214/54)
Here's yet another way to center your favorite text string:
void str_center(int line,char *string,char *color)
{
int col = 40 - (strlen(string) / 2);
/* This method uses the length of the string to center it. So,
you would get strange results if you embedded control codes
in your string.
*/
if(od_control.user_ansi) { // This way allows you to specify
od_set_cursor(line,col); // the line to put the text on.
od_printf(color); // Use the `white on blue` code types
od_disp_str(string);
}
else {
od_repeat(' ',col); // This method uses the CURRENT
od_disp_str(string); // line the cursor happens to be on.
}
return;
}
Mark Williamson
Software Solutions BBS
1:214/54
Lemoore CA
(209)997-0224
v32/v42bis
Open access to first time callers.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
By: Mark Williamson, Software Solutions (1:214/54)
/******************************************************
* fill_box() by Mark Williamson, Software Solutions BBS
* Fidonet 1:214/54, (209)997-0224
*
* This code will paint a box in the
* specified color using the specified
* character using ansi/avatar graphics.
* Note that this does not make a border!
* Only 'fills' a block on the screen.
* Can be used to clear just parts of a screen.
*
* Call the function with the following parameters:
*
* int srow,scol: Starting row,col of the box
* int erow,ecol: Ending row,col of the box
* int attrib: od_set_attrib() style color code
* char fill_char: The character to use to paint the
* block. Use ' ' to clear a block.
*
* This code is placed in the public domain.
******************************************************/
#include <stdio.h>
#include "opendoor.h"
void fill_box(int srow, int scol, int erow, int ecol,
int attrib, char fill_char);
void main(void)
{
fill_box(3,10,13,40,0x1f,'°');
}
void fill_box(int srow, int scol, int erow, int ecol,
int attrib,char fill_char)
{
int line_len,x;
if(srow<1) srow=1;
if(erow>24) erow=24;
if(scol<1) scol=1;
if(ecol>80) ecol=80;
line_len=ecol-scol;
od_clr_scr();
od_set_attrib(attrib);
for(x=srow;x<erow+1;x++) {
od_set_cursor(x,scol);
od_repeat(fill_char,line_len);
}
}
----------------------------------------------------------------------------
OpenDoors Tech Journal Information
----------------------------------------------------------------------------
Editors: Scott Burkett
Under the Nile BBS
1:3613/12@fidonet.org
56:101/2@intlnet.org
(706) 596-8126 14.4
1113 29th Street
Columbus, GA 31902
Brian Pirie
BP ECOMM Systems
1:243/8@fidonet.org
Brian.Pirie@f8.n243.z1.fidonet.org (Internet EMail)
(613) 526-4466 14.4
1416 - 2201 Riverside Drive
Ottawa, Ontario
Canada
K1H 8K9
Published by and for programmers and users of the OpenDoors C Communications
Library and BBS Interface Kit by Pirie Enterprises. It is a compilation of
tips, reviews, and tidbits pertaining to BBS programming and general usage.
The opinions expressed in this publication do not necessarily represent those
of its editors, the OpenDoors author, or other contributors.
OBTAINING COPIES: The latest copy of the OpenDoors Tech Journal will always
be available under the magic name of TECHD (for the DOS version), and TECHW
(for the Windows .WRI version) at both of the systems listed above.
SUBMISSIONS: You are encouraged to submit articles for publication in the
journal. Please send all items to one of the afore-mentioned systems via BBS
upload or mailer file/attach.
----------------------------------------------------------------------------
->< End of The OpenDoors Tech Journal - Volume 93 Issue Number 4 ><-
----------------------------------------------------------------------------

View File

@ -0,0 +1,724 @@
The
OPENDOORS TECH JOURNAL
Volume 93, Number 5 July 20th, 1993
"The Greatest Thing to happen to Journalism Since Real People"
This Issue: A Word from the Editor - Scott Burkett
The Open Door - Brian Pirie (not!)
The Fidonet OPENDOORS Echo - Latest FAQ
Opendoors Tech Corner - ColorToString();
In Search Of - The Art of Debugging
Review: VID v2.01 - The Virus Information Door
OpenDoors Snippets!
OpenDoors Tech Journal Information
----------------------------------------------------------------------------
A Word from the Editor:
----------------------------------------------------------------------------
Finally! After months of long-distance mail polling, the OPENDOORS echo is
now residing on the North American fidonet backbone! Yep. Sorry, Ma Bell.
More on this later, and now .... the rest of the story. Sorry Paul Harvey.
Listen up children, today's editorial survey question is one which is sure to
draw quite a bit of flak from programmers around the globe. Which is the
better stimulant, Jolt Cola or Maxwell House? :-)
DoorNet! That's right. Strange things are amiss at the Circle-K! Look for
an OPENDOORS conference (both mail and file based) to appear soon on the
DoorNet backbone listing. Thanks go out to Vince Jacobs for his work on
getting this implemented. This should make ODTJ and OD distribution a bit
easier on all of us. There has been mention of gating the current fidonet
OPENDOORS echo through to Doornet. I applaud this idea and welcome it with
much grandiose. Ahem.
On another wavelength entirely, several hundred netmail messages were lost
from Under the Nile's mail machine a few weeks ago. Unfortunately, there
were a few requests for product announcements contained therein. If the
authors would be so kind as to send them back in, we will gladly publish
them in the next edition. Danke!
On a serious note, my gerbil died. Peace, and a bottle of hair grease....
(Scott, it's time for your medication....yes, mother)
----------------------------------------------------------------------------
THE OPEN DOOR - By Brian Pirie
----------------------------------------------------------------------------
Unfortunately (I know, I know), Brian was unavailable for this issue. I
finally tracked him down in Tibet, busily polling the local populace for
new ideas for the 4.20 release. At any rate, look for him in ODTJ #6, along
with (hopefully) OpenDoors 4.20... :-)
----------------------------------------------------------------------------
OPENDOORS Echo FAQ - Frequently Asked Questions
----------------------------------------------------------------------------
By: Brian Pirie
July 17th, 1993
ABOUT THIS FAQ
--------------
This document is a collection of frequently asked questions and answers.
If you have any questions about OpenDoors or the OPENDOORS echo, please
first refer to this FAQ. Not only will this help to reduce unnecessary
trafic in the echo, but it will also provide you with the answer to many
questions much more quickly than you would have otherwise.
If you have any suggestions for additions or changes to this FAQ, please
direct them to the moderator, Brian Pirie (FidoNet: 1:243/8, Internet:
brian@bpecomm.ocunix.on.ca).
Since the OPENDOORS echo and this FAQ are currently under a state of
change, this FAQ will be posted on a very regular basis for the time
being. In the future, the FAQ will probably be automatically posted on a
bi-weekly basis.
CONTENTS
--------
1.) What are the rules of the OPENDOORS echo?
2.) What IS OpenDoors?
3.) Where can I get a copy of OpenDoors?
4.) What is the newest version of OpenDoors?
5.) How much does OpenDoors cost?
6.) Is the OpenDoors source code available?
7.) Are there beta test versions of OpenDoors?
8.) How can I contact the author of OpenDoors?
9.) What IS the OpenDoors echo?
10.) What about the echo archives?
11.) How can I get help with OpenDoors or BBS door/utility programming?
12.) What guidelines are there for posting source code?
1.) WHAT ARE THE RULES OF THE OPENDOORS ECHO?
----------------------------------------
The rules of the OPENDOORS echo are few and far between. The most
important rules are those that are standard to all EchoMail conferences
that are distributed as a part of the FidoNet backbone distribution
system. The echo may not be used for illegal purposes, nor is profane
language accepted. Beyond this, your are trusted to use your own
judgement. While it is important to have as high a "signal to noise
ratio" as possible, it is also important to recognize the diverse group
of people you are communicating with though the OPENDOORS echo. There is
a wide range of technical knowledge, knowledge of network etiquette, and
personal background. If you can try to be as understanding and helpful
as possible, your doing so will help to keep friction and flaming to a
minimum.
Since the participants in the OPENDOORS echo are generally all
programmers, it seems natural that they will want to tell the world
about the programs they have written. For this reason, announcements of
new programs - either written with OpenDoors or of interest to the
participants of this echo - is encourage. However, advertising of new
programs is not the primary purpose of the echo. For this reason, we
would ask that you refrain from posting the same advertisment message
more than once within a reasonable length of time (perhaps a month).
If you are having any difficulty with the OPENDOORS echo - technical,
social, or otherwise - please feel more than free to contact the
moderator, Brian Pirie (1:243/8).
2.) WHAT IS OPENDOORS?
-----------------
OpenDoors is a Turbo C(++) / Borland C++ door programming toolkit used
by well over 100 door programmers around the world. OpenDoors handles
all of the details of door programming, such as communicating with the
modem, interfacing with virtually any BBS package, maintaining status
lines, monitoring carrier detect and user timeouts, handling sysop
function keys such as DOS shell or chat, providing advanced ANSI/AVATAR
graphics support, and much more.
OpenDoors is designed to allow you to write door programs just as you
would write any other C program, without requiring any additional effort
or knowledge. You can easily create fully functional door programs with
just a few lines of code. OpenDoors is so easy to use that many
OpenDoors programmers have begun using it with no programming
experience.
OpenDoors directly interfaces with all of the most popular BBS packages
including RemoteAccess, QuickBBS, Telegard, Wildcat, PC-Board, Maximus,
Renegade, EzyCom, RBBS-PC, Spitfire, SuperBBS, RoboBoard, WWIV and many
others. In addition, OpenDoors allows the sysop to specify custom door
information file formats to permit your doors to run on virtually any
BBS system.
Included with OpenDoors are a number of example doors that you can
compile, alter, or use as a basis for your own doors. Among these
example doors are a voting booth type door and an ANSI music
demonstration door, and dozens of sample doors within the door
programming tutorial manual.
OpenDoors also provides a number of special features that you can
optionally include in your doors, such as transparent configuation file
support, logfile support, FILES.BBS listing, and many advanced
ANSI/AVATAR graphics routines.
3.) WHERE CAN I GET A COPY OF OPENDOORS?
-----------------------------------
Below is a short table listing sites from which the newest version of
OpenDoors is available, as of April 19th, 1993. In addition to the sites
listed below, the newest verion of OpenDoors will likely be available
from any system that carries "Programmer's Distribution Network" files.
Also, if you send a self-addressed envelope, along with either a 3-1/2"
or 5-1/4" (360K) diskette, and $2.00 to cover postage, I would be happy
to mail the newest version of OpenDoors to you. My address is listed in
section 8.
Also, the most recent list of OpenDoors distribution sites is always
available for download or file request from my system, in the file
OD_SITES.ZIP. If you are interested in becoming an official OpenDoors
distribution site, please see the file included in the OD_SITES.ZIP
archive.
-------------------------------------------------------------------------------
FIDONET
LOCATION ADDRESS DATA NUMBER MODEM
-------------------------------------------------------------------------------
Sydney, Australia 3:712/618 +61 2 552 3255 (v.32/PEP)
Sydney, Australia 3:714/906 +61 2 977 6820 (v.32bis/HST)
Lancaster Park, Alberta, Canada 1:342/49 +1 403 973 3856 (v.32bis/HST)
Saint John, New Brunswick, Canada 1:255/7 +1 506 652 7292 (v.32bis)
Ottawa, Ontario, Canada 1:243/8 +1 613 526 4466 (v.32)
Mascouche, Quebec, Canada 1:167/235 +1 514 968 1709 (v.32bis)
Trieste, Italy 2:333/603 +39 40 3783111 (v.32bis/HST)
Paraparaumu, New Zealand 3:771/180 +64 4 298 4194 (v.32bis)
Cambridge, United Kingdom 2:440/34 +44 223 301487 (v.32bis)
Ipswich, Suffolk, United Kingdom 2:440/107 +44 473 692882 (v.32bis)
Ipswich, Suffolk, United Kingdom 2:440/112 +44 473 87450 (v.32bis)
Mildenhall, Suffolk, United Kingdom 2:440/37 +44 638 718623 (v.32bis/HST)
San Jose, California, USA 1:143/324 +1 408 265 4660 (v.32)
San Ramon, California, USA 1:161/610 +1 510 830 4616 (v.32bis/HST)
Fort Myers, Florida, USA 1:371/26 +1 813 939 3009 (v.32bis/HST)
Columbus, Georgia, USA 1:3613/12 +1 706 596 8126 (v.32)
Chicago, Illinois, USA 1:115/743 +1 312 587 8756 (v.32bis/HST)
Baltimore, Maryland, USA 1:261/1062 +1 410 256 1979 (v.32bis)
Minneapolis, Minnesota, USA 1:282/1016 +1 612 378 7783 (v.32bis)
Muskogee, Oklahoma, USA 1:3813/309 +1 918 687 1612 (v.32bis)
-------------------------------------------------------------------------------
4.) WHAT IS THE NEWEST VERSION OF OPENDOORS?
---------------------------------------
Version 4.10 is the most recently released version of OpenDoors. There
is a more recent beta-test version of OpenDoors. For information on this
beta-test version, see section 7.
5.) HOW MUCH DOES OPENDOORS COST?
----------------------------
OpenDoors is distributed on a try-before-you-buy basis. You can pickup a
copy of OpenDoors from any of the OpenDoors distribution sites, listed
above, to have a closer look at the package. However, if you wish to
continue using OpenDoors after the three week trial period, you must
purchase an OpenDoors registration. Full details on registering
OpenDoors is included in the OpenDoors manual. However, a brief table
listing the prices within a number of countries is listed below:
-----------------------------------------------
REGISTRATION
REGISTRATION ONLY AND SOURCE CODE
-----------------------------------------------
34 Canadian Dollars 68 Canadian Dollars
28 US Dollars 56 US Dollars
18 British Pounds 36 British Pounds
150 French Francs 300 French Francs
44 German Marks 88 German Marks
50 Netherland Gilders 100 Netherland Gilders
39 Australian Dollars 78 Australian Dollars
-----------------------------------------------
6.) IS THE OPENDOORS SOURCE CODE AVAILABLE?
--------------------------------------
Yes, the OpenDoors source code is available, at a cost equal to the
registration, to registered users. Both the regisration and source code
may also be purchased at the same time, for a cost equal to twice the
normal registration fee. When you purchase the OpenDoors source code,
the most recent version of the source code is sent to directly. Also,
you will be entitled to free upgrades to all future versions of the
source code. Whenever you wish to pick up a new version of the source
code, you may download it from the OpenDoors support BBS, arrange to
pick it up via a FidoNet-compatible mailer (simply send me a message
asking me to place the source code package "on hold" for you to poll and
pick up), or by sending a diskette and self-addressed diskette mailer.
7.) ARE THERE BETA TEST VERSIONS OF OPENDOORS?
-----------------------------------------
Yes. The beta test versions of OpenDoors are available to registered
OpenDoors users. However, keep in mind that the beta test version has
some new features that are still under development, and has not yet been
thoroughly tested. To save space, the documentation is not included with
the beta test version. As such, it is assumed that you also have the
most recent non-beta version of OpenDoors. The most recent beta version
may be file-requested from 1:243/8 as OD_BETA
8.) HOW CAN I CONTACT THE AUTHOR OF OPENDOORS?
-----------------------------------------
If you wish to contact the author of OpenDoors, Brian Pirie, please feel
free to do so. I may be reached by any of the following means:
FidoNet NetMail : 1:243/8
Internet EMail : brian@bpecomm.ocunix.on.ca
Modem (BBS) : +1 613 526 4466
Conventional Mail : Brian Pirie
Apt. #1416 - 2201 Riverside Drive
Ottawa, Ontario
K1H 8K9
Canada
9.) WHAT IS THE OPENDOORS ECHO?
--------------------------
The OPENDOORS echomail conference is devoted to OpenDoors and BBS door /
utility programming in general. The OPENDOORS echo serves as a place
where people working with OpenDoors can share ideas, source code
examples, and other tricks and techniques. Through the OPENDOORS echo
you can receive help with OpenDoors and programming in general. Also
available through the OPENDOORS echo is information on future versions
of OpenDoors and recent developments of concern to BBS door and utility
programmers. The OPENDOORS echo is also place for suggestions for future
versions of OpenDoors, OpenDoors bug reports, a place to announce the
availablility of your programs, and much more information of interest to
OpenDoors programmers. There are participants in the OpenDoors echo from
throughout Canada and the U.S., as well as people in Europe and
Australia.
10.) WHAT ABOUT THE ECHO ARCHIVES?
----------------------------
Although we attempt to answer the most commonly asked questions in this
FAQ, there is so much discussed in the OPENDOORS echo that it is
impossible to address every possible question. As such, you may be
interested in referring to the OPENDOORS echo archives, in order to
learn more about OpenDoors and BBS door/utility programming in general.
The OPENDOORS echo archives are prepared on a monthly basis, and
are available from the moderators system. Currently, the following
archives are available for request from 1:243/8 or download from the BBS
at +1 613 526 4466:
ODJUL92.ZIP 42776 Discussion from the OpenDoors echo, July '92
ODAUG92.ZIP 35432 Discussion from the OpenDoors echo, August '92
ODSEP92.ZIP 36308 Discussion from the OpenDoors echo, September '92
ODOCT92.ZIP 30922 Discussion from the OpenDoors echo, October '92
ODNOV92.ZIP 34844 Discussion from the OpenDoors echo, November '92
ODDEC92.ZIP 53647 Discussion from the OpenDoors echo, December '92
ODJAN93.ZIP 24683 Discussion from the OpenDoors echo, January '93
ODFEB93.ZIP 41562 Discussion from the OpenDoors echo, February '93
ODMAR93.ZIP 24080 Discussion from the OpenDoors echo, March '93
ODAPR93.ZIP 30027 Discussion from the OpenDoors echo, April '93
ODMAY93.ZIP 39440 Discussion from the OpenDoors echo, May '93
ODJUN93.ZIP 56615 Discussion from the OpenDoors echo, June '93
11.) HOW CAN I GET HELP WITH OPENDOORS OR BBS DOOR/UTILITY PROGRAMMING?
-----------------------------------------------------------------
If you have any problems with a program, please feel more than free to
post a message here, asking for help. Afterall, that is one of the
central purposes of this echo. However, try to keep the following points
in mind when asking a question. Doing so will help others to better
understand your problem, and as such will help them help you.
A.) If you are having a problem with a program, try to
describe as much about the problem as possible. If you
can, precisely how to reproduce the problem. If you wish
to do so, posting source code can also be of great
advantage. For more information on posting source code in
the echo, please see section 12.
B.) Explain what steps you have already taken in trying to
solve your problem. This will allow others to pick up from
where you have become "stuck", and not suggest solutions
that you have already tried yourself.
12.) WHAT GUIDELINES ARE THERE FOR POSTING SOURCE CODE?
-------------------------------------------------
You are more than welcome to post source code in this echo. If you do
so, please keep the following guidelines in mind.
A.) Unless you explicitly say otherwise, any source code
posted in this echo will be considered to be released to
the public domain. If you have some source code that you
do not wish others to copy, don't post it here!
B.) For your source code to be useful to others, it has to be
understandable. Adding comments can be of great benifit to
someoone trying to understand your code.
C.) If you are posting a program written with OpenDoors,
please be sure that you do NOT include your registration
key in the source code!
----------------------------------------------------------------------------
OpenDoors Tech Corner: ColorToString()
----------------------------------------------------------------------------
Authored by: Brian Pirie, OpenDoors author
/* Function to convert an integer color attribute to an OpenDoors */
/* style color description string, in the format: */
/* */
/* [Flashing] [Bright] [Foreground] on [Background] */
/* */
/* The function takes two parameters, an unsigned integer */
/* representing the input color, and a pointer to a string where */
/* the colour description should be output. Be sure that this */
/* string is large enough to hold the largest possible color */
/* description string. (If the code is not altered, the largest */
/* possible string will be 35 characters, including the null */
/* terminator */
void ColorToString(unsigned int color, char *outString)
{
/* Array containing names of various colors */
static char colorString[8][33]={"Black",
"Blue",
"Green",
"Cyan",
"Red",
"Magenta",
"Yellow",
"White"};
/* Initialize string */
outString[0]='\0';
/* If flashing bit is set, output "Flashing" string + space */
if(color & 0x80) {
strcat(outString, "Flashing ");
}
/* If bright bit is set, output "Bright" string + space */
if(color & 0x08) {
strcat(outString, "Bright ");
}
/* Output foreground color */
strcat(outString, colorString[color & 0x07]);
/* Output the word "on" with a space before & after */
strcat(outString, " on ");
/* Output background color */
strcat(outString, colorString[(color & 0x70) >> 4]);
}
Editor's Note: Brian was kind enough to put this function together for us
upon request for a function to perform the reverse of the od_color_config()
function. I had to add a bracket or two that was left out (he did mention
that it was untested code!), but it works like a champ.
----------------------------------------------------------------------------
In Search Of - The Art of Debugging
By Mark Williamson
----------------------------------------------------------------------------
It happens. The inevitable. You have spent so many hours trying to
write the most optimized, cleanest code possible. But your best efforts
are laid to rest when some verocious little creature pops up, seemingly
at random, and wreaks havoc on all your efforts.
What causes these bugs to appear? Can it be programming style? Or a
forgotten temporary variable? Where, or where, is that bug!
If this has happened to you, don't feel bad. 50 percent of your time
programming will be devoted to the debugging cycle. Many books have
been written that are devoted to the art of programming style, debugging
and the development cycle. I will only touch on a couple of pointers to
get you started in the right direction in locating that invisible target
called so affectionately, the "bug."
Case scenario: I was working on a program that would shell to DOS using
one of the OD_SPAWN... functions. OPENDOOR.DOC discusses in
good detail how to use either of these functions. But, being the eager
programmer that I am, I happily went about my way after I read what I
thought I needed to know. The program in question uses a temporary
directory to store files extracted from .ZIP/.ARJ/etc.. archive files.
As the program was running, it worked just great. Unpacked the files
using PKZIP. Repacked them using ARJ.
Then I tried it again. That's when it all fell apart for me.
Unwillingly, I just started a four-day straight debugging session,
lasting until the wee hours of the night.
Point one: Always read the docs...thoroughly!
During this four day debugging frenzy I removed 20 or more variables I
didn't need, rewrote five functions to be more independent and portable
(ie modular programming) and greatly optimized the program overall.
But I still couldn't find the bug.
Here's a sample of the code:
od_set_cursor(15,20);
od_printf("`bright cyan`Unpacking");
error=run_it(progname,unpackcommand); // see the run_it function
// below.
if(error==0){
od_set_cursor(15,33);
od_printf("`bright green`ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ `bright cyan` Ok ");
}
The above code did not do as it appears it should. In fact, as soon as
the trace feature of Turbo C++ 3.0 hit the line that prints out the bar
and the word "Ok", what actually was printed out was something like
this:
Unpacking :\BBSFILES\BBSUPLOADS\CHKZIP.ZIP
but not:
Unpacking ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ Ok
Now remember, I hadn't read the section on the od_swapping_path variable
yet.
The OD_SPAWN.. functions will swap to either EMS memory or DISK. The
variable od_control.od_swapping_path is empty by default, which equates
to the CURRENT DIRECTORY!. Thus, when my utility unpacked/repacked the
files, it packed up the swap file also. Then, when I ran it the second
and future times on the same archive file, I was overwriting the swap
file! Effectively overwriting the program's data and code segments.
Lesson learned: Read the docs..first. Don't use the old tried and
untrue "If all else fails, read the docs." Read them first. Read them
several times.
How to debug:
If your compiler has a trace feature, use it.
Put all the variables in the watch window that could possibly have any
bearing on the function your are testing. Look for suspicious changes
in values when the variable has not been 'touched'.
Minimize global variable useage. This makes portability difficult. If
you write functions that do not rely on any outside information except
that which is passed as an parameter, then it will be much easier to use
the same functions over and over, throughout many of your projects.
Use descriptive variables. C gives you much luxury in the length of
your variable names. Use this to the max. How many times have you
scratched your head and wondered "what does this one do?"
Use descriptive function names. See above
Read other programmer's source for ideas. Many times you will probably
be reinventing the wheel. Read the C snippets for ideas. Check out
some other source code to see how it's done elsewhere. This may give
you much needed insight into the art of programming style.
And last but not least.. Use comment lines! Don't be vague. Commenting
your source code will most likely help only one person. You. But, you
are the only one that matters anyway right?
Good luck and press on!
Mark Williamson
Software Solutions
Fido 1:214/54
Home of Labtest 2.00 - The Definitive Upload Processor
Written entirely in Turbo C++ 3.0 using Brian Pirie's Open Doors 4.1
----------------------------------------------------------------------------
REVIEW: VID v2.01
----------------------------------------------------------------------------
VID v2.01, the BBS Virus Information Door from Cairo Research Labs, is now
available!
The original VID was designed to provide a quick online virus reference for
BBS users, but has quickly evolved into quite a bit more! Thanks to a
tremendous response from Sysops around the world, VID has provided BBS users
with quick, accurate viral assessments while online on their favorite BBS
system.
What's New in This Release?
o Over 100 new viruses added, bringing the total up to 1,557 entries.
o Cleaned up display in several of the search and list options,
including multi-column virus listings (Thanks to Chris Koziol).
o Provided an option for online documentation for end-users.
* Due to an internal problem in the original 2.00 release, you must
use v2.01+ to use any new enhancement modules. The database
structures have changed a bit.
* The periodic VID integrity check has been enhanced. VID now
stores its integrity information in a file called SANITY.CHK.
Ensure that this file resides in the VID directory!
* In the 2.00 release, the VIDDEF.TBL file had to reside in the
path. This was causing a message subsystem initialization error
if VID could not locate this file in the path! VID now looks in
the current directory first. (Thanks to Steve Pepin)
! In the Behavior search, although the default answer is "Ignore",
the prompt showed the default as "No". Fixed! (Steve Pepin).
! If VID was typed alone with no arguments, the old switches from
the 1.10 release were displayed! Fixed! (Steve Pepin, again!).
! VID now handles extraneous spaces in registration keys. This
occurred when clipping a key from a netmail message. Squashed!
(Thanks to Bart Holiman).
! In the 2.0 datafiles, the "Stealth" flag on several viruses was
not set properly. Squashed!
FREQ: VID - This will get you the VID engine, documentation, Lite-level
database, and any release notes. 165K in size (VID201.ZIP).
VIDPLUS - This will get you the VID+ modules. You must have the VID
engine (above) for this to be functional! This expands
to around 1.5MB or so. 323K in size (VP0793.ZIP).
FROM - Under the Nile BBS, 1:3613/12, 14.4 USR
(706) 596-8126
---------------------------------------------------------------------------
OPENDOORS SNIPPPPPPPPPETS!!!!!!
----------------------------------------------------------------------------
By : Mark Williamson
The previous post of this code had a little error. In the fill_box()
function, remove the od_clr_scr(). I had put that in for test purposes. Sorry
bout that!
/********************************************************************/
I would like to submit this code for the next issue of ODTJ. Please
post my name and bbs info in the ODTJ with this code:
/******************************************************
* fill_box() by Mark Williamson, Software Solutions BBS
* Fidonet 1:214/54, (209)997-0224
*
* This code will paint a box in the
* specified color using the specified
* character using ansi/avatar graphics.
* Note that this does not make a border!
* Only 'fills' a block on the screen.
* Can be used to clear just parts of a screen.
*
* Call the function with the following parameters:
*
* int srow,scol: Starting row,col of the box
* int erow,ecol: Ending row,col of the box
* int attrib: od_set_attrib() style color code
* char fill_char: The character to use to paint the
* block. Use ' ' to clear a block.
*
* This code is placed in the public domain.
******************************************************/
#include <stdio.h>
#include "opendoor.h"
void fill_box(int srow, int scol, int erow, int ecol,
int attrib, char fill_char);
void main(void)
{
fill_box(3,10,13,40,0x1f,'°');
}
void fill_box(int srow, int scol, int erow, int ecol,
int attrib,char fill_char)
{
int line_len,x;
if(srow<1) srow=1;
if(erow>24) erow=24;
if(scol<1) scol=1;
if(ecol>80) ecol=80;
line_len=ecol-scol;
/* od_clr_scr(); OOPS! TAKE THIS LINE OUT */
od_set_attrib(attrib);
for(x=srow;x<erow+1;x++) {
od_set_cursor(x,scol);
od_repeat(fill_char,line_len);
}
}
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
// The following function provided by Brian Pirie
// during a telephone conversation with Brian and myself
//
// Arguments: Prog - the path/filename of the program to run
// command_line - path/filename of the program and any
// command line arguments the program needs.
//
// Example: prog = "PKUNZIP"
// command_line = "PKUNZIP TESTFILE.ZIP"
//
// Return value: errorlevel of child process
int run_it(char *prog,char *command_line)
{
char *arg[3];
arg[0]=prog;
arg[1]=command_line;
arg[2]=NULL;
strcpy(arg[1],strshl(arg[1],strlen(prog)));
return(od_spawnvpe(P_WAIT,prog,arg,NULL));
}
----------------------------------------------------------------------------
OpenDoors Tech Journal Information
----------------------------------------------------------------------------
Editors: Scott Burkett
Under the Nile BBS
1:3613/12@fidonet.org
Scott.Burkett@f12.n3613.z1.fidonet.org (Internet EMail)
(706) 596-8126 14.4 USR
1113 29th Street
Columbus, GA 31902
Brian Pirie
BP ECOMM Systems
1:243/8@fidonet.org
brian@bpecomm.ocunix.on.ca (Internet EMail)
(613) 526-4466 14.4
1416 - 2201 Riverside Drive
Ottawa, Ontario
Canada
K1H 8K9
Published by and for programmers and users of the OpenDoors C Communications
Library and BBS Interface Kit by Pirie Enterprises. It is a compilation of
tips, reviews, and tidbits pertaining to BBS programming and general usage.
The opinions expressed in this publication do not necessarily represent those
of its editors, the OpenDoors author, or other contributors.
OBTAINING COPIES: The latest copy of the OpenDoors Tech Journal will always
be available under the magic name of TECHD (for the DOS version), and TECHW
(for the Windows .WRI version) at both of the systems listed above.
SUBMISSIONS: You are encouraged to submit articles for publication in the
journal. Please send all items to one of the afore-mentioned systems via BBS
upload or mailer file/attach.
----------------------------------------------------------------------------
->< End of The OpenDoors Tech Journal - Volume 93 Issue Number 5 ><-
----------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,173 @@
----------------------------------------------------------------------------
The OpenDoors Rollcall!
----------------------------------------------------------------------------
The OpenDoors Roll Call is a compilation of BBS utilities and doors that were
authored using Brian Pirie's OpenDoors package. If you would like to see
your products listed in this section, send the following information to either
Brian Pirie or myself (via netmail, echomail, or snailmail):
Product Name
Author Name
Description
Price
FREQ Address/BBS Number
FREQ Name
Latest Version
----------------------------------------------------------------------------
Auto-Message
------------
Author(s): Vince Jacobs - Lone Wolf Software
Version:
Requestable from:
Freq name:
Description: Message to next caller door.
Price:
BFE (BBS Front End System)
--------------------------
Author(s): Scott Burkett - Cairo Research Labs
version: 1.30.2à
Requestable from: 1:3613/12
Freq name: BFE
Description: Complete BBS carousel, front end menu builder, remote jobs, etc
Price: $10
BID (BBS Information Door)
--------------------------
Author(s): Brian Pirie - Pirie Enterprises
version: 2.00
Requestable from: 1:243/8
Freq name: BID
Description: A door to introduce new BBS users to the world of BBSing
Price: Freeware
CALL-BACK
---------
Author(s): Don Laverdure
version: 4.02
Requestable from: 1:249/124
Freq name: CB-402.ARJ
Description: Callback verifier door for RA/SBBS/QBBS systems
Price: unknown/Shareware
EZVote
------
Author(s): Brian Pirie - Pirie Enterprises
version: 4.10
Requestable from: 1:243/8
Freq name: EZVOTE
Description: A user voting door for use with most BBS systems
Price: Freeware
Flame-Thrower
-------------
Author(s): Vince Jacobs - Lone Wolf Software
Version:
Requestable from:
Freq name:
Description: Users leave next caller a flaming one-liner.
Price:
Node-Door
---------
Author(s): Don Laverdure
Version: 2.11
Requestable from: 1:249/124
Freq name: ND-211.ARJ
Description: Nodelist browser door for raw nodelists.
Price: unknown/Shareware
RegPRO
------
Author(s): Scott Burkett - Cairo Research Labs
Version: 2.60
Requestable from: 3613/12
Freq name: REGPRO
Description: Online BBS Fullscreen Entry Form/User Questionnaire System
Price: $10/Shareware
ROBO TAPE
---------
Author(s): Vince Jacobs - Lone Wolf Software
Version: 2.00
Requestable from: 1:3813/309, 62:9600/0, 75:400/0 Anytime But ZMH.
Freq name: ROBOT200.ARJ
Description: BBS Tape Access Door
Price: $10/Shareware
TBM (Turbo Bulletin Manager)
----------------------------
Author(s): Scott Burkett - Cairo Research Labs
Version: 2.50
Requestable from: 3613/12
Freq name: TBM
Description: BBS Bulletin Manager/Tons of features/Most BBS Systems
Price: $10/Shareware
Tic-Tac-Toe
-----------
Author(s): Vince Jacobs - Lone Wolf Software
Version:
Requestable from:
Freq name:
Description: Plays just like the real thing.
Price:
Triple Dare
-----------
Author(s): Vince Jacobs - Lone Wolf Software
Version:
Requestable from:
Freq name:
Description: Try and outdraw the dealer! Great graphics.
Price:
Turbo Poll
----------
Author(s): Vince Jacobs - Lone Wolf Software
Version:
Requestable from:
Freq name:
Description: Very graphical voting booth door
Price:
Turbo Quotes
------------
Author(s): Vince Jacobs - Lone Wolf Software
Version:
Requestable from:
Freq name:
Description: Randomly displays quotes to users
Price:
Users-Info
----------
Author(s): Vince Jacobs - Lone Wolf Software
Version:
Requestable from:
Freq name:
Description: Displays Exteneded Info about users and prints it out.
Price:
VID (Virus Information Door)
----------------------------
Author(s): Scott Burkett - Cairo Research Labs
Version: 2.00
Requestable from: 3613/12
Freq name: VID and VIDPLUS (Enhancement Module)
Description: Online Virus Reference Database for most BBS types
Price: $10/Shareware
VKill
-----
Author(s): Scott Burkett - Cairo Research Labs
Version: 3.00a
Requestable from: 1:3613/12
Freq name: VKILL
Description: Upload Integrity Door for Maximus CBCS
Price: $10/Shareware

View File

@ -0,0 +1,25 @@
/* MSC / BC compatible findfirst()/findnext() definitions. */
#ifdef __TURBOC__
#include <dir.h>
#include <dos.h>
#else
#include <dos.h>
struct ffblk
{
char ff_reserved[21];
char ff_attrib;
unsigned ff_ftime;
unsigned ff_fdate;
long ff_fsize;
char ff_name[13];
}
#define findfirst(p, f, a) _dos_findfirst(p, (struct _find_t *)f, a)
#define findnext(f) _dos_findnext((struct _find_t *)f)
#define FA_RDONLY _A_RDONLY
#define FA_HIDDEN _A_HIDDEN
#define FA_SYSTEM _A_SYSTEM
#define FA_LABEL _A_VOLID
#define FA_DIREC _A_SUBDIR
#define FA_ARCH _A_ARCH
#endif

View File

@ -0,0 +1,342 @@
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "opendoor.h"
#include "cmdline.h"
#ifndef BOOL
typedef int BOOL;
#endif
typedef enum
{
kParamLocal,
kParamBPS,
kParamPort,
kParamNode,
kParamHelp,
kParamPersonality,
kParamMaxTime,
kParamAddress,
kParamIRQ,
kParamNoFOSSIL,
kParamNoFIFO,
kParamDropFile,
kParamUserName,
kParamTimeLeft,
kParamSecurity,
kParamLocation,
kParamUnknown
} tCommandLineParameter;
static void AdvanceToNextArg(int *pnCurrentArg, int nArgCount,
char *pszOption);
static void GetNextArgName(int *pnCurrentArg, int nArgCount,
char *papszArguments[], char *pszString,
int nStringSize);
static tCommandLineParameter GetCommandLineParameter(char *pszArgument);
void ParseStandardCommandLine(int nArgCount, char *papszArguments[])
{
char *pszCurrentArg;
int nCurrentArg;
for(nCurrentArg = 1; nCurrentArg < nArgCount; ++nCurrentArg)
{
pszCurrentArg = papszArguments[nCurrentArg];
switch(GetCommandLineParameter(pszCurrentArg))
{
case kParamLocal:
od_control.od_force_local = TRUE;
break;
case kParamBPS:
AdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
od_control.baud = atol(papszArguments[nCurrentArg]);
break;
case kParamPort:
AdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
od_control.port = atoi(papszArguments[nCurrentArg]);
break;
case kParamHelp:
printf("AVALIABLE COMMAND LINE PARAMETERS:\n");
printf(" -L or -LOCAL - Causes door to operate in local mode, without requiring a\n");
printf(" door information (drop) file.\n");
printf(" -DROPFILE x - Door information file directory or directory+filename.\n");
printf(" -N x or -NODE x - Sets the node number to use.\n");
printf(" -B x or -BPS x - Sets the serial port <---> modem bps (baud) rate to use.\n");
printf(" -P x or -PORT x - Sets the serial port to use, were 0=COM1, 1=COM2, etc.\n");
printf(" -ADDRESS x - Sets serial port address in decimal NOT hexidecimal\n");
printf(" (only has effect if FOSSIL driver is not being used).\n");
printf(" -IRQ x - Sets the serial port IRQ line (only has effect if FOSSIL\n");
printf(" driver is not being used).\n");
printf(" -NOFOSSIL - Disables use of FOSSIL driver, even if available.\n");
printf(" -NOFIFO - Disables use of 16550 FIFO buffers (only if FOSSIL driver\n");
printf(" is not being used).\n");
printf(" -PERSONALITY x - Sets the sysop status line / function key personality to\n");
printf(" use - one of Standard, PCBoard, RemoteAccess or Wildcat.\n");
printf(" -MAXTIME x - Sets the maximum number of minutes that any user will be\n");
printf(" permitted to access the door.\n");
printf(" -USERNAME x - Name of user who is currently online.\n");
printf(" -TIMELEFT x - User's time remaining online.\n");
printf(" -SECURITY x - User's security level.\n");
printf(" -LOCATION x - Location from which user is calling.\n");
printf(" -?, -H or -HELP - Displays command-line help and exits.\n");
exit(1);
break;
case kParamNode:
AdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
od_control.od_node = atoi(papszArguments[nCurrentArg]);
break;
case kParamPersonality:
AdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
if(stricmp(papszArguments[nCurrentArg], "Standard") == 0)
{
od_control.od_default_personality = PER_OPENDOORS;
}
else if(stricmp(papszArguments[nCurrentArg], "PCBoard") == 0)
{
od_control.od_default_personality = PER_PCBOARD;
}
else if(stricmp(papszArguments[nCurrentArg], "RemoteAccess") == 0)
{
od_control.od_default_personality = PER_RA;
}
else if(stricmp(papszArguments[nCurrentArg], "Wildcat") == 0)
{
od_control.od_default_personality = PER_WILDCAT;
}
else
{
printf("Unknown personality: %s\n", papszArguments[nCurrentArg]);
exit(1);
}
break;
case kParamMaxTime:
AdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
od_control.od_maxtime = atoi(papszArguments[nCurrentArg]);
break;
case kParamAddress:
AdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
od_control.od_com_address = atoi(papszArguments[nCurrentArg]);
break;
case kParamIRQ:
AdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
od_control.od_com_irq = atoi(papszArguments[nCurrentArg]);
break;
case kParamNoFOSSIL:
od_control.od_no_fossil = TRUE;
break;
case kParamNoFIFO:
od_control.od_com_no_fifo = TRUE;
break;
case kParamDropFile:
AdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
strncpy(od_control.info_path, papszArguments[nCurrentArg],
sizeof(od_control.info_path) - 1);
od_control.info_path[sizeof(od_control.info_path) - 1] = '\0';
break;
case kParamUserName:
GetNextArgName(&nCurrentArg, nArgCount, papszArguments,
od_control.user_name, sizeof(od_control.user_name));
break;
case kParamTimeLeft:
AdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
od_control.user_timelimit = atoi(papszArguments[nCurrentArg]);
break;
case kParamSecurity:
AdvanceToNextArg(&nCurrentArg, nArgCount, pszCurrentArg);
od_control.user_security = atoi(papszArguments[nCurrentArg]);
break;
case kParamLocation:
GetNextArgName(&nCurrentArg, nArgCount, papszArguments,
od_control.user_location, sizeof(od_control.user_location));
break;
default:
printf("Unrecognized command line option: %s\n", pszCurrentArg);
exit(1);
break;
}
}
}
static void AdvanceToNextArg(int *pnCurrentArg, int nArgCount, char *pszOption)
{
if(++*pnCurrentArg >= nArgCount)
{
printf("Missing parameter for option: %s\n", pszOption);
exit(1);
}
}
static void GetNextArgName(int *pnCurrentArg, int nArgCount,
char *papszArguments[], char *pszString,
int nStringSize)
{
BOOL bFirst = TRUE;
if((*pnCurrentArg) + 1 >= nArgCount)
{
printf("Missing parameter for option: %s\n",
papszArguments[(*pnCurrentArg) - 1]);
exit(1);
}
pszString[0] = '\0';
while(++*pnCurrentArg < nArgCount)
{
if(GetCommandLineParameter(papszArguments[*pnCurrentArg])
!= kParamUnknown)
{
--*pnCurrentArg;
break;
}
if(strlen(pszString) >= nStringSize - 1)
{
break;
}
if(!bFirst)
{
strcat(pszString, " ");
}
strncat(pszString, papszArguments[*pnCurrentArg],
strlen(pszString) - nStringSize - 1);
pszString[nStringSize - 1] = '\0';
bFirst = FALSE;
}
}
static tCommandLineParameter GetCommandLineParameter(char *pszArgument)
{
if(*pszArgument == '-' || *pszArgument == '/')
{
++pszArgument;
}
if(stricmp(pszArgument, "L") == 0
|| stricmp(pszArgument, "LOCAL") == 0)
{
return(kParamLocal);
}
else if(stricmp(pszArgument, "B") == 0
|| stricmp(pszArgument, "BPS") == 0
|| stricmp(pszArgument, "BAUD") == 0)
{
return(kParamBPS);
}
else if(stricmp(pszArgument, "P") == 0
|| stricmp(pszArgument, "PORT") == 0)
{
return(kParamPort);
}
else if(stricmp(pszArgument, "N") == 0
|| stricmp(pszArgument, "NODE") == 0)
{
return(kParamNode);
}
else if(stricmp(pszArgument, "?") == 0
|| stricmp(pszArgument, "H") == 0
|| stricmp(pszArgument, "HELP") == 0)
{
return(kParamHelp);
}
else if(stricmp(pszArgument, "PERSONALITY") == 0)
{
return(kParamPersonality);
}
else if(stricmp(pszArgument, "MAXTIME") == 0)
{
return(kParamMaxTime);
}
else if(stricmp(pszArgument, "ADDRESS") == 0)
{
return(kParamAddress);
}
else if(stricmp(pszArgument, "IRQ") == 0)
{
return(kParamIRQ);
}
else if(stricmp(pszArgument, "NOFOSSIL") == 0)
{
return(kParamNoFOSSIL);
}
else if(stricmp(pszArgument, "NOFIFO") == 0)
{
return(kParamNoFIFO);
}
else if(stricmp(pszArgument, "DROPFILE") == 0)
{
return(kParamDropFile);
}
else if(stricmp(pszArgument, "USERNAME") == 0)
{
return(kParamUserName);
}
else if(stricmp(pszArgument, "TIMELEFT") == 0)
{
return(kParamTimeLeft);
}
else if(stricmp(pszArgument, "SECURITY") == 0)
{
return(kParamSecurity);
}
else if(stricmp(pszArgument, "LOCATION") == 0)
{
return(kParamLocation);
}
else
{
return(kParamUnknown);
}
}
void NoDoorFileHandler(void)
{
/* Alter OpenDoors behaviour, so that we proceed with defaults if */
/* no door information file is available, rather than exiting with */
/* an error. Set od_no_file_func to point to this function. */
if(strlen(od_control.user_name) == 0)
{
strcpy(od_control.user_name, "Unknown User");
}
if(strlen(od_control.user_location) == 0)
{
strcpy(od_control.user_location, "Unknown Location");
}
if(od_control.user_timelimit == 0)
{
od_control.user_timelimit = 30;
}
od_control.od_info_type = CUSTOM;
}

View File

@ -0,0 +1,5 @@
#ifndef INC_CMDLINE
#define INC_CMDLINE
void ParseStandardCommandLine(int nArgCount, char *papszArguments[]);
void NoDoorFileHandler(void);
#endif

View File

@ -0,0 +1,352 @@
/* fileview.c - File viewing door that demonstrates the use of the */
/* PagedViewer() function. This door can be setup to */
/* to display a single text file, or any file from an */
/* entire directory of text files. The program accepts */
/* a single command-line argument, which if present, */
/* specifies the filename or wildcard of the files to */
/* display. If this argument is not present, all files */
/* in the current directory will be available for */
/* viewing. If there is more than one possible file to */
/* be displayed, this program will display a list of */
/* files that the user can choose from to display. If */
/* there is only one possible file, that file is */
/* is displayed. This program uses PagedViewer() for two */
/* seperate uses - the list of available files, and for */
/* viewing the file itself. */
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "bpfind.h"
#include "opendoor.h"
#include "pageview.h"
/* Configurable constants. */
#define FILENAME_SIZE 75
#define PATH_CHARS (FILENAME_SIZE - 13)
#define LINE_SIZE 80
#define ARRAY_GROW_SIZE 20
/* Global variables. */
int nTotalFiles = 0;
int nFileArraySize = 0;
char *paszFileArray = NULL;
FILE *pfCurrentFile;
int nTotalLines = 0;
int nLineArraySize = 0;
long *palLineOffset = NULL;
/* Function prototypes. */
void AddFilesMatching(char *pszFileSpec);
char *GetFilename(int nIndex);
int AddFilename(char *pszFilename);
void GetDirOnly(char *pszOutDirName, const char *pszInPathName);
int DirExists(const char *pszDirName);
void BuildPath(char *pszOut, char *pszPath, char *pszFilename);
void FreeFileList(void);
void DisplayFileName(int nLine, void *pCallbackData);
void DisplayFile(char *pszFilename);
void DisplayFileLine(int nLine, void *pCallbackData);
int AddOffsetToArray(long lOffset);
void FreeLineArray(void);
/* Program execution begins here. */
int main(int nArgCount, char *papszArgument[])
{
int nArg;
int nChoice;
od_init();
/* Get file specifiction from command-line, if any. */
if(nArgCount >= 2)
{
for(nArg = 1; nArg < nArgCount; ++nArg)
{
AddFilesMatching(papszArgument[nArg]);
}
}
/* If there are no command-line parameters, use *.* */
else
{
AddFilesMatching("*.*");
}
/* If there are no matching files, display error. */
if(nTotalFiles == 0)
{
od_printf("No files were found.\n\r\n\r");
od_printf("Press [Enter] to continue.\n\r");
od_get_answer("\n\r");
return(0);
}
/* If only one file was found, then display it. */
else if(nTotalFiles == 1)
{
DisplayFile(GetFilename(0));
}
/* If more than one file was found, allow user to choose file */
/* to display. */
else
{
/* Loop until user chooses to quit. */
nChoice = 0;
for(;;)
{
/* Get user's selection. */
nChoice = PagedViewer(nChoice, nTotalFiles, DisplayFileName,
NULL, TRUE, "Choose A File To Display", 19);
/* If user chose to quit, then exit door. */
if(nChoice == NO_LINE) break;
/* Otherwise, display the file that the user chose. */
DisplayFile(GetFilename(nChoice));
}
}
FreeFileList();
return(0);
}
void AddFilesMatching(char *pszFileSpec)
{
struct ffblk DirEntry;
int bNoMoreFiles;
char szDirName[PATH_CHARS + 1];
char szFileName[FILENAME_SIZE];
/* Check that file specification is not too long. */
if(strlen(pszFileSpec) > PATH_CHARS)
{
return;
}
/* Get directory name from path. */
GetDirOnly(szDirName, pszFileSpec);
bNoMoreFiles = findfirst(pszFileSpec, &DirEntry, FA_RDONLY);
while(!bNoMoreFiles)
{
BuildPath(szFileName, szDirName, DirEntry.ff_name);
AddFilename(szFileName);
bNoMoreFiles = findnext(&DirEntry);
}
}
void GetDirOnly(char *pszOutDirName, const char *pszInPathName)
{
char *pchBackslashChar;
/* Default dir name is entire path. */
strcpy(pszOutDirName, pszInPathName);
/* If there is a backslash in the string. */
pchBackslashChar = strrchr(pszOutDirName, '\\');
if(pchBackslashChar != NULL)
{
/* Remove all character beginning at last backslash from path. */
*pchBackslashChar = '\0';
}
else
{
/* If there is no backslash in the filename, then the dir name */
/* is empty. */
pszOutDirName[0] = '\0';
}
}
void BuildPath(char *pszOut, char *pszPath, char *pszFilename)
{
/* Copy path to output filename. */
strcpy(pszOut, pszPath);
/* Ensure there is a trailing backslash. */
if(strlen(pszOut) > 0 && pszOut[strlen(pszOut) - 1] != '\\')
{
strcat(pszOut, "\\");
}
/* Append base filename. */
strcat(pszOut, pszFilename);
}
char *GetFilename(int nIndex)
{
return(paszFileArray + (nIndex * FILENAME_SIZE));
}
int AddFilename(char *pszFilename)
{
int nNewArraySize;
char *paszNewArray;
char *pszNewString;
/* If array is full, then try to grow it. */
if(nTotalFiles == nFileArraySize)
{
nNewArraySize = nFileArraySize + ARRAY_GROW_SIZE;
if((paszNewArray =
realloc(paszFileArray, nNewArraySize * FILENAME_SIZE)) == NULL)
{
return(FALSE);
}
nFileArraySize = nNewArraySize;
paszFileArray = paszNewArray;
}
/* Get address to place new string at, while incrementing total number */
/* of filenames. */
pszNewString = GetFilename(nTotalFiles++);
/* Copy up to the maximum number of filename characters to the string. */
strncpy(pszNewString, pszFilename, FILENAME_SIZE - 1);
pszNewString[FILENAME_SIZE - 1] = '\0';
return(TRUE);
}
void FreeFileList(void)
{
if(nFileArraySize > 0)
{
free(paszFileArray);
nFileArraySize = 0;
nTotalFiles = 0;
paszFileArray = NULL;
}
}
void DisplayFileName(int nLine, void *pCallbackData)
{
(void)pCallbackData;
od_printf(GetFilename(nLine));
}
void DisplayFile(char *pszFilename)
{
char szLine[LINE_SIZE];
long lnOffset;
/* Clear the screen. */
od_clr_scr();
/* Attempt to open the file. */
pfCurrentFile = fopen(pszFilename, "r");
if(pfCurrentFile == NULL)
{
od_printf("Unable to open file.\n\r\n\r");
od_printf("Press [Enter] to continue.\n\r");
od_get_answer("\n\r");
return;
}
/* Get file offsets of each line and total line count from file. */
for(;;)
{
lnOffset = fTell(pfCurrentFile);
if(fgets(szLine, LINE_SIZE, pfCurrentFile) == NULL) break;
AddOffsetToArray(lnOffset);
}
/* Use PagedViewer() to view the file. */
PagedViewer(0, nTotalLines, DisplayFileLine, NULL, FALSE, NULL, 21);
/* Deallocate array of line offsets. */
FreeLineArray();
/* Close the file. */
fclose(pfCurrentFile);
}
void DisplayFileLine(int nLine, void *pCallbackData)
{
char szLine[LINE_SIZE];
long lnTargetOffset = palLineOffset[nLine];
int nLineLen;
(void)pCallbackData;
/* Move to proper offset in file. */
if(lnTargetOffset != ftell(pfCurrentFile))
{
fseek(pfCurrentFile, lnTargetOffset, SEEK_SET);
}
/* Get line from line. */
if(fgets(szLine, LINE_SIZE, pfCurrentFile) != NULL)
{
/* Remote any trailing CR/LF sequence from line. */
nLineLen = strlen(szLine);
while(nLineLen > 0
&& (szLine[nLineLen - 1] == '\r' || szLine[nLineLen - 1] == '\n'))
{
szLine[--nLineLen] = '\0';
}
/* Display the line on the screen. */
od_disp_str(szLine);
}
}
int AddOffsetToArray(long lOffset)
{
long *palNewArray;
int nNewArraySize;
/* If array is full, then grow it. */
if(nTotalLines == nLineArraySize)
{
nNewArraySize = nLineArraySize + ARRAY_GROW_SIZE;
if((palNewArray =
realloc(palLineOffset, nNewArraySize * sizeof(long))) == NULL)
{
return(FALSE);
}
nLineArraySize = nNewArraySize;
palLineOffset = palNewArray;
}
palLineOffset[nTotalLines++] = lOffset;
return(TRUE);
}
void FreeLineArray(void)
{
if(nLineArraySize > 0)
{
nTotalLines = 0;
nLineArraySize = 0;
free(palLineOffset);
palLineOffset = NULL;
}
}

View File

@ -0,0 +1,177 @@
/* pageview.c - Implementation of the PagedViewer() system. */
#include <string.h>
#include "opendoor.h"
#include "pageview.h"
char bTitleColor = 0x0c;
char bTitleLineColor = 0x04;
char bNumberColor = 0x0a;
char bTextColor = 0x02;
char bPromptColor = 0x0f;
int PagedViewer(
int nInitialLine, /* Zero-based initial line number. */
int nTotalLines, /* Total line count. */
void (*pDisplayCallback)(int nLine, void *pData),
void *pCallbackData, /* Data to pass to callback func. */
BOOL bAllowSelection, /* TRUE if selection is permitted. */
char *pszTitle, /* Title string, or NULL. */
int nPageSize) /* # of lines to display per page. */
{
int nCurrentPage = 0;
int nScreenLine;
int nAbsoluteLine;
char chPressed;
char bCanPageDown;
char bCanPageUp;
/* Determine current page from initial line number, if specified. */
if(nInitialLine != NO_LINE)
{
nCurrentPage = nInitialLine / nPageSize;
}
/* Loop until user makes a selection, or chooses to quit. */
for(;;)
{
/* Display the current page. */
/* Clear the screen */
od_printf("\n\r");
od_clr_scr();
/* If a title has been specified, then display it. */
if(pszTitle != NULL)
{
od_set_attrib(bTitleColor);
od_repeat(' ', (80 - strlen(pszTitle)) / 2);
od_disp_str(pszTitle);
od_printf("\n\r");
od_set_attrib(bTitleLineColor);
if(od_control.user_ansi || od_control.user_avatar)
{
od_repeat(196, 79);
}
else
{
od_repeat('-', 79);
}
od_printf("\n\r");
}
/* Display the lines on this page. */
nAbsoluteLine = nCurrentPage * nPageSize;
nScreenLine = 0;
while(nScreenLine < nPageSize && nAbsoluteLine < nTotalLines)
{
/* If selection is permitted, display an identifier for each line. */
if(bAllowSelection)
{
od_set_attrib(bNumberColor);
if(nScreenLine < 9)
{
od_printf("%d. ", nScreenLine + 1);
}
else
{
od_printf("%c. ", 'A' + (nScreenLine - 9));
}
}
/* Display the line itself. */
od_set_attrib(bTextColor);
(*pDisplayCallback)(nAbsoluteLine, pCallbackData);
od_printf("\n\r");
/* Move to next line. */
nScreenLine++;
nAbsoluteLine++;
}
/* Determine whether user can page up or down from this page. */
bCanPageDown = nCurrentPage < (nTotalLines - 1) / nPageSize;
bCanPageUp = nCurrentPage > 0;
/* Display prompt at bottom of screen. */
od_set_attrib(bPromptColor);
od_printf("\n\r[Page %d of %d] ", nCurrentPage + 1,
((nTotalLines - 1) / nPageSize) + 1);
if(bAllowSelection)
{
od_printf("Choose an option or");
}
else
{
od_printf("Available options:");
}
if(bCanPageDown)
{
od_printf(" [N]ext page,");
}
if(bCanPageUp)
{
od_printf(" [P]revious page,");
}
od_printf(" [Q]uit.");
/* Loop until the user makes a valid choice. */
for(;;)
{
/* Get key from user */
chPressed = toupper(od_get_key(TRUE));
if(chPressed == 'Q')
{
/* If user chooses to quit, then return without a selection. */
od_printf("\n\r");
return(NO_LINE);
}
else if(chPressed == 'P' && bCanPageUp)
{
/* Move to previous page and redraw screen. */
--nCurrentPage;
break;
}
else if(chPressed == 'N' && bCanPageDown)
{
/* Move to next page and redraw screen. */
++nCurrentPage;
break;
}
else if(bAllowSelection
&& (
(chPressed >= '1' && chPressed <= '9')
|| (chPressed >= 'A' && chPressed <= 'M')
)
)
{
/* If user pressed a possible line key, and selection is */
/* enabled, try translating character to a line number. */
if(chPressed >= '1' && chPressed <= '9')
{
nScreenLine = chPressed - '1';
}
else
{
nScreenLine = 9 + (chPressed - 'A');
}
/* Calculate absolute line number. */
nAbsoluteLine = nScreenLine + (nCurrentPage * nPageSize);
/* If selected line is within range, then return selected line */
/* number. */
if(nScreenLine < nPageSize && nAbsoluteLine < nTotalLines)
{
od_printf("\n\r");
return(nAbsoluteLine);
}
}
}
}
}

View File

@ -0,0 +1,19 @@
/* pageview.h - Include file for PagedViewer() function. */
/* Manifest constant. */
#define NO_LINE -1
/* Boolean definitions. */
#ifndef BOOL
typedef int BOOL;
#endif
/* Prototype for the function. */
int PagedViewer(
int nInitialLine,
int nTotalLines,
void (*pDisplayCallback)(int nLine, void *pCallbackData),
void *pCallbackData,
BOOL bAllowSelection,
char *pszTitle,
int nPageSize);

View File

@ -0,0 +1,46 @@
OpenDoors tips package #3
---
(C) Copyright 1994, Brian Pirie. All Rights Reserved.
This package includes a collection of tips and utility functions to help
those using the OpenDoors door programming toolkit. You are free to use
these tips and included source code as you wish, without any fee or
royalty.
This package includes the following tip files:
Tip #1. Drawing horizontal bar graphs using od_repeat().
Files: tip1.txt, tip1.c
Tip #2. Transferring files using DSZ.
Files: tip2.txt, tip2.c
Tip #3. A generic paged viewing / selection routine, and text file
viewing door that uses the paged viewing routine.
Files: tip3.txt, pageview.c, pageview.h, fileview.c, bpfind.h
Tip #4. Command-line processing for many standard door-related command
line options.
Files: tip4.txt,tip4.c, cmdline.c, cmdline.h
How to contact the author
-------------------------
I can be reached by any of the following means:
Internet email : brianp@bpecomm.ocunix.on.ca
Fidonet Crashmail : 1:243/8 (you must poll for a response)
Modem (24hrs/day) : +1 613 526 4466
Conventional mail : Brian Pirie
#1416 - 2201 Riverside Drive
Ottawa, Ontario
K1H 8K9
Canada

View File

@ -0,0 +1,88 @@
/* Includes */
#include "opendoor.h"
/* Function prototypes. */
void DrawHorizontalBar(int nValue, int nMinValue, int nMaxValue,
int nMaxChars);
void DrawGraphOfPercentages(int nItems, int *panPercentages,
char **papszTitles, char bTitleColor, char bGraphColor,
int nTitleWidth, int nGraphWidth);
/* Main function - program execution begins here. */
main()
{
char *apszTitles[7] = {"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"};
int anValues[7] = {50, 75, 100, 25, 83, 0, 43};
od_printf("`bright green`Test graph:\n\r");
DrawGraphOfPercentages(7, anValues, apszTitles, 0x02, 0x0f, 20, 50);
od_get_key(TRUE);
return(0);
}
/* Function to draw horizontal graph of percentages with titles, to */
/* demonstrate the use of the DrawHorizontalBar() function. */
/* No titles should have more than nTitleWidth characters. */
void DrawGraphOfPercentages(int nItems, int *panPercentages,
char **papszTitles, char bTitleColor, char bGraphColor,
int nTitleWidth, int nGraphWidth)
{
int nCurrentItem;
/* Loop for each item (line) in the graph. */
for(nCurrentItem = 0; nCurrentItem < nItems; ++nCurrentItem)
{
/* Set display color for title text. */
od_set_attrib(bTitleColor);
/* Add spaces to right-align all titles. */
od_repeat(' ', nTitleWidth - strlen(papszTitles[nCurrentItem]));
/* Display the title. */
od_disp_str(papszTitles[nCurrentItem]);
/* Add space between title and graph. */
od_printf(" ");
/* Set display color for graph. */
od_set_attrib(bGraphColor);
/* Draw bar graph for this line. */
DrawHorizontalBar(panPercentages[nCurrentItem], 0, 100, nGraphWidth);
/* Move to the next line. */
od_printf("\n\r");
}
}
/* Function to draw a horizontal bar, given a value, the minimum and maximum */
/* possible values, and the number of characters the horizontal bar should */
/* extended for the maximum value. */
void DrawHorizontalBar(int nValue, int nMinValue, int nMaxValue,
int nMaxChars)
{
/* Determine lenght of bar */
int nBarChars = ((nValue - nMinValue) * nMaxChars) / nMaxValue;
if(od_control.user_ansi || od_control.user_avatar)
{
/* If ANSI or AVATAR graphics are available, assume that IBM extended */
/* ASCII is also available. This function uses character 220 to form */
/* bars that are 1/2 the height of the line. You might also want to */
/* try character 119, which will form bars that are the entire height */
/* of the line. */
od_repeat(220, nBarChars);
}
else
{
/* In ASCII mode, the bar is formed by the '=' character. */
od_repeat('=', nBarChars);
}
}

View File

@ -0,0 +1,55 @@
Many different types of programs can be enhanced by the use of graphical
information. Often, this graphical information can take the form of
horizontal bar graphs.
An easy way to draw horizontal bars in door programs written with
OpenDoors, is to use the od_repeat() function. Not only does od_repeat()
allow you to easily form a bar by repeating a particular character the
specified number of times, but it is also a very efficient way to do so.
od_repeat() will take advantage of terminal emulation optimizations,
when available. For instance, a character can be repeated any number of
times with AVATAR by sending a short 3-byte sequence that specifies the
character and number of times to repeat.
How do you calculate the number of character to use to form a bar in
your graph? The DrawHorizontalBar() function, which is provided below,
will do this calculation for you. Simply provide the value to be
represented by this bar, the minimum and maximum possible values, and
the maximum number of character to use to draw the bar. For example, if
you are graphing percentages (which could range from 0% to 100%), and
wanted the graph to fit in a space of 40 columns, you would use:
DrawHorizontalBar(nPercent, 0, 100, 40);
The included tip1.c is a complete program which demonstrates the
DrawHorizontalBar() function as called from another function that will
create complete horizontal bar graphs. This second function,
DrawGraphOfPercentages(), takes an array of titles, and array of values
corresponding to each title, and draws a complete bar graph from this
information.
/* Function to draw a horizontal bar, given a value, the minimum and maximum */
/* possible values, and the number of characters the horizontal bar should */
/* extended for the maximum value. */
void DrawHorizontalBar(int nValue, int nMinValue, int nMaxValue,
int nMaxChars)
{
/* Determine lenght of bar */
int nBarChars = ((nValue - nMinValue) * nMaxChars) / nMaxValue;
if(od_control.user_ansi || od_control.user_avatar)
{
/* If ANSI or AVATAR graphics are available, assume that IBM extended */
/* ASCII is also available. This function uses character 220 to form */
/* bars that are 1/2 the height of the line. You might also want to */
/* try character 119, which will form bars that are the entire height */
/* of the line. */
od_repeat(220, nBarChars);
}
else
{
/* In ASCII mode, the bar is formed by the '=' character. */
od_repeat('=', nBarChars);
}
}

View File

@ -0,0 +1,245 @@
/* tip2.c - Example program to demonstrate how to send or receive files */
/* using DSZ, from within an OpenDoors program. */
/* Include required header files. */
#include <stdio.h>
#include <assert.h>
#include "opendoor.h"
/* File transfer protocol enumeration. */
typedef enum
{
XModem,
XModemCRC,
XModem1K,
YModem,
YModemG,
ZModem
} eProtocol;
/* Function prototypes. */
int TransferFile(char *pszFilename, eProtocol Protocol, char bReceive);
eProtocol ChooseProtocol(void);
void AddParameter(char **papszArguments, int *pnCount, char *pszNewArgument);
/* Manifest constants. */
#define ARGS_ARRAY_SIZE 10
/* Global variable with DSZ filename. */
char szDSZFilename[80] = "DSZ";
/* Program's execution begins here. */
main()
{
char chAnswer;
char bReceive;
eProtocol Protocol;
char szFilename[73];
int bSuccess;
od_printf("OpenDoors file transfer demo.\n\r\n\r");
/* Get file transfer direction from user. */
od_printf("Do you wish to [U]pload or [D]ownload? ");
chAnswer = od_get_answer("UD");
if(chAnswer == 'U')
{
od_printf("Upload\n\r\n\r");
bReceive = TRUE;
}
else
{
od_printf("Download\n\r\n\r");
bReceive = FALSE;
}
/* Get file transfer protocol from user. */
Protocol = ChooseProtocol();
/* Get filename. */
od_printf("\n\rEnter filename(s) : ");
od_input_str(szFilename, 72, ' ', 255);
od_printf("\n\r");
/* Perform file transfer. */
bSuccess = TransferFile(szFilename, Protocol, bReceive);
/* Display result of file transfer to user. */
od_clr_scr();
if(bSuccess)
{
od_printf("File transfer successful.\n\r");
}
else
{
od_printf("File transfer not completed.\n\r");
}
/* Prompt user to exit program. */
od_printf("Press [Enter] to return to BBS.\n\r");
od_get_answer("\n\r");
/* Return control to calling BBS software. */
od_exit(0, FALSE);
return(0);
}
/* Function to allow user to choose a file transfer protocol. */
eProtocol ChooseProtocol(void)
{
eProtocol Protocol;
char chAnswer;
od_printf("Available file transfer protocols:\n\r");
od_printf(" [X] XModem\n\r");
od_printf(" [C] XModem/CRC\n\r");
od_printf(" [1] XModem/1K\n\r");
od_printf(" [Y] YModem\n\r");
od_printf(" [G] YModem-G\n\r");
od_printf(" [Z] ZModem\n\r\n\r");
od_printf("Please select a protocol: ");
chAnswer = od_get_answer("XC1YGZ");
switch(chAnswer)
{
case 'X':
od_printf("XModem\n\r");
Protocol = XModem;
break;
case 'C':
od_printf("XModem/CRC\n\r");
Protocol = XModemCRC;
break;
case '1':
od_printf("XModem/1K\n\r");
Protocol = XModem1K;
break;
case 'Y':
od_printf("YModem\n\r");
Protocol = YModem;
break;
case 'G':
od_printf("YModem-G\n\r");
Protocol = YModemG;
break;
case 'Z':
default:
od_printf("ZModem\n\r");
Protocol = ZModem;
break;
}
return(Protocol);
}
/* Function to send or receive a file to/from remote system. */
int TransferFile(char *pszFilename, eProtocol Protocol, char bReceive)
{
char szPort[7];
char *apszArguments[ARGS_ARRAY_SIZE];
int nArgCount = 0;
/* Filename cannot be NULL. */
assert(pszFilename != NULL);
/* Ensure that we are not operating in local mode. */
if(od_control.baud == 0)
{
od_printf("Operating in local mode; file transfer not possible.\n\r");
return(FALSE);
}
/* Generate DSZ command line */
/* Begin with executable filename. */
AddParameter(apszArguments, &nArgCount, szDSZFilename);
/* Add port parameter. */
AddParameter(apszArguments, &nArgCount, "port");
sprintf(szPort, "%d", od_control.port + 1);
AddParameter(apszArguments, &nArgCount, szPort);
/* Restrict inbound files to current drive and directory. */
AddParameter(apszArguments, &nArgCount, "restrict");
/* Generate DSZ protocol parameters from specified protocol and direction. */
if(bReceive)
{
switch(Protocol)
{
case XModem:
case XModem1K:
AddParameter(apszArguments, &nArgCount, "rx");
break;
case XModemCRC:
AddParameter(apszArguments, &nArgCount, "rc");
break;
case YModem:
AddParameter(apszArguments, &nArgCount, "rb");
break;
case YModemG:
AddParameter(apszArguments, &nArgCount, "rb");
AddParameter(apszArguments, &nArgCount, "-g");
break;
case ZModem:
AddParameter(apszArguments, &nArgCount, "rz");
break;
default:
assert(FALSE);
}
}
else
{
switch(Protocol)
{
case XModem:
case XModemCRC:
AddParameter(apszArguments, &nArgCount, "sx");
break;
case XModem1K:
AddParameter(apszArguments, &nArgCount, "sx");
AddParameter(apszArguments, &nArgCount, "-k");
break;
case YModem:
case YModemG:
AddParameter(apszArguments, &nArgCount, "sb");
break;
case ZModem:
AddParameter(apszArguments, &nArgCount, "sz");
break;
default:
assert(FALSE);
}
}
/* Add filename parameter to command line. */
AddParameter(apszArguments, &nArgCount, pszFilename);
/* Display prompt to user providing */
od_printf("Begin your transfer now, or press [Ctrl]-[X] several times to abort.\n\r");
/* Execute command using the OpenDoors od_spawn() function. */
return(od_spawnvpe(P_WAIT, apszArguments[0], apszArguments, NULL) == 0);
}
/* Function to add next parameter to array of parameters to pass to */
/* od_spawnvpe(). */
void AddParameter(char **papszArguments, int *pnCount, char *pszNewArgument)
{
assert(*pnCount < ARGS_ARRAY_SIZE - 1);
assert(papszArguments != NULL);
assert(pnCount != NULL);
assert(pszNewArgument != NULL);
/* Add next argument to array. */
papszArguments[(*pnCount)++] = pszNewArgument;
/* Ensure that the array is always NULL-terminated. */
papszArguments[*pnCount] = NULL;
}

View File

@ -0,0 +1,45 @@
Often, it can be useful or necessary to send and receive files between
a program using OpenDoors, and the remote user's system. To allow file
uploading and downloadeding, you can either implement the common file
transfer protocols as part of your program, or you can call an external
file transfer program, such as DSZ. This tip demonstrates how you can
call DSZ using OpenDoors.
In order to see this program in action, you should run a terminal
program on one machine, and connect to second machine that will run this
example program. (You could also do this in two different windows on one
machine.) The demonstration program will ask whether you want to upload
or download files, and will then prompt you for the file transfer protocol
to use and the filename to transfer. Once this is done, DSZ is invoked
to perform the file transfer. As such, DSZ will need to be installed on
the machine that will run the example program.
The tip2.c source file provides a function that you can use to perform
file transfers. This function is defined as follows:
int TransferFile(char *pszFilename, eProtocol Protocol, char bReceive)
The first parameter should contain the name of the file or files to be
transfered. The second parameter should specify the file transfer
protocol to use, and should be one of the following enumerated
constants:
XModem
XModemCRC
XModem1K
YModem
YModemG
ZModem
The third parameter specifies whether the file is being send (FALSE) or
received (TRUE). From the user's perspective, sending the file means
downloading, and receiving the file means uploading.
The TransferFile() function returns TRUE if the file transfer was
completed, and FALSE if it was not.
If the DSZ program is not present in the system's PATH or the current
directory, then the global variable szDSZFilename must be set to the
full path and filename of the DSZ program. This could be done by adding
a custom OpenDoors configuration file line with a keyword such as
"DSZPath".

View File

@ -0,0 +1,82 @@
Many people have admired the paged question selection facility in the
OpenDoors 5.00 EZVote example door. EZVote allows the user to choose
questions from a list of up to 200 questions, by displaying one page
of questions at a time. The user is able to page up or down in the list
of quesitons, select a question from the list, or return to the main
menu. A prompt at the bottom of the screen shows the current page
number, and a list of options that are currently available. For
instance, when displaying the first of two pages, this prompt indicates
that the user can move to the next page, but not the previous page.
This OpenDoors Tip shows a generic function that provides the same sorts
of capabilities that are seen in the EZVote example door, in a form that
can be re-used in many different programs. This function, named
PagedViewer(), can be used for displaying multi-paged messages, text
files, or for permitting selection from a potentially very long list of
items. To use the PagedViewer() in a program, you should add the
pageview.c file to your project file / makefile, and #include the
pageview.h file in any source file that calls PagedViewer().
The prototype for the PagedViewer() function is as follows:
int PagedViewer(
int nInitialLine,
int nTotalLines,
void (*pDisplayCallback)(int nLine, void *pCallbackData),
void *pCallbackData,
BOOL bAllowSelection,
char *pszTitle,
int nPageSize);
The nInitialLine parameter specifies the line to begin viewing at.
Normally this would be 0, but you may wish to pass a different value to
this function to force the viewer to begin on a page other than the
first. Using this parameter, you can have the user return to
the page they were previously viewing, rather than returning to the
first page and having to again find their original location.
The nTotalLines parameter specifies the total number of lines that can
be viewed, and can be any value greater than or equal to 0.
The pDisplayCallback parameter must be a pointer to a function that the
PagedViewer will call to display a particular line of the file at the
current location. When PagedViewer() calls your function, it will pass
the line number to be displayed, along with the value originally passed
to PagedViewer() in pCallbackData. The provided function should simply
display the text for the specified line number, without a trailing CR/LF
sequence, and then return.
The pCallbackData can point to any data that you wish PagedViewer() to
pass to your callback function, or may be NULL if you do not wish to use
this feature.
The bAllowSelection parameter should be TRUE if the user should be able
to make a selection from the list, and FALSE if they should not. If
bAllowSelection is TRUE, PagedViewer() will display a letter beside each
line, and allow the user to select a line by pressing the corresponding
letter. If you are using PagedViewer() to display a text file or
message, you will want to set bAllowSelection to FALSE. If you are using
PagedViewer() to display a list of items from which the user can select,
you will want to set bAllowSelection to TRUE.
The pszTitle parameter can point to a title to be displayed at the top
of each page, and could be something like ("Select a message"). If you
do not wish to have a title displayed, set this parameter to NULL.
The nPageSize parameter specifies the number of lines that should be
displayed on each page. If you do not wish to have the local screen
(with a two line status line) to be scrolled while displaying the list,
the maximum page size you should use is 21 if no title is being
displayed, and 19 if a title is being displayed.
The included fileview.c text file viewing program demonstrates the use
of PagedViewer(). The fileview.c door can be setup to allow the user to
view one or more files. If setup to view multiple files, the program
first displays a list of files that the user can select to view.
The fileview.c program uses PagedViewer() in two places - for providing
the list of files and for displaying the file itself. As such, the user
can page up or down in the list of files, select a file to view, and
then page up or down in the file. When the user selects quit while
viewing the file, they are returned to the list of files to possibly
select another file. When the user selects quit from the list of files,
the door returns control to the calling BBS software.

View File

@ -0,0 +1,19 @@
#include "opendoor.h"
#include "cmdline.h"
int main(int argc, char *argv[])
{
/* Set function to be called if no door information file is found. */
od_control.od_no_file_func = NoDoorFileHandler;
/* Call command-line processing function before first call to any */
/* OpenDoors function! */
ParseStandardCommandLine(argc, argv);
/* Proceed with door normally. */
od_printf("Hello World!\n\r\n\r");
od_printf("Press [Enter] to return to BBS.\n\r");
od_get_answer("\n\r");
return(0);
}

View File

@ -0,0 +1,50 @@
It is common for BBS door programs to accept command line parameters
that permit various door-related settings, such as the serial port, baud
rate, and node number. This tip demonstrates how you can do this when
working with OpenDoors. This tip is presented in the following files:
cmdline.h - Header file for command line processing function.
cmdline.c - Implementation of command line processing function.
tip4.c - Example of a program that uses the command line
processing function.
The cmdline.c module implements the ParseStandardCommandLine() function,
which takes as its parameters the same argc and argv parameters that are
passed to the main() function of any C program. The
ParseStandardCommandLine() function then sets the appropriate OpenDoors
settings based on the following optional command-line parameters:
-L or -LOCAL - Causes door to operate in local mode, without
requiring a door information (drop) file.
-B x or -BPS x - Sets the bps (baud) rate to use.
-P x or -PORT x - Sets the serial port to use, were 0=COM1, 1=COM2,
etc.
-N x or -NODE x - Sets the node number to use.
-?, -H or -HELP - Displays command-line help and exits
-PERSONALITY x - Sets the sysop status line / function key
personality to use.
-MAXTIME x - Sets the maximum number of minutes that any
user will be permitted to access the door.
-ADDRESS x - Sets serial port address, to be used if FOSSIL
driver is not being used.
-IRQ x - Sets the serial port IRQ line, to be used if
FOSSIL driver is not being used.
-NOFOSSIL - Disables use of FOSSIL driver, even if it is
present.
-NOFIFO - Disables use of 16550 FIFO buffers (only if
FOSSIL driver is not being used).
-DROPFILE x - Door information file directory or
directory+filename.
-USERNAME x - Name of user who is currently online.
-TIMELEFT x - User's time remaining online.
-SECURITY x - User's security level.
-LOCATION x - Location from which user is calling.
Note that any information that is available from the door information
file overrides information provided on the command-line. If sufficient
parameters are provided on the command-line, the door can be operated
without a door information file. In order to do this, cmdline.c provides
a callback function that you can hook into od_control.od_no_file_func,
as demonstrated in tip4.c.
Case is not sensitive in the names of command line arguments.

View File

@ -0,0 +1 @@
make -fDOS.mak -DTARGET=l > out.txt

Some files were not shown because too many files have changed in this diff Show More