Skip to content
Snippets Groups Projects
Commit 1f99bd88 authored by rswindell's avatar rswindell
Browse files

Ported the filelist v2 utility to v3.

parent 095dd43b
No related branches found
No related tags found
No related merge requests found
/* filelist.c */
/* Utility to create list of files from Synchronet file directories */
/* Default list format is FILES.BBS, but file size, uploader, upload date */
/* and other information can be included. */
/* $Id$ */
/****************************************************************************
* @format.tab-size 4 (Plain Text/Source Code File Header) *
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
* *
* Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* See the GNU General Public License for more details: gpl.txt or *
* http://www.fsf.org/copyleft/gpl.html *
* *
* Anonymous FTP access to the most recent released source is available at *
* ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
* *
* Anonymous CVS access to the development source and modification history *
* is available at cvs.synchro.net:/cvsroot/sbbs, example: *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login *
* (just hit return, no password is necessary) *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src *
* *
* For Synchronet coding style and modification guidelines, see *
* http://www.synchro.net/source.html *
* *
* You are encouraged to submit any modifications (preferably in Unix diff *
* format) via e-mail to mods@synchro.net *
* *
* Note: If this box doesn't appear square, then you need to fix your tabs. *
****************************************************************************/
#include "sbbs.h"
#define FILELIST_VER "3.00"
#define MAX_NOTS 25
scfg_t scfg;
char *crlf="\r\n";
long lputs(char *str)
{
char tmp[256];
int i,j,k;
j=strlen(str);
for(i=k=0;i<j;i++) /* remove CRs */
if(str[i]==CR && str[i+1]==LF)
continue;
else
tmp[k++]=str[i];
tmp[k]=0;
return(fputs(tmp,stdout));
}
/****************************************************************************/
/* Performs printf() through local assembly routines */
/* Called from everywhere */
/****************************************************************************/
int lprintf(char *fmat, ...)
{
va_list argptr;
char sbuf[256];
int chcount;
va_start(argptr,fmat);
chcount=vsprintf(sbuf,fmat,argptr);
va_end(argptr);
lputs(sbuf);
return(chcount);
}
void stripctrlz(char *str)
{
char tmp[1024];
int i,j,k;
k=strlen(str);
for(i=j=0;i<k;i++)
if(str[i]!=0x1a)
tmp[j++]=str[i];
tmp[j]=0;
strcpy(str,tmp);
}
#define ALL (1L<<0)
#define PAD (1L<<1)
#define HDR (1L<<2)
#define CDT_ (1L<<3)
#define EXT (1L<<4)
#define ULN (1L<<5)
#define ULD (1L<<6)
#define DLS (1L<<7)
#define DLD (1L<<8)
#define NOD (1L<<9)
#define PLUS (1L<<10)
#define MINUS (1L<<11)
#define JST (1L<<12)
#define NOE (1L<<13)
#define DFD (1L<<14)
#define TOT (1L<<15)
#define AUTO (1L<<16)
/*********************/
/* Entry point (duh) */
/*********************/
int main(int argc, char **argv)
{
char revision[16];
char error[512];
char *p,str[256],fname[256],ext,not[MAX_NOTS][9],nots=0;
uchar *datbuf,*ixbbuf;
int i,j,file,dirnum,libnum,desc_off,lines
,omode=O_WRONLY|O_CREAT|O_TRUNC;
ulong l,m,n,cdt,misc=0,total_cdt=0,total_files=0,datbuflen;
time_t uld,dld;
FILE *in,*out=NULL;
sscanf("$Revision$" + 11, "%s", revision);
fprintf(stderr,"\nFILELIST v%s-%s (rev %s) - Generate Synchronet File "
"Directory Lists\n"
,FILELIST_VER
,PLATFORM_DESC
,revision
);
if(argc<2
|| strcmp(argv[1],"-?")==0
|| strcmp(argv[1],"-help")==0
|| strcmp(argv[1],"--help")==0
|| strcmp(argv[1],"/?")==0
) {
printf("\n usage: FILELIST <dir_code or * for ALL> [switches] [outfile]\n");
printf("\n");
printf("switches: -lib name All directories of specified library\n");
printf(" -not code Exclude specific directory\n");
printf(" -cat Concatenate to existing outfile\n");
printf(" -pad Pad filename with spaces\n");
printf(" -hdr Include directory headers\n");
printf(" -cdt Include credit value\n");
printf(" -tot Include credit totals\n");
printf(" -uln Include uploader's name\n");
printf(" -uld Include upload date\n");
printf(" -dfd Include DOS file date\n");
printf(" -dld Include download date\n");
printf(" -dls Include total downloads\n");
printf(" -nod Exclude normal descriptions\n");
printf(" -noe Exclude normal descriptions, if extended "
"exists\n");
printf(" -ext Include extended descriptions\n");
printf(" -jst Justify extended descriptions under normal\n");
printf(" -+ Include extended description indicator (+)\n");
printf(" -- Include offline file indicator (-)\n");
printf(" -* Short-hand for -pad -hdr -cdt -+ --\n");
exit(0); }
p=getenv("SBBSCTRL");
if(p==NULL) {
printf("\nSBBSCTRL environment variable not set.\n");
printf("\nExample: SET SBBSCTRL=/sbbs/ctrl\n");
exit(1);
}
memset(&scfg,0,sizeof(scfg));
scfg.size=sizeof(scfg);
SAFECOPY(scfg.ctrl_dir,p);
if(chdir(scfg.ctrl_dir)!=0)
fprintf(stderr,"!ERROR changing directory to: %s", scfg.ctrl_dir);
printf("\nLoading configuration files from %s\n",scfg.ctrl_dir);
if(!load_cfg(&scfg,NULL,TRUE,error)) {
fprintf(stderr,"!ERROR loading configuration files: %s\n",error);
exit(1);
}
prep_dir(scfg.data_dir, scfg.temp_dir);
if(!(scfg.sys_misc&SM_LOCAL_TZ))
putenv("TZ=UTC0");
dirnum=libnum=-1;
if(argv[1][0]=='*')
misc|=ALL;
else if(argv[1][0]!='-') {
strupr(argv[1]);
for(i=0;i<scfg.total_dirs;i++)
if(!stricmp(argv[1],scfg.dir[i]->code))
break;
if(i>=scfg.total_dirs) {
printf("\nDirectory code '%s' not found.\n",argv[1]);
exit(1); }
dirnum=i; }
for(i=1;i<argc;i++) {
if(!stricmp(argv[i],"-lib")) {
if(dirnum!=-1) {
printf("\nBoth directory code and -lib parameters were used.\n");
exit(1); }
i++;
if(i>=argc) {
printf("\nLibrary short name must follow -lib parameter.\n");
exit(1); }
strupr(argv[i]);
for(j=0;j<scfg.total_libs;j++)
if(!stricmp(scfg.lib[j]->sname,argv[i]))
break;
if(j>=scfg.total_libs) {
printf("\nLibrary short name '%s' not found.\n",argv[i]);
exit(1); }
libnum=j; }
else if(!stricmp(argv[i],"-not")) {
if(nots>=MAX_NOTS) {
printf("\nMaximum number of -not options (%u) exceeded.\n"
,MAX_NOTS);
exit(1); }
i++;
if(i>=argc) {
printf("\nDirectory internal code must follow -not parameter.\n");
exit(1); }
sprintf(not[nots++],"%.8s",argv[i]); }
else if(!stricmp(argv[i],"-all")) {
if(dirnum!=-1) {
printf("\nBoth directory code and -all parameters were used.\n");
exit(1); }
if(libnum!=-1) {
printf("\nBoth library name and -all parameters were used.\n");
exit(1); }
misc|=ALL; }
else if(!stricmp(argv[i],"-pad"))
misc|=PAD;
else if(!stricmp(argv[i],"-cat"))
omode=O_WRONLY|O_CREAT|O_APPEND;
else if(!stricmp(argv[i],"-hdr"))
misc|=HDR;
else if(!stricmp(argv[i],"-cdt"))
misc|=CDT_;
else if(!stricmp(argv[i],"-tot"))
misc|=TOT;
else if(!stricmp(argv[i],"-ext"))
misc|=EXT;
else if(!stricmp(argv[i],"-uln"))
misc|=ULN;
else if(!stricmp(argv[i],"-uld"))
misc|=ULD;
else if(!stricmp(argv[i],"-dld"))
misc|=DLD;
else if(!stricmp(argv[i],"-dfd"))
misc|=DFD;
else if(!stricmp(argv[i],"-dls"))
misc|=DLS;
else if(!stricmp(argv[i],"-nod"))
misc|=NOD;
else if(!stricmp(argv[i],"-jst"))
misc|=(EXT|JST);
else if(!stricmp(argv[i],"-noe"))
misc|=(EXT|NOE);
else if(!stricmp(argv[i],"-+"))
misc|=PLUS;
else if(!stricmp(argv[i],"--"))
misc|=MINUS;
else if(!stricmp(argv[i],"-*"))
misc|=(HDR|PAD|CDT_|PLUS|MINUS);
else if(i!=1) {
if(argv[i][0]=='*') {
misc|=AUTO;
continue; }
if((j=nopen(argv[i],omode))==-1) {
printf("\nError opening/creating %s for output.\n",argv[i]);
exit(1); }
out=fdopen(j,"wb"); } }
if(!out && !(misc&AUTO)) {
printf("\nOutput file not specified, using FILES.BBS in each "
"directory.\n");
misc|=AUTO; }
for(i=0;i<scfg.total_dirs;i++) {
if(!(misc&ALL) && i!=dirnum && scfg.dir[i]->lib!=libnum)
continue;
for(j=0;j<nots;j++)
if(!stricmp(not[j],scfg.dir[i]->code))
break;
if(j<nots)
continue;
if(misc&AUTO && scfg.dir[i]->seqdev) /* CD-ROM */
continue;
printf("\n%-*s %s",LEN_GSNAME,scfg.lib[scfg.dir[i]->lib]->sname,scfg.dir[i]->lname);
sprintf(str,"%s%s.IXB",scfg.dir[i]->data_dir,scfg.dir[i]->code);
if((file=nopen(str,O_RDONLY))==-1)
continue;
l=filelength(file);
if(misc&AUTO) {
sprintf(str,"%sFILES.BBS",scfg.dir[i]->path);
if((j=nopen(str,omode))==-1) {
printf("\nError opening/creating %s for output.\n",str);
exit(1); }
out=fdopen(j,"wb"); }
if(misc&HDR) {
sprintf(fname,"%-*s %-*s Files: %4u"
,LEN_GSNAME,scfg.lib[scfg.dir[i]->lib]->sname
,LEN_SLNAME,scfg.dir[i]->lname,l/F_IXBSIZE);
fprintf(out,"%s\r\n",fname);
strset(fname,'-');
fprintf(out,"%s\r\n",fname); }
if(!l) {
close(file);
if(misc&AUTO) fclose(out);
continue; }
if((ixbbuf=(char *)MALLOC(l))==NULL) {
close(file);
if(misc&AUTO) fclose(out);
printf("\7ERR_ALLOC %s %lu\n",str,l);
continue; }
if(read(file,ixbbuf,l)!=(int)l) {
close(file);
if(misc&AUTO) fclose(out);
printf("\7ERR_READ %s %lu\n",str,l);
FREE((char *)ixbbuf);
continue; }
close(file);
sprintf(str,"%s%s.DAT",scfg.dir[i]->data_dir,scfg.dir[i]->code);
if((file=nopen(str,O_RDONLY))==-1) {
printf("\7ERR_OPEN %s %lu\n",str,O_RDONLY);
FREE((char *)ixbbuf);
if(misc&AUTO) fclose(out);
continue; }
datbuflen=filelength(file);
if((datbuf=MALLOC(datbuflen))==NULL) {
close(file);
printf("\7ERR_ALLOC %s %lu\n",str,datbuflen);
FREE((char *)ixbbuf);
if(misc&AUTO) fclose(out);
continue; }
if(read(file,datbuf,datbuflen)!=(int)datbuflen) {
close(file);
printf("\7ERR_READ %s %lu\n",str,datbuflen);
FREE((char *)datbuf);
FREE((char *)ixbbuf);
if(misc&AUTO) fclose(out);
continue; }
close(file);
m=0L;
while(m<l && !ferror(out)) {
for(j=0;j<12 && m<l;j++)
if(j==8)
str[j]='.';
else
str[j]=ixbbuf[m++]; /* Turns FILENAMEEXT into FILENAME.EXT */
str[j]=0;
unpadfname(str,fname);
fprintf(out,"%-12.12s",misc&PAD ? str : fname);
total_files++;
n=ixbbuf[m]|((long)ixbbuf[m+1]<<8)|((long)ixbbuf[m+2]<<16);
uld=(ixbbuf[m+3]|((long)ixbbuf[m+4]<<8)|((long)ixbbuf[m+5]<<16)
|((long)ixbbuf[m+6]<<24));
dld=(ixbbuf[m+7]|((long)ixbbuf[m+8]<<8)|((long)ixbbuf[m+9]<<16)
|((long)ixbbuf[m+10]<<24));
m+=11;
if(n>=datbuflen /* index out of bounds */
|| datbuf[n+F_DESC+LEN_FDESC]!=CR) { /* corrupted data */
fprintf(stderr,"\n\7%s%s is corrupted!\n"
,scfg.dir[i]->data_dir,scfg.dir[i]->code);
exit(-1); }
if(misc&PLUS && datbuf[n+F_MISC]!=ETX
&& (datbuf[n+F_MISC]-SP)&FM_EXTDESC)
fputc('+',out);
else
fputc(SP,out);
desc_off=12;
if(misc&(CDT_|TOT)) {
getrec((char *)&datbuf[n],F_CDT,LEN_FCDT,str);
cdt=atol(str);
total_cdt+=cdt;
if(misc&CDT_) {
fprintf(out,"%7lu",cdt);
desc_off+=7; } }
if(misc&MINUS) {
sprintf(str,"%s%s",scfg.dir[i]->path,fname);
if(!fexist(str))
fputc('-',out);
else
fputc(SP,out); }
else
fputc(SP,out);
desc_off++;
if(misc&DFD) {
sprintf(str,"%s%s",scfg.dir[i]->path,fname);
fprintf(out,"%s ",unixtodstr(&scfg,fdate(str),str));
desc_off+=9; }
if(misc&ULD) {
fprintf(out,"%s ",unixtodstr(&scfg,uld,str));
desc_off+=9; }
if(misc&ULN) {
getrec((char *)&datbuf[n],F_ULER,25,str);
fprintf(out,"%-25s ",str);
desc_off+=26; }
if(misc&DLD) {
fprintf(out,"%s ",unixtodstr(&scfg,dld,str));
desc_off+=9; }
if(misc&DLS) {
getrec((char *)&datbuf[n],F_TIMESDLED,5,str);
j=atoi(str);
fprintf(out,"%5u ",j);
desc_off+=6; }
if(datbuf[n+F_MISC]!=ETX && (datbuf[n+F_MISC]-SP)&FM_EXTDESC)
ext=1; /* extended description exists */
else
ext=0; /* it doesn't */
if(!(misc&NOD) && !(misc&NOE && ext)) {
getrec((char *)&datbuf[n],F_DESC,LEN_FDESC,str);
fprintf(out,"%s",str); }
if(misc&EXT && ext) { /* Print ext desc */
sprintf(str,"%s%s.EXB",scfg.dir[i]->data_dir,scfg.dir[i]->code);
if(!fexist(str))
continue;
if((j=nopen(str,O_RDONLY))==-1) {
printf("\7ERR_OPEN %s %lu\n",str,O_RDONLY);
continue; }
if((in=fdopen(j,"rb"))==NULL) {
close(j);
continue; }
fseek(in,(n/F_LEN)*512L,SEEK_SET);
lines=0;
if(!(misc&NOE)) {
fprintf(out,"\r\n");
lines++; }
while(!feof(in) && !ferror(in)
&& ftell(in)<(long)((n/F_LEN)+1)*512L) {
if(!fgets(str,128,in) || !str[0])
break;
stripctrlz(str);
if(lines) {
if(misc&JST)
fprintf(out,"%*s",desc_off,"");
fputc(SP,out); /* indent one character */ }
fprintf(out,"%s",str);
lines++; }
fclose(in); }
fprintf(out,"\r\n"); }
FREE((char *)datbuf);
FREE((char *)ixbbuf);
fprintf(out,"\r\n"); /* blank line at end of dir */
if(misc&AUTO) fclose(out); }
if(misc&TOT && !(misc&AUTO))
fprintf(out,"TOTALS\n------\n%lu credits/bytes in %lu files.\r\n"
,total_cdt,total_files);
printf("\nDone.\n");
return(0);
}
# Microsoft Developer Studio Project File - Name="filelist" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=filelist - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "filelist.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "filelist.mak" CFG="filelist - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "filelist - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "filelist - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "filelist - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "msvc.win32.exe.release"
# PROP Intermediate_Dir "msvc.win32.exe.release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "../xpdev" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "SBBS_EXPORTS" /D "WRAPPER_EXPORTS" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "filelist - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "filelist___Win32_Debug"
# PROP BASE Intermediate_Dir "filelist___Win32_Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "msvc.win32.exe.debug"
# PROP Intermediate_Dir "msvc.win32.exe.debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../xpdev" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "SBBS_EXPORTS" /D "WRAPPER_EXPORTS" /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "filelist - Win32 Release"
# Name "filelist - Win32 Debug"
# Begin Source File
SOURCE=.\ars.c
# End Source File
# Begin Source File
SOURCE=.\dat_rec.c
# End Source File
# Begin Source File
SOURCE=.\date_str.c
# End Source File
# Begin Source File
SOURCE=..\xpdev\dirwrap.c
# End Source File
# Begin Source File
SOURCE=.\filedat.c
# End Source File
# Begin Source File
SOURCE=.\filelist.c
# End Source File
# Begin Source File
SOURCE=..\xpdev\filewrap.c
# End Source File
# Begin Source File
SOURCE=..\xpdev\genwrap.c
# End Source File
# Begin Source File
SOURCE=.\load_cfg.c
# End Source File
# Begin Source File
SOURCE=.\nopen.c
# End Source File
# Begin Source File
SOURCE=.\scfglib1.c
# End Source File
# Begin Source File
SOURCE=.\scfglib2.c
# End Source File
# Begin Source File
SOURCE=.\str_util.c
# End Source File
# End Target
# End Project
......@@ -39,6 +39,18 @@ Package=<4>
###############################################################################
Project: "filelist"=.\filelist.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "fixsmb"=.\fixsmb.dsp - Package Owner=<4>
Package=<5>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment