Finished internal protocols

This commit is contained in:
Michiel Broek 2004-11-28 15:19:26 +00:00
parent ac2c34c9d5
commit 70792652c8
4 changed files with 511 additions and 336 deletions

View File

@ -37,25 +37,14 @@ v0.71.0 27-Oct-2004
troubles to implement right then it's worth these days. This
is caused by telnet connections when we never know what the
real linespeed is with to/from the user.
Added internal zmodem download and upload protocol. Not yet
enabled for public use, this will be done when it's ready.
The receiver will accept non-standard zmodem 8k blocks. The
sender is normal zmodem or zmodem-8K.
TODO: uploads smaller then blocksize seems to fail with
Dynacomm.
With user chat, the timeout timer wasn't refreshed.
Rewrote the rewritten terminal i/o to get zmodem upload to
work.
Added ymodem and xmodem download protocols, both with option
for 1k blocks. Not yet enabled for public use also.
Added the following internal file transfer protocols: Xmodem,
Ymodem, Ymodem-1K, Ymodem-G, Zmodem and Zmodem-8K (aka ZedZap).
Xmodem should not be used, but is available because Ymodem is
available.
For mode information see the manual setup/protocol.html.
After upload, files are now stored correctly in the filebase.
In change protocol, changed the colors.
Note: you could enable the internal protocols by adding these
to the protocol setup. But I recommend against it because not
yet all safety checks for uploads are installed. When the time
is right I will change mbsetup so that these protocols will be
automatic added.
With user chat, the timeout timer wasn't refreshed.
mbnewusr:
Rewrote terminal i/o.
@ -67,6 +56,9 @@ v0.71.0 27-Oct-2004
mbsetup:
In file transfers edit, removed switches for batch and bidirect
protocols, added a switch for internal protocols.
New internal protocols are automatic added and the external
protocols are disabled. Some fields of the internal protocols
are protected.
In file areas, free downloads is now default for new areas.
lang:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -14,22 +14,37 @@
</HEAD>
<BODY>
<BLOCKQUOTE>
<div align='right'><h5>Last update 15-Jun-2002</h5></div>
<div align='center'><H1>MBSE BBS Setup - BBS Setup - Transfer Protocols.</H1></div>
<div align='right'><h5>Last update 28-Nov-2004</h5></div>
<div align='center'><H1>MBSE BBS Setup - BBS Setup - File Transfer Protocols.</H1></div>
<H3>Introduction.</H3>
<p>
It might look strange that you have to define transfer protocols for the bbs
while for the mailer you don't need to do that. This is historic, ifcico
already had internal protocols and the precessor of the bbs package had external
protocols. Because my priority was make the bbs working it still is that way.
When time comes I will build some of the protocols internal, adding external
protocols will allways be possible.
MBSE BBS has Xmodem, Ymodem, Ymodem-1K, Ymodem-G, Zmodem and Zmodem-8K (aka
ZedZap) build in. In addition some external protocols are added to the setup but
they are disabled by default. When the bbs is started the first time, a set of
default protocols is created. The code used is based on the code from lrzsz
package wich is based in the original code written by Chuck Forsberg.
<p>
When you configured the sources and build mbse, the configure script searched
for excisting transfer protocols. When mbsetup was run the first time, when mbtask was
started, the protocols found on your system are already configured with the
right paths and enabled.
Ymodem is receiver driven. That means if the user has selected plain Ymodem at
the bbs and
his local client is using Ymodem-G and when the user starts a download, the files are
sent with Ymodem-G and not with plain Ymodem. With the same configuation an
upload will be sent with plain Ymodem. With downloads, the Ymodem at the bbs
will use what the client wants: 128 or 1K data blocks, crc of checksum, normal or
streaming Ymodem-G.
<p>
Zmodem is transmitter driven. That means if the user has selected Zmodem-8K at
the bbs and his local client is using normal Zmodem and when the user starts a
download, the download is sent with Zmodem-8K. With the same configuration an
upload will be sent with plain Zmodem. With uploads, the Zmodem at the bbs
doesn't care what is being used, it will adapt to the client program.
<p>
These days (2004) nobody should use Xmodem anymore but when I wrote Ymodem you
also get Xmodem because they are the same. Only with Xmodem the user has to
type in the filename to both sides. If you enable it you are on your own and you
may need to change the sources to make it really work because I didn't add
typing in the filename at the bbs. Also, Xmodem is restricted to 8.3 filenames
and the bbs uses long filenames.
<P>&nbsp;<p>
<H3>Transfer Protocols Setup.</H3>
@ -40,13 +55,14 @@ right paths and enabled.
<strong>Upload </strong>The full path and filename and parameters to upload files.
<strong>Download </strong>The full path and filename and parameters to download files.
<strong>Available </strong>If this protocol is available.
<strong>Batching </strong>If this is a batching protocol.
<strong>Bi direct </strong>If this is a bi-directional protocol (Not supported yet).
<strong>Internal </strong>If this is internal or external protocol.
<strong>Advice </strong>A small advice to the user shown before the transfer starts.
<strong>Efficiency </strong>The efficiency in percent. Has no real meaning.
<strong>Deleted </strong>If this protocol must be deleted.
<strong>Sec. level </strong>The security level a user must have to select this protocol.
</pre>
Some fields cannot be changed when this is an internal protocol, they are
hardcoded.
<P>
<IMG SRC="../images/protocol.png" alt='File transfer protocols'>
<P>

View File

@ -41,6 +41,8 @@
int ProtUpdated = 0;
int ProtRecords = 0;
/*
@ -61,75 +63,106 @@ int CountProtocol(void)
PROThdr.recsize = sizeof(PROT);
fwrite(&PROThdr, sizeof(PROThdr), 1, fil);
/*
* Write default set of protocols
*/
memset(&PROT, 0, sizeof(PROT));
sprintf(PROT.ProtKey, "1");
sprintf(PROT.ProtKey, "A");
sprintf(PROT.ProtName, "Ymodem");
if (strlen(_PATH_SB) && strlen(_PATH_RB)) {
sprintf(PROT.ProtUp, "%s -v", _PATH_RB);
sprintf(PROT.ProtDn, "%s -v -u", _PATH_SB);
PROT.Available = TRUE;
} else {
sprintf(PROT.ProtUp, "/usr/bin/rb -v");
sprintf(PROT.ProtDn, "/usr/bin/sb -v -u");
PROT.Available = FALSE;
}
PROT.Available = FALSE;
sprintf(PROT.Advice, "Press Ctrl-X to abort");
PROT.Efficiency = 92;
PROT.Efficiency = 75;
fwrite(&PROT, sizeof(PROT), 1, fil);
sprintf(PROT.ProtKey, "B");
sprintf(PROT.ProtName, "Ymodem-1K");
if (strlen(_PATH_SB) && strlen(_PATH_RB)) {
sprintf(PROT.ProtUp, "%s -k -v", _PATH_RB);
sprintf(PROT.ProtDn, "%s -k -v -u", _PATH_SB);
} else {
sprintf(PROT.ProtUp, "/usr/bin/rb -k -v");
sprintf(PROT.ProtDn, "/usr/bin/sb -k -v -u");
}
PROT.Efficiency = 82;
fwrite(&PROT, sizeof(PROT), 1, fil);
sprintf(PROT.ProtKey, "C");
sprintf(PROT.ProtName, "Zmodem");
if (strlen(_PATH_SZ) && strlen(_PATH_RZ)) {
sprintf(PROT.ProtUp, "%s -p -v", _PATH_RZ);
sprintf(PROT.ProtDn, "%s -b -q -r -u", _PATH_SZ);
} else {
sprintf(PROT.ProtUp, "/usr/bin/rz -p -v");
sprintf(PROT.ProtDn, "/usr/bin/sz -b -q -r -u");
}
PROT.Efficiency = 98;
fwrite(&PROT, sizeof(PROT), 1, fil);
memset(&PROT, 0, sizeof(PROT));
sprintf(PROT.ProtKey, "L");
sprintf(PROT.ProtName, "Local disk");
sprintf(PROT.ProtUp, "%s/bin/rf", getenv("MBSE_ROOT"));
sprintf(PROT.ProtDn, "%s/bin/sf", getenv("MBSE_ROOT"));
sprintf(PROT.Advice, "It goes before you know");
PROT.Available = FALSE;
PROT.Level.level = 32000;
PROT.Efficiency = 100;
fwrite(&PROT, sizeof(PROT), 1, fil);
memset(&PROT, 0, sizeof(PROT));
sprintf(PROT.ProtKey, "Y");
sprintf(PROT.ProtName, "Ymodem 1K");
if (strlen(_PATH_SB) && strlen(_PATH_RB)) {
sprintf(PROT.ProtUp, "%s -k -v", _PATH_RB);
sprintf(PROT.ProtDn, "%s -k -v -u", _PATH_SB);
PROT.Internal = TRUE;
PROT.Available = TRUE;
} else {
sprintf(PROT.ProtUp, "/usr/bin/rb -k -v");
sprintf(PROT.ProtDn, "/usr/bin/sb -k -v -u");
PROT.Available = FALSE;
}
sprintf(PROT.Advice, "Press Ctrl-X to abort");
PROT.Efficiency = 95;
sprintf(PROT.ProtKey, "1");
sprintf(PROT.ProtName, "Ymodem-1K");
PROT.Efficiency = 82;
fwrite(&PROT, sizeof(PROT), 1, fil);
sprintf(PROT.ProtKey, "8");
sprintf(PROT.ProtName, "Zmodem-8K (ZedZap)");
PROT.Efficiency = 99;
fwrite(&PROT, sizeof(PROT), 1, fil);
sprintf(PROT.ProtKey, "G");
sprintf(PROT.ProtName, "Ymodem-G");
PROT.Efficiency = 90;
fwrite(&PROT, sizeof(PROT), 1, fil);
PROT.Available = FALSE;
sprintf(PROT.ProtKey, "X");
sprintf(PROT.ProtName, "Xmodem");
PROT.Efficiency = 75;
fwrite(&PROT, sizeof(PROT), 1, fil);
PROT.Available = TRUE;
sprintf(PROT.ProtKey, "Y");
sprintf(PROT.ProtName, "Ymodem");
PROT.Efficiency = 75;
fwrite(&PROT, sizeof(PROT), 1, fil);
memset(&PROT, 0, sizeof(PROT));
sprintf(PROT.ProtKey, "Z");
sprintf(PROT.ProtName, "Zmodem");
if (strlen(_PATH_SZ) && strlen(_PATH_RZ)) {
sprintf(PROT.ProtUp, "%s -p -v", _PATH_RZ);
sprintf(PROT.ProtDn, "%s -b -q -r -u", _PATH_SZ);
PROT.Available = TRUE;
} else {
sprintf(PROT.ProtUp, "/usr/bin/rz -p -v");
sprintf(PROT.ProtDn, "/usr/bin/sz -b -q -r -u");
PROT.Available = FALSE;
}
sprintf(PROT.Advice, "Press Ctrl-X to abort");
PROT.Efficiency = 98;
PROT.Efficiency = 92;
fwrite(&PROT, sizeof(PROT), 1, fil);
fclose(fil);
chmod(ffile, 0640);
return 4;
} else
ProtUpdated = 1;
return 10;
} else {
return -1;
}
} else {
fread(&PROThdr, sizeof(PROThdr), 1, fil);
fseek(fil, 0, SEEK_END);
count = (ftell(fil) - PROThdr.hdrsize) / PROThdr.recsize;
fclose(fil);
}
return count;
}
@ -145,14 +178,17 @@ int OpenProtocol(void);
int OpenProtocol(void)
{
FILE *fin, *fout;
char fnin[PATH_MAX], fnout[PATH_MAX];
char fnin[PATH_MAX], fnout[PATH_MAX], newkey = 'A', *usedkeys;
long oldsize;
int AddInt = TRUE;
sprintf(fnin, "%s/etc/protocol.data", getenv("MBSE_ROOT"));
sprintf(fnout, "%s/etc/protocol.temp", getenv("MBSE_ROOT"));
if ((fin = fopen(fnin, "r")) != NULL) {
if ((fout = fopen(fnout, "w")) != NULL) {
fread(&PROThdr, sizeof(PROThdr), 1, fin);
usedkeys = xstrcpy((char *)"18GXYZ");
/*
* In case we are automaic upgrading the data format
* we save the old format. If it is changed, the
@ -162,8 +198,22 @@ int OpenProtocol(void)
if (oldsize != sizeof(PROT)) {
ProtUpdated = 1;
Syslog('+', "Upgraded %s, format changed", fnin);
} else
ProtUpdated = 0;
}
/*
* First check if the database needs upgrade with internal
* protocols.
*/
while (fread(&PROT, oldsize, 1, fin) == 1) {
if (PROT.Internal) {
AddInt = FALSE;
usedkeys = xstrcat(usedkeys, PROT.ProtKey);
}
}
fseek(fin, PROThdr.hdrsize, SEEK_SET);
if (AddInt)
Syslog('+', "Will add new internal transfer protocols");
PROThdr.hdrsize = sizeof(PROThdr);
PROThdr.recsize = sizeof(PROT);
fwrite(&PROThdr, sizeof(PROThdr), 1, fout);
@ -175,12 +225,72 @@ int OpenProtocol(void)
*/
memset(&PROT, 0, sizeof(PROT));
while (fread(&PROT, oldsize, 1, fin) == 1) {
if (!PROT.Internal) {
/*
* Check selection key, if it is one of the new
* internal ones, change the key. Also disable
* the external protocols.
*/
if (strstr(usedkeys, PROT.ProtKey)) {
Syslog('+', "Change external protocol %s key %s to %c", PROT.ProtName, PROT.ProtKey, newkey);
sprintf(PROT.ProtKey, "%c", newkey);
newkey++;
ProtUpdated = 1;
}
if (AddInt && PROT.Available) {
Syslog('+', "Disable external protocol %s", PROT.ProtName);
PROT.Available = FALSE;
ProtUpdated = 1;
}
}
fwrite(&PROT, sizeof(PROT), 1, fout);
memset(&PROT, 0, sizeof(PROT));
}
if (AddInt) {
Syslog('+', "Adding new internal protocols");
memset(&PROT, 0, sizeof(PROT));
PROT.Internal = TRUE;
PROT.Available = TRUE;
sprintf(PROT.Advice, "Press Ctrl-X to abort");
sprintf(PROT.ProtKey, "1");
sprintf(PROT.ProtName, "Ymodem-1K");
PROT.Efficiency = 82;
fwrite(&PROT, sizeof(PROT), 1, fout);
sprintf(PROT.ProtKey, "8");
sprintf(PROT.ProtName, "Zmodem-8K (ZedZap)");
PROT.Efficiency = 99;
fwrite(&PROT, sizeof(PROT), 1, fout);
sprintf(PROT.ProtKey, "G");
sprintf(PROT.ProtName, "Ymodem-G");
PROT.Efficiency = 90;
fwrite(&PROT, sizeof(PROT), 1, fout);
PROT.Available = FALSE;
sprintf(PROT.ProtKey, "X");
sprintf(PROT.ProtName, "Xmodem");
PROT.Efficiency = 75;
fwrite(&PROT, sizeof(PROT), 1, fout);
PROT.Available = TRUE;
sprintf(PROT.ProtKey, "Y");
sprintf(PROT.ProtName, "Ymodem");
PROT.Efficiency = 75;
fwrite(&PROT, sizeof(PROT), 1, fout);
sprintf(PROT.ProtKey, "Z");
sprintf(PROT.ProtName, "Zmodem");
PROT.Efficiency = 92;
fwrite(&PROT, sizeof(PROT), 1, fout);
ProtRecords += 6;
ProtUpdated = 1;
}
fclose(fin);
fclose(fout);
free(usedkeys);
return 0;
} else
return -1;
@ -210,7 +320,7 @@ void CloseProtocol(int force)
while (fread(&PROT, PROThdr.recsize, 1, fi) == 1)
if (!PROT.Deleted)
fill_stlist(&pro, PROT.ProtKey, ftell(fi) - PROThdr.recsize);
fill_stlist(&pro, PROT.ProtName, ftell(fi) - PROThdr.recsize);
sort_stlist(&pro);
for (tmp = pro; tmp; tmp = tmp->next) {
@ -227,6 +337,7 @@ void CloseProtocol(int force)
Syslog('+', "Updated \"protocol.data\"");
if (!force)
working(6, 0, 0);
ProtUpdated = 0;
return;
}
}
@ -323,6 +434,15 @@ int EditProtRec(int Area)
show_bool(15,21, PROT.Deleted);
show_sec( 16,21, PROT.Level);
if (PROT.Internal) {
set_color(BLUE, BLACK);
show_str( 8,21,20, PROT.ProtName);
show_bool(12,21, PROT.Internal);
show_str( 13,21,30, PROT.Advice);
show_int( 14,21, PROT.Efficiency);
show_bool(15,21, PROT.Deleted);
}
j = select_menu(10);
switch(j) {
case 0: crc1 = 0xffffffff;
@ -344,14 +464,35 @@ int EditProtRec(int Area)
IsDoing("Browsing Menu");
return 0;
case 1: E_UPS( 7,21,1, PROT.ProtKey, "The ^Key^ to select this protocol")
case 2: E_STR( 8,21,20,PROT.ProtName, "The ^name^ of this protocol")
case 3: E_STR( 9,21,50,PROT.ProtUp, "The ^Upload^ path, binary and parameters")
case 4: E_STR( 10,21,50,PROT.ProtDn, "The ^Download^ path, binary and parameters")
case 2: if (PROT.Internal)
errmsg((char *)"Editing not allowd with internal protocol");
else
E_STR( 8,21,20,PROT.ProtName, "The ^name^ of this protocol")
case 3: if (PROT.Internal)
errmsg((char *)"Editing not allowd with internal protocol");
else
E_STR( 9,21,50,PROT.ProtUp, "The ^Upload^ path, binary and parameters")
case 4: if (PROT.Internal)
errmsg((char *)"Editing not allowd with internal protocol");
else
E_STR( 10,21,50,PROT.ProtDn, "The ^Download^ path, binary and parameters")
case 5: E_BOOL(11,21, PROT.Available, "Is this protocol ^available^")
case 6: E_BOOL(12,21, PROT.Internal, "Is this a ^internal^ transfer protocol")
case 7: E_STR( 13,21,30,PROT.Advice, "A small ^advice^ to the user, eg \"Press Ctrl-X to abort\"")
case 8: E_INT( 14,21, PROT.Efficiency,"The ^efficiency^ in % of this protocol")
case 9: E_BOOL(15,21, PROT.Deleted, "Is this protocol ^Deleted^")
case 6: if (PROT.Internal)
errmsg((char *)"Editing not allowd with internal protocol");
else
E_BOOL(12,21, PROT.Internal, "Is this a ^internal^ transfer protocol")
case 7: if (PROT.Internal)
errmsg((char *)"Editing not allowd with internal protocol");
else
E_STR( 13,21,30,PROT.Advice, "A small ^advice^ to the user, eg \"Press Ctrl-X to abort\"")
case 8: if (PROT.Internal)
errmsg((char *)"Editing not allowd with internal protocol");
else
E_INT( 14,21, PROT.Efficiency,"The ^efficiency^ in % of this protocol")
case 9: if (PROT.Internal)
errmsg((char *)"Editing not allowd with internal protocol");
else
E_BOOL(15,21, PROT.Deleted, "Is this protocol ^Deleted^")
case 10:E_SEC( 16,21, PROT.Level, "8.5.11 PROTOCOL SECURITY LEVEL", s_protrec)
}
}
@ -363,7 +504,7 @@ int EditProtRec(int Area)
void EditProtocol(void)
{
int records, i, x;
int i, o = 0, y;
char pick[12];
FILE *fil;
char temp[PATH_MAX];
@ -377,8 +518,8 @@ void EditProtocol(void)
return;
}
records = CountProtocol();
if (records == -1) {
ProtRecords = CountProtocol();
if (ProtRecords == -1) {
working(2, 0, 0);
return;
}
@ -393,31 +534,35 @@ void EditProtocol(void)
set_color(WHITE, BLACK);
mbse_mvprintw( 5, 6, "8.5 PROTOCOL SETUP");
set_color(CYAN, BLACK);
if (records != 0) {
if (ProtRecords != 0) {
sprintf(temp, "%s/etc/protocol.temp", getenv("MBSE_ROOT"));
working(1, 0, 0);
if ((fil = fopen(temp, "r")) != NULL) {
fread(&PROThdr, sizeof(PROThdr), 1, fil);
x = 4;
y = 7;
set_color(CYAN, BLACK);
for (i = 1; i <= records; i++) {
offset = sizeof(PROThdr) + ((i - 1) * PROThdr.recsize);
for (i = 1; i <= 10; i++) {
if ((o + i) <= ProtRecords) {
offset = sizeof(PROThdr) + (((o + i) - 1) * PROThdr.recsize);
fseek(fil, offset, 0);
fread(&PROT, PROThdr.recsize, 1, fil);
if (i == 11)
x = 44;
if (PROT.Available)
if (PROT.Deleted)
set_color(LIGHTRED, BLACK);
else if (PROT.Available)
set_color(CYAN, BLACK);
else
set_color(LIGHTBLUE, BLACK);
sprintf(temp, "%3d. %s %-30s", i, PROT.ProtKey, PROT.ProtName);
temp[37] = '\0';
mbse_mvprintw(i + 6, x, temp);
sprintf(temp, "%3d. %1s %-20s %s %3d %-30s %5d", i, PROT.ProtKey, PROT.ProtName,
PROT.Internal?"Int":"Ext", PROT.Efficiency, PROT.Advice, PROT.Level.level);
mbse_mvprintw(y, 4, temp);
y++;
}
}
fclose(fil);
}
/* Show records here */
}
strcpy(pick, select_record(records, 20));
strcpy(pick, select_record(ProtRecords, 10));
if (strncmp(pick, "-", 1) == 0) {
CloseProtocol(FALSE);
@ -427,14 +572,24 @@ void EditProtocol(void)
if (strncmp(pick, "A", 1) == 0) {
working(1, 0, 0);
if (AppendProtocol() == 0) {
records++;
ProtRecords++;
working(1, 0, 0);
} else
working(2, 0, 0);
}
if ((atoi(pick) >= 1) && (atoi(pick) <= records))
if (strncmp(pick, "N", 1) == 0)
if ((o + 10) < ProtRecords)
o = o + 10;
if (strncmp(pick, "P", 1) == 0)
if ((o - 10) >= 0)
o = o - 10;
if ((atoi(pick) >= 1) && (atoi(pick) <= ProtRecords)) {
EditProtRec(atoi(pick));
o = ((atoi(pick) - 1) / 10) * 10;
}
}
}
@ -452,13 +607,12 @@ void InitProtocol(void)
char *PickProtocol(int nr)
{
static char Prot[21] = "";
int records, i, x;
int o = 0, i, x, y;
char pick[12];
FILE *fil;
char temp[PATH_MAX];
long offset;
clr_index();
working(1, 0, 0);
if (config_read() == -1) {
@ -466,30 +620,34 @@ char *PickProtocol(int nr)
return Prot;
}
records = CountProtocol();
if (records == -1) {
ProtRecords = CountProtocol();
if (ProtRecords == -1) {
working(2, 0, 0);
return Prot;
}
clr_index();
set_color(WHITE, BLACK);
sprintf(temp, "%d. PROTOCOL SELECT", nr);
mbse_mvprintw( 5, 4, temp);
set_color(CYAN, BLACK);
if (records != 0) {
if (ProtRecords) {
sprintf(temp, "%s/etc/protocol.data", getenv("MBSE_ROOT"));
working(1, 0, 0);
if ((fil = fopen(temp, "r")) != NULL) {
fread(&PROThdr, sizeof(PROThdr), 1, fil);
x = 2;
y = 7;
set_color(CYAN, BLACK);
for (i = 1; i <= records; i++) {
offset = sizeof(PROThdr) + ((i - 1) * PROThdr.recsize);
for (i = 1; i <= 20; i++) {
if (i == 11) {
x = 42;
y = 7;
}
if ((o + i) <= ProtRecords) {
offset = sizeof(PROThdr) + (((o + i) - 1) * PROThdr.recsize);
fseek(fil, offset, 0);
fread(&PROT, PROThdr.recsize, 1, fil);
if (i == 11)
x = 42;
if (PROT.Available)
set_color(CYAN, BLACK);
else
@ -497,14 +655,19 @@ char *PickProtocol(int nr)
sprintf(temp, "%3d. %s %-30s", i, PROT.ProtKey, PROT.ProtName);
temp[37] = '\0';
mbse_mvprintw(i + 6, x, temp);
y++;
}
strcpy(pick, select_pick(records, 20));
}
strcpy(pick, select_pick(ProtRecords, 20));
if ((atoi(pick) >= 1) && (atoi(pick) <= records)) {
if ((atoi(pick) >= 1) && (atoi(pick) <= ProtRecords)) {
offset = sizeof(PROThdr) + ((atoi(pick) - 1) * PROThdr.recsize);
fseek(fil, offset, 0);
fread(&PROT, PROThdr.recsize, 1, fil);
if (PROT.Available)
strcpy(Prot, PROT.ProtName);
else
errmsg((char *)"This protocol is not available");
}
fclose(fil);
}
@ -551,8 +714,10 @@ int bbs_prot_doc(FILE *fp, FILE *toc, int page)
fprintf(wp, "<COL width='30%%'><COL width='70%%'>\n");
fprintf(wp, "<TBODY>\n");
add_webtable(wp, (char *)"Selection key", PROT.ProtKey);
if (!PROT.Internal) {
add_webtable(wp, (char *)"Protocol name", PROT.ProtName);
add_webtable(wp, (char *)"Upload command", PROT.ProtUp);
}
add_webtable(wp, (char *)"Download command", PROT.ProtDn);
add_webtable(wp, (char *)"Available", getboolean(PROT.Available));
add_webtable(wp, (char *)"Internal protocol", getboolean(PROT.Internal));
@ -567,8 +732,10 @@ int bbs_prot_doc(FILE *fp, FILE *toc, int page)
fprintf(fp, " Selection key %s\n", PROT.ProtKey);
fprintf(fp, " Protocol name %s\n", PROT.ProtName);
if (!PROT.Internal) {
fprintf(fp, " Upload command %s\n", PROT.ProtUp);
fprintf(fp, " Download command %s\n", PROT.ProtDn);
}
fprintf(fp, " Available %s\n", getboolean(PROT.Available));
fprintf(fp, " Internal protocol %s\n", getboolean(PROT.Internal));
fprintf(fp, " User advice %s\n", PROT.Advice);