home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 December
/
simtel1292_SIMTEL_1292_Walnut_Creek.iso
/
msdos
/
packet
/
cbbs60so.arc
/
MBUTIL.C
< prev
next >
Wrap
Text File
|
1989-02-19
|
16KB
|
807 lines
/*
* MBUTIL.C - 2/17/88 - Utility functions.
*/
#include "mb.h"
static char *onoff[2] = { "off", "on" };
/*
* ! Command: Do DOS command ...
*/
dosys()
{
strcpy(tmp->scr, port->line + 2);
remnl(tmp->scr);
if (system(tmp->scr)) perror("Error");
}
/*
* Sort utility.
* base is the start of the array of items.
* n is the number of items.
* w is the item size.
* t is scratch space the size of one item.
*/
sort(base, n, w, t)
char *base;
int n;
int w;
char *t;
{
register int i;
register int j;
register int g;
char *p1, *p2;
for (g = n/2; g; g /= 2)
for (i = g; i < n; i++)
for (j = i - g; j >= 0; j -= g)
{
p1 = base + (w * j);
p2 = base + (w * (j + g));
if (strncmp(p1, p2, w) <= 0) break;
memcpy(t, p1, w);
memcpy(p1, p2, w);
memcpy(p2, t, w);
}
}
/*
* Return number of days between two dates.
*/
ddiff(fr, to)
char fr[], to[];
{
register int d;
static short dpm[13] =
{ 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
d = 365 * (10 * (to[0] - fr[0]) + to[1] - fr[1]);
d += (dpm[10 * (to[2] - '0') + to[3] - '0'] -
dpm[10 * (fr[2] - '0') + fr[3] - '0']);
d += 10 * (to[4] - fr[4]) + to[5] - fr[5];
return d;
}
/*
* Wild card match of callsigns with ? and * in first arg.
*/
wcm(s1, s2)
char *s1, *s2;
{
register short l;
if (*s1 is '*') if (matchn(s2, cport->user->call, ln_call)) return false;
for (l = 0; l < ln_call; l++, s1++, s2++)
{
if (*s1 is '*') return true;
if (*s1 isnt '?') if (*s1 isnt *s2) return false;
}
return true;
}
/*
* Save remote sysop command, for later execution.
*/
savecmd()
{
strcpy(scmd, port->line);
s_param setbit s_cmd;
port->msg = mdone;
}
/*
* EP command: change port parameters.
*/
edport()
{
register PORTS *p;
register int i;
if ((p = findport(*port->fld[1])) is NULL) { port->msg = mnport; return; }
sprintf(tmp->scr, "Change parameters for port %c, %s\n\n", p->id, p->name);
outstr(tmp->scr);
while (true)
{
outstr("Bbs Down Up Gate Illegal Monitor Remote Xparent 1 2 3 Time Cdigi Fwd Error\n");
sprintf(tmp->scr,"%c %c %c %c %c %c %c %c %c %c %c %-3d %d %-2d %d\n",
(p->priv & p_bbs)/p_bbs +'0',
(p->priv & p_dnload)/p_dnload +'0', (p->priv & p_upload)/p_upload +'0',
(p->priv & p_gate)/p_gate +'0', (p->priv & p_ilcal)/p_ilcal +'0',
(p->priv & p_mon)/p_mon +'0', (p->priv & p_sysop)/p_sysop +'0',
p->tmode +'0',p->ecmon +'0', p->ecuser +'0', p->eccmds +'0',
p->ctime, p->ndigi, p->fwdmin, p->errmax);
outstr(tmp->scr);
getcmd();
if (port->mode & gone) return;
i = atoi(port->fld[1]);
switch(port->opt1)
{
case 'B' : p->priv flipbit p_bbs; break;
case 'C' : p->ndigi = i; break;
case 'D' : p->priv flipbit p_dnload; break;
case 'E' : p->errmax = i; break;
case 'F' : p->fwdmin = i; break;
case 'G' : p->priv flipbit p_gate; break;
case 'I' : p->priv flipbit p_ilcal; break;
case 'M' : p->priv flipbit p_mon; break;
case 'R' : p->priv flipbit p_sysop; break;
case 'T' : p->ctime = i; break;
case 'U' : p->priv flipbit p_upload; break;
case 'X' : p->tmode = 1 - p->tmode; break;
case '1' : p->ecmon = 1 - p->ecmon; break;
case '2' : p->ecuser = 1 - p->ecuser; break;
case '3' : p->eccmds = 1 - p->eccmds; break;
default : if (!port->opt1) return;
}
}
}
/*
* ES command: change system parameters.
*/
chgparam()
{
register int i;
while (true)
{
outstr("Bell Kill F&B-kill Svc-msg\n");
sprintf(tmp->scr, "%c %c %c %c\n",
(s_param & s_page)/s_page+'0', (s_param & s_kill)/s_kill+'0',
(s_param & s_fkill)/s_fkill+'0', (s_param & s_svc)/s_svc+'0');
outstr(tmp->scr);
getcmd();
if (port->mode & gone) return;
switch(port->opt1)
{
case 'B' : s_param flipbit s_page; break;
case 'F' : s_param flipbit s_fkill; break;
case 'K' : s_param flipbit s_kill; break;
case 'S' : s_param flipbit s_svc; break;
default : if(!port->opt1) return;
}
}
}
/*
* Screen paging.
*/
char *pausemsg;
static char *pghdr = NULL;
static short lnmax;
static short lncnt;
/*
* If local console, pause until user types a character.
* Return the character.
* If not local console, just return a blank.
*/
char pause()
{
register char t;
if (port->mode is local)
if (!pt_flag)
{
prtx(pausemsg);
t = inchar();
outchar('\n');
return toupper(t);
}
return ' ';
}
/*
* Start screen paging.
*/
pgst(cp)
char *cp;
{
if ((pghdr = cp) is NULL) lnmax = 23; else lnmax = 22;
lncnt = lnmax;
}
/*
* Pause if full screen.
*/
char pgck()
{
if (--lncnt) return ' ';
lncnt = lnmax;
return pause();
}
/*
* Display header if at top of screen.
*/
pghd()
{
if (lncnt is lnmax) if (pghdr isnt NULL) outstr(pghdr);
}
/*
* Pause if required at last line.
*/
pgdn()
{
if (lncnt isnt lnmax) pause();
}
/*
* Display "no such file" message, and file name.
*/
nofile(c)
char *c;
{
prtx(mnfile); outstr(c); outchar('\n');
}
/*
* Memory allocation problem, just plain quit.
*/
errall()
{
outstr("Not enough memory\n");
exit (0);
}
/*
* Is this a callsign?
*/
iscall(c)
char *c;
{
register short i, ld, nd;
nd = 0;
for (i = 0; (i < ln_call) and (*c isnt ' '); i++, c++)
{
if (ld = isdigit(*c)) nd++;
}
return ((i > 3) and ((nd is 1) or (nd is 2)) and !ld);
}
/*
* Print list of ports and port names.
*/
shports()
{
register PORTS *p;
sprintf(port->line, "Use %c and port ID:\n", port->opt1);
outstr(port->line);
for (p = porthd; p isnt NULL; p = p->next)
{
sprintf(port->line, "%c%c %s\n", port->opt1, p->id, p->name);
outstr(port->line);
}
}
/*
* Return pointer to port with id pid, or NULL.
*/
PORTS *findport(pid)
char pid;
{
register PORTS *p;
for (p = porthd; p isnt NULL; p = p->next) if (p->id is pid) return p;
return NULL;
}
/*
* Is it?
*/
iseof(cp)
char *cp;
{
return match(cp, "*** EOF\n");
}
/*
* Remove new line and control characters from end of string.
*/
remnl(p)
char *p;
{
for (; *p; p++)
{
if (*p is '\n') { *p = '\0'; return; }
if (*p < ' ') *p = ' ';
}
}
/*
* Parse a callsign.
* Blank pad the output field, remove trailing ssid from call.
* Return the SSID.
*/
pcall(c, p)
char *c;
char *p;
{
register short i;
/*
* Blank fill the target buffer.
*/
fill (c, ' ', ln_call);
/*
* Ignore leading spaces.
*/
while (*p and (*p is ' ')) p++;
/*
* Copy the call from the string into the call buffer.
*/
for (i = ln_call; i and *p; i--)
{
if (*p <= ' ') return 0;
if (*p is '-') return atoi(++p);
if (*p is '.') return 0;
*c++ = *p++;
}
if (*p++ is '-') return atoi(p); else return 0;
}
/*
* Is the string a number?
*/
num(p)
char *p;
{
for (; *p; p++) if (!isdigit(*p)) return false;
return true;
}
/*
* "Output, no blanks".
*/
outnb(p, n)
char *p;
short n;
{
while (n--) switch (*p)
{
case ' ' :
case '\n' :
case '\0' : return;
default: outchar(*p++);
}
}
/*
* Print a number right justified in a fixed width field.
*/
outnr(i, n)
int i; /* The number to print */
short n; /* Field width */
{
char num[7];
sprintf (num, "%-6u", i);
outnb (num, n);
}
/*
* Display software version.
*/
prtver()
{
outstr(ver); outchar('\n');
}
/*
* Print multi-line message.
*/
prtm(m)
MLM *m;
{
register MLM *p;
for (p = m; p isnt NULL; p = p->next) prtx(p->text);
}
/*
* Print a string, expanding the "$" fields.
*/
prtx(p)
char *p;
{
for (; *p; p++)
{
if (*p isnt '$') outchar(*p);
else switch (*(++p))
{
case 'A' : outnb(port->mmhs->bbs, ln_call); break;
case 'B' : outchar(port->mmhs->type); break;
case 'C' : outnr(mfhs->next_msg, 5); break;
case 'D' : outstr(l_date); break;
case 'E' : outstr(port->mmhs->title); break;
case 'F' : outstr(port->lport->name); break;
case 'G' : outnb(port->mmhs->to, ln_call); break;
case 'H' : p++; break;
case 'I' : outnb(port->user->handle, ln_handle); break;
case 'J' : outnb(port->mmhs->date, ln_date); break;
case 'K' : outnb(port->mmhs->time, ln_time); break;
case 'L' : outnr(mfhs->next_msg - 1, 5); break;
case 'M' : outnr(port->mmhs->number, 5); break;
case 'N' : outnr(mfhs->count, 4); break;
case 'O' : outnb(cport->user->call, ln_call); break;
case 'P' : outnb(port->mmhs->from, ln_call); break;
case 'Q' : outstr(qth); break;
case 'R' : outnb(port->rcall, ln_call); break;
case 'S' : outnb(port->lport->user->call, ln_call); break;
case 'T' : outnb(l_time, ln_time); break;
case 'U' : outnb(port->user->call, ln_call); break;
case 'V' : outstr(ver); break;
case 'W' : outnb(port->lport->user->handle, ln_handle); break;
case 'X' : outnb(port->user->date, ln_date); break;
case 'Y' : outnb(port->user->time, ln_time); break;
case 'Z' : outnr(port->user->msg_number, 5); break;
case 'a' : outstr(orgbbs); break;
case 'h' : outstr(port->mmhs->call); break;
case 'j' : outstr(orgdate); break;
case 'k' : outstr(orgtime); break;
case 'm' : outstr(orgmsg); break;
default : outchar(*p);
}
}
}
/*
* Write random record.
*/
write_rec(fid, rec, buffer)
int fid;
int rec;
char buffer[];
{
long lseek();
long offs;
offs = (long)rec * (long)RECSIZE;
lseek(fid, offs, 0);
return (write(fid, buffer, RECSIZE) is RECSIZE);
}
/*
* Read random record.
*/
read_rec(fid, rec, buffer)
int fid;
int rec;
char buffer[];
{
long lseek();
long offs;
offs = (long)rec * (long)RECSIZE;
lseek(fid, offs, 0);
return (read(fid, buffer, RECSIZE) is RECSIZE);
}
/*
* Fill buffer with characters from the current input,
* until CR or buffer overflow. Terminate buffer with
* '\0', thus making it a string.
* Translate \r to \n.
* Ignore \n.
* Deal with backspace and things like that.
* Set flags for timeout and disconnect.
*/
getdat()
{
register char *cp;
register PORTS *p;
register char ch;
p = port;
if (p->flags & p_dotmr)
{
if ((p->mode & idle) and (p->dev is p_tnc)) settmr(&p->itime, 2);
else settmr(&p->itime, p->ctime);
}
p->flags setbit p_dotmr;
cp = p->line;
while (true)
{
while(!instat())
{
if (p isnt cport)
{
ioport(cport);
if (instat())
{
ch = inchar();
if (ch is achar)
{
p->mode = forced;
ioport(p);
return true;
}
if (ch is tchar)
{
p->flags setbit p_opreq;
ioport(p);
return true;
}
}
ioport(p);
}
if (p->flags & p_trans)
if (!isdcd())
{
if (!(p->mode & idle)) p->mode = discon;
return true;
}
if (!chktmr(p->itime))
{
*cp = '\0';
if (!(p->mode & idle)) p->mode = timeout;
return true;
}
}
*cp = inchar();
/*
* Got a character, deal with it.
*/
if ((cp is (p->line + linelen - 2)) or (*cp is '\r'))
{
/*
* Got a whole line. Either buffer full, or character is CR.
*/
if (*cp is '\r') *cp = '\n';
cp++; *cp = '\0';
if (p->flags & p_echo) outchar('\n');
if (!(p->flags & p_trans))
{
if (isdis(p->line))
{
if (!(p->mode & idle)) p->mode = discon;
return true;
}
if (isretry(p->line)) return false;
if (isreq(p->line))
{
p->flags setbit p_req;
pcall(p->rcall, p->line + 20);
p->flags clrbit p_dotmr;
return false;
}
}
return true;
}
/*
* Not end of line.
* Stuff the character in the buffer.
* Handle some control characters. Ignore some.
*/
switch(*cp)
{
default : if (p->flags & p_echo) outchar(*cp); cp++; break;
case '\b' :
if (cp > p->line) { cp--; if (p->flags & p_echo) outstr("\b \b"); }
break;
case '\n' : if (cp is p->line) { *cp = '\0'; return false; }
case '\0' : ; /* Ignore most ctl char */
case ctl_c: ; /* Ignore most ctl char */
case ctl_v: ; /* Ignore most ctl char */
}
}
}
/*
* Is the string a header line?
*/
ishead(p)
char *p;
{
if (!*p or (*p is '\n')) return false; /* end of headers */
if (strnicmp(p, "R:" ,2) and strnicmp(p, "I:", 2)) return false;
return true;
}
/*
* Parse a command line.
*
* Input: Line of text in port->line.
* Returns: Fields are placed in port->cmd.
* Fields are pointed to by port->fld[].
* port->flds is set to the number of fields found.
* Each field is null-terminated.
* Fields beyond maxflds are ignored.
*/
parse()
{
register short bl;
register char *in, *out;
for (port->flds = 0; port->flds < maxflds;)
port->fld[port->flds++] = nullstr;
in = port->line;
out = port->cmd;
bl = false;
port->flds = 0;
while (*in and (port->flds < maxflds) and (out < (port->cmd + cmdlen - 1)))
{
*out = toupper(*in);
if (bl)
{
if ((*in <= ' ') or ((*in is '@') and (port->flds is 2)))
{
bl = false;
*out = '\0';
if (*in is '@')
{
out++;
*out = '@';
port->fld[port->flds++] = out++;
*out = '\0';
}
}
out++;
}
else
{
if (*in > ' ')
{
bl = true;
port->fld[port->flds++] = out++;
}
}
in++;
}
*out = '\0';
port->opt1 = *port->fld[0];
port->opt2 = *(port->fld[0] + 1);
if (!port->opt2) port->opt2 = ' ';
}
/*
* Bundle getdat and parse.
*/
getcmd()
{
while(!getdat());
parse();
}
/*
* Fill some memory with a character.
*/
fill(adr, ch, len)
char *adr;
char ch;
int len;
{
while (len--) *adr++ = ch;
}
/*
* Copy C string to LJSF string.
*/
ljsf(to, from, size)
char *to;
char *from;
int size;
{
fill(to, ' ', size);
while (size--)
{
if (*from < ' ') return;
*to++ = *from++;
}
}
/*
* Copy LJSF string to C string.
*/
unbl(to, from, size)
char *to, *from;
int size;
{
while (size--)
{
if (*from <= ' ') { *to = '\0'; return; }
*to++ = *from++;
}
*to = '\0';
}
/*
* Are you sure? .....
*/
sure()
{
outstr("Are you sure (Y/N)?\n");
while (!getdat());
if (toupper(*port->line) is 'Y') return false;
return true;
}
/* Search string for match */
search(a,b,c)
char *a, *b;
int c;
{
for( ; *a; a++)
if (matchn(a, b, c)) return true;
return false;
}