/* TFL.C
My very own file list generator for TAG BBS.
Reads TFL.CFG and generates lists based on info contained within.
*/
#include <alloc.h>
#include <ctype.h>
#include <dir.h>
#include <dos.h>
#include <mem.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* note: Martin's C structs are junk! these work however */
#include "tagrec.h"
#define CMD_NOTFOUND -1
#define CMD_FBOARDS 0
#define CMD_MFILEPATH 1
#define CMD_DFILEPATH 2
#define CMD_LISTHEADER 3
#define CMD_LISTFOOTER 4
#define CMD_AREAHEADER 5
#define CMD_AREAFOOTER 6
#define CMD_FORMAT 7
#define CMD_LIST 8
#define CMD_ENDLIST 9
#define CMD_UNVALIDATED 10
#define CMD_DSL 11
#define CMD_AR 12
#define CMD_BOARDS 13
#define CMD_CDROM 14
#define CMD_FIXSIZE 15
#define CMD_FIXDATE 16
#define CMD_OFFLINE 17
#define CMD_DOWNLOADS 18
#define CMD_ULAGE 19
#define CMD_FILEAGE 20
#define NO 0
#define YES 1
char *keywords[] =
{
/* list of all keywords to be found in the config file */
"FBOARDS", /* global only */
"MFILEPATH", /* global only */
"DFILEPATH", /* global only */
"LISTHEADER", /* global or local */
"LISTFOOTER", /* global or local */
"AREAHEADER", /* global or local */
"AREAFOOTER", /* global or local */
"FORMAT", /* global or local */
"LIST",
"ENDLIST",
"UNVALIDATED", /* local - allow unvalidated files */
"DSL", /* local - DSL's allowed */
"AR", /* local - AR flags allowed */
"BOARDS", /* local - list of board numbers */
"CDROM", /* local - allow CD-ROM files */
"FIXSIZE", /* local - fix file sizes */
"FIXDATE", /* local - set date to file date */
"OFFLINE", /* local - allow offline files */
"DOWNLOADS", /* local - minimum downloads numbers */
"ULAGE", /* local - ul file age */
"FILEAGE", /* local - real file age */
""
};
char inputline[256],
*ptr,
fboardname[80] = "",
listname[80] = "",
mfilepath[80] = "",
dfilepath[80] = "",
boardname[80], /* bbs name for this area */
boardfname[12], /* name of the .dir file [@]........ */
ulpath[80],
dlpath[80],
dirfname[80], /* full name of .dir file */
filename[16], /* just name of the file */
fname[80], /* full name of file */
description[80],
owner[40],
filedate[16],
uldate[16];
long ulage,
fileage,
ulsize,
filesize,
ulblocks,
fileblocks,
today;
int g_listheadercnt = 0,
g_listfootercnt = 0,
g_areaheadercnt = 0,
g_areafootercnt = 0,
g_formatcnt = 0;
char *g_listheader[32],
*g_listfooter[32],
*g_areaheader[32],
*g_areafooter[32],
*g_format[10];
int l_listheadercnt = 0,
l_listfootercnt = 0,
l_areaheadercnt = 0,
l_areafootercnt = 0,
l_formatcnt = 0;
char *l_listheader[32],
*l_listfooter[32],
*l_areaheader[32],
*l_areafooter[32],
*l_format[10];
int l_unvalidated = NO,
l_cdrom = NO,
l_fixsize = NO,
l_fixdate = NO,
l_offline = NO,
l_downloads = 0,
l_ulage = 0,
l_fileage = 0;
unsigned char l_bflags[128], /* support upto 1024 file areas */
l_dslflags[32], /* 256 dsl's */
l_arflags[4]; /* 24 ar's */
int l_bflagset,
l_dslflagset,
l_arflagset;
int missing,
linenum,
filenum,
boardnum,
areanum,
tareas,
*num;
char **list;
FILE *fboardfile = NULL,
*cfgfile = NULL,
*listfile,
*dirfile;
UlRec fboarddata;
int okay;
UlfRec dirdata,
dirheader;
struct ffblk ffblk;
long tsize,
ksize,
fsize;
/* function prototypes */
void xerror(char *str, ...);
char *fixline(char *str);
void setrflags(unsigned char *rflags, char *str);
void setbflags(unsigned char *bflags, char *str);
void setslflags(unsigned char *slflags, char *str);
void setbit(unsigned char *flags, int bitnum);
int checkbit(unsigned char *flags, int bitnum);
int findword(char *word, char *list[]);
char *strpastoc(char *c, char *pas);
void fsendf(FILE *f, char *str);
int isleap (unsigned yr);
static unsigned months_to_days (unsigned month);
static long years_to_days (unsigned yr);
long ymd_to_scalar (unsigned yr, unsigned mo, unsigned day);
void scalar_to_ymd (long scalar, unsigned *pyr, unsigned *pmo, unsigned *pday);
int main(int args, char *arglist[])
{
int inlist,
cmd,
c,
i,
j,
k,
len,
x,
bsize,
globaldone,
skip,
pass,
fixed;
unsigned int ulage2,
fileage2;
long pos,
areapos;
struct date d;
FILE *tempfile;
/* print welcome message */
printf("TFL v1.3 (c)1994 Aphelion Software\n");
printf("This program is released to the public domain\n");
/* call syntax: TFL <config file> */
if (args != 2)
xerror("Syntax: TFL <config file>");
/* open the config file */
if ((cfgfile = fopen(arglist[1], "r")) == NULL)
xerror("Config file not found.");
/* begin main loop */
inlist = NO;
linenum = 0;
printf("\nReading global information.\n");
globaldone = NO;
getdate(&d);
today = ymd_to_scalar(d.da_year, d.da_mon, d.da_day);
do
{
/* read a line in. */
if (fgets(inputline, 255, cfgfile) == NULL)
break;
/* remove excess stuff from inline */
linenum++;
if (fixline(inputline))
{
/* something in the line. process it */
if ((ptr = strtok(inputline, " ")) == NULL)
xerror("<%d> Invalid data in config file.", linenum);
/* execute the command */
cmd = findword(ptr, keywords);
switch (cmd)
{
case CMD_FBOARDS:
/* open fboard */
if (inlist)
xerror("<%d> FBoards is a global only command.", linenum);
if (*fboardname)
xerror("<%d> FBOARD.DAT specified more than once.", linenum);
if ((ptr = strtok(NULL, "= ")) == NULL)
xerror("<%d> Incomplete data in config file.", linenum);
strcpy(fboardname, ptr);
if ((fboardfile = fopen(fboardname, "rb")) == NULL)
xerror("<%d> Unable to open FBOARDS.DAT.", linenum);
printf("│ FBOARDS.DAT = %s\n", fboardname);
break;
case CMD_MFILEPATH:
if (inlist)
xerror("<%d> MFILE path is a global only command.", linenum);
if (*mfilepath)
xerror("<%d> MFILE path specified more than once.", linenum);
if ((ptr = strtok(NULL, "= ")) == NULL)
xerror("<%d> Incomplete data in config file.", linenum);
strcpy(mfilepath, ptr);
printf("│ MFILE path = %s\n", mfilepath);
break;
case CMD_DFILEPATH:
if (inlist)
xerror("<%d> DFilespath is a global only command.", linenum);
if (*dfilepath)
xerror("<%d> DFiles path specified more than once.", linenum);
if ((ptr = strtok(NULL, "= ")) == NULL)
xerror("<%d> Incomplete data in config file.", linenum);
strcpy(dfilepath, ptr);
printf("│ DFILE path = %s\n", dfilepath);
break;
case CMD_LISTHEADER:
if (!inlist)
{
num = &g_listheadercnt;
list = &g_listheader[*num];
}
else
{
num = &l_listheadercnt;
list = &l_listheader[*num];
}
if (*num >= 32)
xerror("<%d> Too many formats specified.", linenum);
ptr = strtok(NULL, "\"");
ptr = strtok(NULL, "\"");
*list = strdup(ptr);
(*num)++;
break;
case CMD_LISTFOOTER:
if (!inlist)
{
num = &g_listfootercnt;
list = &g_listfooter[*num];
}
else
{
num = &l_listfootercnt;
list = &l_listfooter[*num];
}
if (*num >= 32)
xerror("<%d> Too many formats specified.", linenum);
ptr = strtok(NULL, "\"");
ptr = strtok(NULL, "\"");
*list = strdup(ptr);
(*num)++;
break;
case CMD_AREAHEADER:
if (!inlist)
{
num = &g_areaheadercnt;
list = &g_areaheader[*num];
}
else
{
num = &l_areaheadercnt;
list = &l_areaheader[*num];
}
if (*num >= 32)
xerror("<%d> Too many formats specified.", linenum);
ptr = strtok(NULL, "\"");
ptr = strtok(NULL, "\"");
*list = strdup(ptr);
(*num)++;
break;
case CMD_AREAFOOTER:
if (!inlist)
{
num = &g_areafootercnt;
list = &g_areafooter[*num];
}
else
{
num = &l_areafootercnt;
list = &l_areafooter[*num];
}
if (*num >= 32)
xerror("<%d> Too many formats specified.", linenum);
ptr = strtok(NULL, "\"");
ptr = strtok(NULL, "\"");
*list = strdup(ptr);
(*num)++;
break;
case CMD_FORMAT:
if (!inlist)
{
num = &g_formatcnt;
list = &g_format[*num];
}
else
{
num = &l_formatcnt;
list = &l_format[*num];
}
if (*num >= 32)
xerror("<%d> Too many formats specified.", linenum);
ptr = strtok(NULL, "\"");
ptr = strtok(NULL, "\"");
*list = strdup(ptr);
(*num)++;
break;
case CMD_LIST:
if (inlist)
xerror("<%d> No ENDLIST found in config file.", linenum);
inlist = YES;
if (!globaldone)
{
globaldone = YES;
printf("└ done global info read\n", filenum);
}
if ((ptr = strtok(NULL, "= ")) == NULL)
xerror("<%d> Incomplete data in config file.", linenum);
strcpy(listname, ptr);
/* clear all local data */
memset((void *)l_bflags, 0xff, 128);
memset((void *)l_dslflags, 0xff, 32);
memset((void *)l_arflags, 0xff, 4);
l_bflagset = NO;
l_dslflagset = NO;
l_arflagset = NO;
for (i = 0; i < 10; i++)
{
if (i < l_listheadercnt)
free(l_listheader[i]);
if (i < l_listfootercnt)
free(l_listfooter[i]);
if (i < l_areaheadercnt)
free(l_areaheader[i]);
if (i < l_areafootercnt)
free(l_areafooter[i]);
if (i < l_formatcnt)
free(l_format[i]);
}
l_listheadercnt = 0;
l_listfootercnt = 0;
l_areaheadercnt = 0;
l_areafootercnt = 0;
l_formatcnt = 0;
l_unvalidated = NO;
l_cdrom = NO;
l_fixsize = NO;
l_fixdate = NO;
l_offline = NO;
l_downloads = -1,
l_ulage = -1,
l_fileage = -1;
printf("\nReading information for %s.\n", listname);
break;
case CMD_ENDLIST:
if (!inlist)
xerror("<%d> Found ENDLIST with no matching LIST.", linenum);
printf("│ Creating %s.\n", listname);
if ((listfile = fopen(listname, "w+")) == NULL)
xerror("Unable to create %s.", listname);
if (!l_listheadercnt)
{
for (i = 0; i < g_listheadercnt; i++)
l_listheader[i] = strdup(g_listheader[i]);
l_listheadercnt = g_listheadercnt;
}
if (!l_listfootercnt)
{
for (i = 0; i < g_listfootercnt; i++)
l_listfooter[i] = strdup(g_listfooter[i]);
l_listfootercnt = g_listfootercnt;
}
if (!l_areaheadercnt)
{
for (i = 0; i < g_areaheadercnt; i++)
l_areaheader[i] = strdup(g_areaheader[i]);
l_areaheadercnt = g_areaheadercnt;
}
if (!l_areafootercnt)
{
for (i = 0; i < g_areafootercnt; i++)
l_areafooter[i] = strdup(g_areafooter[i]);
l_areafootercnt = g_areafootercnt;
}
if (!l_formatcnt)
{
for (i = 0; i < g_formatcnt; i++)
l_format[i] = strdup(g_format[i]);
l_formatcnt = g_formatcnt;
}
/* -------- print the list header -------- */
for (i = 0; i < l_listheadercnt; i++)
fsendf(listfile, l_listheader[i]);
rewind(fboardfile);
boardnum = 0;
tareas = 0;
while (fread(&fboarddata, sizeof fboarddata, 1, fboardfile))
{
okay = YES;
/* is this board okay to use? */
if (!checkbit(&l_dslflags, fboarddata.DSL))
okay = NO;
if (!l_cdrom && (fboarddata.Flags.flag1 & ULRF_IsCdRom))
okay = NO;
if (!checkbit(&l_arflags, fboarddata.ArLvl - '@'))
okay = NO;
if (!checkbit(&l_bflags, boardnum))
okay = NO;
if (okay)
{
strpastoc(boardname, fboarddata.Name);
strpastoc(boardfname, fboarddata.Filename);
strpastoc(ulpath, fboarddata.UlPathName);
strpastoc(dlpath, fboarddata.DlPathname);
if (*boardfname == '`')
{
if (!*mfilepath)
xerror("No MFILE path specified.");
sprintf(dirfname, "%s%s.DIR",
mfilepath, &boardfname[1]);
}
else if (*boardfname == '@')
{
if (!*dfilepath)
xerror("No DFILE path specified.");
sprintf(dirfname, "%s%s.DIR",
dfilepath, &boardfname[1]);
}
else
sprintf(dirfname, "%s%s.DIR",
dlpath, boardfname);
if ((dirfile = fopen(dirfname, "r+b")) == NULL)
{
printf("│ Unable to open %s. Skipping.\n", dirfname);
okay = NO;
}
else
{
printf("│ (%4d) %s\n", boardnum, boardname);
filenum = 0;
for (pass = 0; pass < 2; pass++)
{
rewind(dirfile);
if (pass == 1)
{
/* -------- print the area header -------- */
tareas++;
for (i = 0; i < l_areaheadercnt; i++)
fsendf(listfile, l_areaheader[i]);
}
tsize = 0;
fread(&dirheader, sizeof dirheader, 1, dirfile);
pos = ftell(dirfile);
skip = YES;
while (fread(&dirdata, sizeof dirdata, 1, dirfile))
{
okay = YES;
strpastoc(filename, dirdata.Filename);
ptr = filename;
while (*ptr)
if (isspace(*ptr))
strcpy(ptr, ptr + 1);
else
ptr++;
strpastoc(description, dirdata.Description);
strpastoc(owner, dirdata.Owner);
sprintf(fname, "%s%s", ulpath, filename);
if (fboarddata.Flags.flag1 & ULRF_IsCdRom)
missing = NO;
else
missing = findfirst(fname, &ffblk, 0);
strpastoc(uldate, dirdata.Date);
ulage = ymd_to_scalar(
atoi(&uldate[6]) + 1900,
atoi(&uldate[0]),
atoi(&uldate[3]));
ulage2 = dirdata.DateN;
ulblocks = (long)dirdata.Blocks;
ulsize = ulblocks * 128L;
if (fboarddata.Flags.flag1 & ULRF_IsCdRom)
{
strcpy(filedate, uldate);
fileage = ulage;
fileage2 = (unsigned int)
(fileage - ymd_to_scalar(1985, 1, 1));
fileblocks = ulblocks;
filesize = ulsize;
}
else if (!missing)
{
sprintf(filedate, "%02d/%02d/%02d",
(ffblk.ff_fdate >> 5) & 0x000f,
(ffblk.ff_fdate >> 0) & 0x001f,
(((ffblk.ff_fdate >> 9) & 0x007f) + 1980) % 100);
fileage = ymd_to_scalar(
(((ffblk.ff_fdate >> 9) & 0x007f) + 1980),
(ffblk.ff_fdate >> 5) & 0x000f,
(ffblk.ff_fdate >> 0) & 0x001f);
fileage2 = (unsigned int)
(fileage - ymd_to_scalar(1985, 1, 1));
fileblocks = ffblk.ff_fsize / 128;
filesize = ffblk.ff_fsize;
}
else
{
strcpy(filedate, " ");
fileage = 0;
fileage2 = 0;
fileblocks = 0;
filesize = 0;
}
/* correct here */
if (pass == 0)
{
fixed = NO;
if ((ulblocks != fileblocks) && l_fixsize)
{
printf("│ %-14s %ld -> %ld blocks\n",
filename, ulblocks, fileblocks);
dirdata.Blocks = fileblocks;
fixed = YES;
ulsize = filesize;
ulblocks = fileblocks;
}
if (((fileage2 != dirdata.DateN) ||
(ulage != fileage)) &&
l_fixdate)
{
printf("│ %-14s %s -> %s\n",
filename, uldate, filedate);
dirdata.DateN = fileage2;
for (i = 0; i < 8; i++)
dirdata.Date[i + 1] = filedate[i];
fixed = YES;
ulage = fileage;
ulage2 = fileage2;
strcpy(uldate, filedate);
}
if (fixed)
{
fseek(dirfile, pos, SEEK_SET);
fwrite(&dirdata, sizeof dirdata, 1, dirfile);
}
}
/* okay to write file? */
if (!l_unvalidated && (dirdata.Flag.flag1 & FRS_NotValidated))
okay = NO;
if (!l_offline && missing)
okay = NO;
if ((l_fileage >= 0) &&
((today - fileage) > l_fileage))
okay = NO;
if ((l_ulage >= 0) &&
((today - ulage) > l_ulage))
okay = NO;
if ((l_downloads >= 0) &&
(dirdata.Nacc < l_downloads))
okay = NO;
if (okay)
{
if (pass == 1)
{
filenum++;
tsize += ulsize;
for (j = 0; j < l_formatcnt; j++)
fsendf(listfile, l_format[j]);
}
else
{
skip = NO;
}
}
pos = ftell(dirfile);
}
if ((pass == 0) && skip)
break;
}
printf("│ %d file(s)\n", filenum);
if (filenum)
{
/* -------- print the area footer -------- */
for (i = 0; i < l_areafootercnt; i++)
fsendf(listfile, l_areafooter[i]);
}
fclose(dirfile);
}
}
boardnum++;
}
/* -------- print the list footer -------- */
for (i = 0; i < l_listfootercnt; i++)
fsendf(listfile, l_listfooter[i]);
fclose(listfile);
printf("└ %s completed.\n", listname);
inlist = NO;
break;
case CMD_UNVALIDATED:
if (!inlist)
xerror("<%d> Unvalidated is a local only command.", linenum);
l_unvalidated = YES;
printf("│ Unvalidated files allowed.\n");
break;
case CMD_FIXSIZE:
if (!inlist)
xerror("<%d> Fixsize is a local only command.", linenum);
l_fixsize = YES;
printf("│ File size correction active.\n");
break;
case CMD_FIXDATE:
if (!inlist)
xerror("<%d> Fixdate is a local only command.", linenum);
l_fixdate = YES;
printf("│ File date correction active.\n");
break;
case CMD_OFFLINE:
if (!inlist)
xerror("<%d> Offline is a local only command.", linenum);
l_offline = YES;
printf("│ Offline files allowed.\n");
break;
case CMD_DOWNLOADS:
if (!inlist)
xerror("<%d> Downloads is a local only command.", linenum);
if ((ptr = strtok(NULL, "= ")) == NULL)
xerror("<%d> Incomplete data in config file.", linenum);
l_downloads = atoi(ptr);
printf("│ Minimum downloads = %d\n", l_downloads);
break;
case CMD_ULAGE:
if (!inlist)
xerror("<%d> ULAGE is a local only command.", linenum);
if ((ptr = strtok(NULL, "= ")) == NULL)
xerror("<%d> Incomplete data in config file.", linenum);
l_ulage = atoi(ptr);
printf("│ Minimum upload age = %d\n", l_ulage);
break;
case CMD_FILEAGE:
if (!inlist)
xerror("<%d> FILEAGE is a local only command.", linenum);
if ((ptr = strtok(NULL, "= ")) == NULL)
xerror("<%d> Incomplete data in config file.", linenum);
l_fileage = atoi(ptr);
printf("│ Minimum file age = %d\n", l_fileage);
break;
case CMD_DSL:
if ((ptr = strtok(NULL, "= ")) == NULL)
xerror("<%d> Incomplete data in config file.", linenum);
if (!inlist)
xerror("<%d> Unvalidated is a local only command.", linenum);
if (!l_dslflagset)
{
l_dslflagset = YES;
memset((void *)l_dslflags, 0, 32);
}
setslflags(l_dslflags, ptr);
printf("│ Reading DSL's.\n");
break;
case CMD_AR:
if ((ptr = strtok(NULL, "= ")) == NULL)
xerror("<%d> Incomplete data in config file.", linenum);
if (!inlist)
xerror("<%d> AR is a local only command.", linenum);
if (!l_arflagset)
{
l_arflagset = YES;
memset((void *)l_arflags, 0, 4);
}
setrflags(l_arflags, ptr);
printf("│ Reading AR flags.\n");
break;
case CMD_BOARDS:
if ((ptr = strtok(NULL, "= ")) == NULL)
xerror("<%d> Incomplete data in config file.", linenum);
if (!inlist)
xerror("<%d> AR is a local only command.", linenum);
if (!l_bflagset)
{
l_bflagset = YES;
memset((void *)l_bflags, 0, 128);
}
setbflags(l_bflags, ptr);
printf("│ Reading board numbers.\n");
break;
case CMD_CDROM:
if (!inlist)
xerror("<%d> CDROM is a local only command.", linenum);
l_cdrom = YES;
printf("│ CD-ROM allowed.\n");
break;
case CMD_NOTFOUND:
xerror("<%d> Unknown keyword in config file", linenum);
break;
}
}
} while (YES);
fcloseall();
}
void xerror(char *str, ...)
{
va_list argptr;
/* print an error message and abort */
va_start(argptr, str);
vprintf(str, argptr);
va_end(argptr);
exit(1);
}
char *fixline(char *str)
{
/* fix a string. */
char *ptr;
int quote = NO;
/* remove white spaces off front */
ptr = str;
while (isspace(*ptr) && *ptr)
ptr++;
strcpy(str, ptr);
/* remove excess white spaces from middle */
ptr = str;
while (*ptr)
{
if (*ptr == '\"')
quote = !quote;
if (!quote)
{
/* not in quote mode. reduce spaces and truncate at ; */
if (*ptr == ';')
*ptr = '\0';
else
if (isspace(*ptr))
if (isspace(*(ptr + 1)) && *(ptr + 1))
{
strcpy(ptr, ptr + 1);
ptr--;
}
}
if (*ptr)
ptr++;
}
/* remove spaces off end */
while (isspace(str[strlen(str) - 1]))
str[strlen(str) - 1] = '\0';
if (*str)
return str;
else
return NULL;
}
void setbflags(unsigned char *bflags, char *str)
{
char *ptr;
int val,
from,
to;
/* set the board flags based on str. can be inform of:
#
#-#
#-#,#
etc.
*/
ptr = strtok(str, ",");
while (ptr != NULL)
{
if (strrchr(ptr, '-'))
{
/* a range #-# */
from = atoi(ptr);
to = atoi(strrchr(ptr, '-') + 1);
for (val = from; val <= to; val++)
{
if (val >= 1024)
xerror("Board number out of range.");
setbit(bflags, val);
}
}
else
{
/* just a number */
val = atoi(ptr);
if (val >= 1024)
xerror("Board number out of range.");
setbit(bflags, val);
}
ptr = strtok(NULL, ",");
}
}
void setrflags(unsigned char *rflags, char *str)
{
char *ptr;
int val,
from,
to;
/* set the r flags based on str. can be inform of:
#
#-#
#-#,#
etc.
where # is in range @-Z
*/
ptr = strtok(str, ",");
while (ptr != NULL)
{
if (strrchr(ptr, '-'))
{
/* a range #-# */
from = toupper(*ptr) - '@';
to = toupper(*(ptr + 2)) - '@';
if ((from < 0) || (from > 26) || (to < 0) || (to > 26) ||
(from > to))
xerror("Invalid flag specified.");
for (val = from; val <= to; val++)
setbit(rflags, val);
}
else
{
/* just a number */
val = *ptr - '@';
if ((val < 0) || (val > 26))
xerror("Invalid flag specified.");
else
setbit(rflags, val);
}
ptr = strtok(NULL, ",");
}
}
void setslflags(unsigned char *slflags, char *str)
{
char *ptr;
int val,
from,
to;
/* set the secutity level flags based on str. can be inform of:
#
#-#
#-#,#
etc.
*/
ptr = strtok(str, ",");
while (ptr != NULL)
{
if (strrchr(ptr, '-'))
{
/* a range #-# */
from = atoi(ptr);
to = atoi(strrchr(ptr, '-') + 1);
for (val = from; val <= to; val++)
{
if (val >= 256)
xerror("Secutiry level out of range.");
setbit(slflags, val);
}
}
else
{
/* just a number */
val = atoi(ptr);
if (val >= 256)
xerror("Security level out of range.");
setbit(slflags, val);
}
ptr = strtok(NULL, ",");
}
}
void setbit(unsigned char *flags, int bitnum)
{
int byte,
bit;
byte = (bitnum >> 3);
bit = (bitnum & 0x07);
flags[byte] |= (0x01 << bit);
}
int checkbit(unsigned char *flags, int bitnum)
{
int byte,
bit;
byte = (bitnum >> 3);
bit = (bitnum & 0x07);
return (flags[byte] & (0x01 << bit));
}
int findword(char *word, char *list[])
{
int cmd;
char *ptr;
cmd = 0;
while (strcmpi(word, list[cmd]) && *list[cmd])
cmd++;
if (!*list[cmd])
return CMD_NOTFOUND;
return cmd;
}
char *strpastoc(char *d, char *s)
{
register int i;
register char *p;
i = 1;
p = d;
while (i <= s[0])
{
if (i < s[0] && (s[i] == 0x03 || s[i] == '^') &&
(isdigit(s[i+1]) || (s[i+1] >= 0 && s[i+1] <= 9)))
++i;
else
*p++ = s[i];
++i;
}
*p = '\0';
return(d);
}
void fsendf(FILE *f, char *str)
{
/*
%A : area name (26 characters)
%B : file blocks
%C : date of upload (8 characters- ##/##/##)
%D : date on file (8 characters- ##/##/##)
%E : file extension only (3 characters)
%F : full file name (12 characters- period unjustified)
%G : file name only (12 characters)
%H : file description (? characters- last field/no wrap)
%I : file description (? characters- last field/wrapped)
%J : name of uploader (32 characters)
%K : number of files in the area (4 characters- ####)
%L : path here files live (60 characters)
%M : area size ( 7 characters- "##,###k")
%N : area size (10 characters- ##,###,###)
%O : file size ( 7 characters- ##,###k,OFFLINE,UNVAL'D)
%P : file size (10 characters- ##,###,###,OFFLINE,UNVALIDT'D)
%Q : time of file (5 characters- ##:##/military)
%R : times downloaded (5 characters- #####)
%S : number of areas in list (4 characters)
%T : Area number (5 characters)
*/
char buff[256],
*iptr,
*optr,
temp[256],
temp2[256];
int x,
len,
thislen,
i,
j,
k,
c;
iptr = str;
optr = buff;
*optr = '\0';
while (*iptr)
{
if (*iptr == '%')
{
switch (toupper(iptr[1]))
{
case 'A':
/* %A : area name (26 characters) */
sprintf(temp, "%-26s", boardname);
strcat(optr, temp);
optr += 26;
iptr += 2;
break;
case 'B':
/* %B : file blocks # 128 blocks? (#####) */
sprintf(temp, "%5.5ld", ulblocks);
strcat(optr, temp);
optr += strlen(temp);
iptr += 2;
break;
case 'C':
/* %C : date of upload (8 characters- ##/##/##) */
strcpy(temp, uldate);
strcat(optr, temp);
optr += 8;
iptr += 2;
break;
case 'D':
/* %D : date on file (8 characters- ##/##/##) */
strcpy(temp, filedate);
strcat(optr, temp);
optr += 8;
iptr += 2;
break;
case 'E':
/* %E : file extension only (3 characters) */
strcpy(temp, filename);
ptr = strrchr(temp, '.');
if (ptr)
sprintf(temp2, "%-3s", ptr + 1);
strcat(optr, temp2);
optr += 3;
iptr += 2;
break;
case 'F':
/* %F : full file name (12 characters- period unjustified) */
sprintf(temp, "%-12s", filename);
strcat(optr, temp);
optr += 12;
iptr += 2;
break;
case 'G':
/* %G : file name only (8 characters) */
strcpy(temp, filename);
ptr = strrchr(temp, '.');
if (ptr)
*ptr = '\0';
sprintf(temp2, "%-8s", temp);
strcat(optr, temp2);
optr += 8;
iptr += 2;
break;
case 'H':
/* %H : file description (? characters- last field/no wrap) */
strcpy(temp, description);
strcat(optr, temp);
optr += strlen(temp);
iptr += 2;
break;
case 'I':
/* %I : file description (? characters- last field/wrapped) */
x = strlen(buff);
strcpy(temp, description);
strcat(optr, temp);
optr += strlen(temp);
iptr += 2;
thislen = strlen(buff);
while (thislen > 79)
{
/* find wrap point */
for (i = 78; i > x; i--)
if (isspace(buff[i]))
{
/* break it here */
buff[i] = '\0';
fprintf(f, "%s\n", buff);
for (j = 0; j < x; j++)
buff[j] = ' ';
for (k = i + 1;
buff[k] && isspace(buff[k]);
k++);
strcpy(&buff[x], &buff[k]);
break;
}
if (i == x)
{
c = buff[78];
buff[78] = '\0';
fprintf(f, "%s\n", buff);
buff[78] = c;
for (j = 0; j < x; j++)
buff[j] = ' ';
strcpy(&buff[x], &buff[78]);
}
thislen = strlen(buff);
}
break;
case 'J':
/* %J : name of uploader (36 characters) */
strcpy(temp, owner);
sprintf(temp2, "%-36s", temp);
strcat(optr, temp2);
optr += 36;
iptr += 2;
break;
case 'K':
/* %K : number of files in the area (4 characters- ####) */
sprintf(temp, "%4d", filenum);
strcat(optr, temp);
optr += 4;
iptr += 2;
break;
case 'L':
/* %L : path here files live (60 characters) */
strpastoc(temp, fboarddata.UlPathName);
sprintf(temp2, "%-60s", temp);
strcat(optr, temp2);
optr += 60;
iptr += 2;
break;
case 'M':
/* %M : area size ( 7 characters- "##,###k") */
ksize = tsize / 1024;
if (ksize > 999)
sprintf(temp, "%2ld,%03ldk",
ksize / 1000L,
ksize % 1000L);
else
sprintf(temp, "%6ldk", ksize);
strcat(optr, temp);
optr += 7;
iptr += 2;
break;
case 'N':
/* %N : area size (10 characters- ##,###,###)*/
if (tsize > 999999L)
sprintf(temp, "%2ld,%03ld,%03ld",
tsize / 1000000L,
(tsize % 1000000L) / 1000L,
tsize % 1000L);
else if (tsize > 999)
sprintf(temp, " %3ld,%03ld",
tsize / 1000L,
tsize % 1000L);
else
sprintf(temp, " %3ld", tsize);
strcat(optr, temp);
optr += 10;
iptr += 2;
break;
case 'O':
/* %O : file size ( 7 characters- ##,###k,OFFLINE,UNVAL'D) */
if (dirdata.Flag.flag1 & FRS_NotValidated)
strcpy(temp, "UNVAL'D");
else if (ulsize)
{
ksize = ulsize / 1024L;
if (ksize > 999)
sprintf(temp, "%2ld,%03ldk",
ksize / 1000L,
ksize % 1000L);
else
sprintf(temp, "%6ldk", ksize);
}
else
strcpy(temp, "OFFLINE");
strcat(optr, temp);
optr += 7;
iptr += 2;
break;
case 'P':
/* P : file size (10 characters- ##,###,###,OFFLINE,UNVALIDT'D) */
if (dirdata.Flag.flag1 & FRS_NotValidated)
strcpy(temp, "UNVALIDT'D");
else if (ulsize)
{
if (ulsize > 999999L)
sprintf(temp, "%2ld,%03ld,%03ld",
ulsize / 1000000L,
(ulsize % 1000000L) / 1000L,
ulsize % 1000L);
else if (ulsize > 999)
sprintf(temp, " %3ld,%03ld",
ulsize / 1000L,
ulsize % 1000L);
else
sprintf(temp, " %3ld", ulsize);
}
else
strcpy(temp, " OFFLINE");
strcat(optr, temp);
optr += 10;
iptr += 2;
break;
case 'Q':
/* %Q : time of file (5 characters- ##:##/military) */
if ((fboarddata.Flags.flag1 & ULRF_IsCdRom) || missing)
strcpy(temp, " ");
else
sprintf(temp, "%02d:%02d",
(ffblk.ff_ftime >> 11) & 0x001f,
(ffblk.ff_ftime >> 5) & 0x003f);
strcat(optr, temp);
optr += 5;
iptr += 2;
break;
case 'R':
/* %R : times downloaded (5 characters- #####) */
sprintf(temp, "%5d", dirdata.Nacc);
strcat(optr, temp);
optr += 5;
iptr += 2;
break;
case 'S':
/* %S : number of areas in list (5 characters) */
sprintf(temp, "%5d", tareas);
strcat(optr, temp);
optr += 5;
iptr += 2;
break;
case 'T':
/* %T : Area number (5 characters) */
sprintf(temp, "%5d", boardnum);
strcat(optr, temp);
optr += 5;
iptr += 2;
break;
default:
*optr = *iptr;
optr++;
iptr++;
*optr = '\0';
break;
}
}
else
{
*optr = *iptr;
optr++;
iptr++;
*optr = '\0';
}
}
fprintf(f, "%s\n", buff);
}
int isleap (unsigned yr)
{
return yr % 400 == 0 || (yr % 4 == 0 && yr % 100 != 0);
}
static unsigned months_to_days (unsigned month)
{
return (month * 3057 - 3007) / 100;
}
static long years_to_days (unsigned yr)
{
return yr * 365L + yr / 4 - yr / 100 + yr / 400;
}
long ymd_to_scalar (unsigned yr, unsigned mo, unsigned day)
{
long scalar;
scalar = day + months_to_days(mo);
if ( mo > 2 ) /* adjust if past February */
scalar -= isleap(yr) ? 1 : 2;
yr--;
scalar += years_to_days(yr);
return scalar;
}
void scalar_to_ymd (long scalar, unsigned *pyr, unsigned *pmo, unsigned *pday)
{
unsigned n; /* compute inverse of years_to_days() */
for ( n = (unsigned)((scalar * 400L) / 146097); years_to_days(n) < scalar;)
n++; /* 146097 == years_to_days(400) */
*pyr = n;
n = (unsigned)(scalar - years_to_days(n-1));
if ( n > 59 ) { /* adjust if past February */
n += 2;
if ( isleap(*pyr) )
n -= n > 62 ? 1 : 2;
}
*pmo = (n * 100 + 3007) / 3057; /* inverse of months_to_days() */
*pday = n - months_to_days(*pmo);
}