home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
455.lha
/
finddisk_v3.1
/
fd2src
/
fd2.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-12-10
|
21KB
|
1,168 lines
/* FindDisk2.2
Author : Ross MacGregor
Date : 27/10/88
Last Update : 5/03/90
Comments : This is a public domain program.
DiskList stored in compacted form:
below: { unskrunched } => { skrunched }
[] is a byte of memory
* compacts strings of spaces
{ [$20] [$20] [$20] [$20] [$20] } => { [SKRUNCHAR] [SKRUNOFFS 5] }
{ [$20] [$20] } => { [$20] [$20] }
* the STARTSTR is compacted
{ STARTSTR } => { [STARTCHAR] }
*/
/*#include <functions.h>*/
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/libraries.h>
#include <exec/ports.h>
#include <exec/interrupts.h>
#include <exec/io.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
/* lattice will want smaller strings - sorry, do it yourself */
#define HELPTEXT1 "\nFindDisk2.2 :\n\
FD -l ; Loads DiskList to ram:\n\
FD -s ; Saves DiskList back to disk (first doing an update)\n\
FD -d [path] ; Saves dir listing to ram:TempDL\n\
FD -a [path] ; Saves listing with all sub-directories included\n\
FD -u ; Updates the DiskList with TempDL\n\
FD -n ; Creates a new (empty) DiskList\n"
#define HELPTEXT2 "FD -r diskname ; Removes directory from DiskList matching 'diskname'\n\
FD text1 [textn] ; Lists disk dir with a line containing text1 to textn\n\
FD text ; Case insensitive scan for text\n\
FD !text ; Case sensitive scan for for text\n"
#define HELPTEXT3 "\nEnvironment Variables: (= default setting)\n\
DLDISK = FindDisk:Disklist (Disk storage location/name)\n\
DLTEMP = ram:DiskList (Ram storage location/name)\n\
DLDRIVE = df0: (Captures dir of this drive)\n\n"
#define CP_BUFF 1024L /* Buffer size for the file copy function */
/* This indicates the start line of a dir listing, and
it MUST have the name of the disk on the same line. */
#define STARTSTR "Directory of "
/* Special character used to compact the spaces in DiskList */
#define SKRUNCHAR 1
#define SKRUNOFFS 10
/* Special characters used to replace the STARTSTR */
#define STARTCHAR 2
/* Lines in the stored dir listing array */
#define NUMLINES 25
/* Max length of the lines read in */
#define LINELEN 170
#define MAXBUF LINELEN+1
struct FileHandle *fdl, *ftmp;
struct FileHandle *confh;
char *tempdl="ram:TempDL";
char *dltemp="ram:DiskList", *dldisk="FindDisk:DiskList";
char *sdir_pat="df0:";
#define MAXPATHLEN 80
char *dlpath;
char buffer[LINELEN];
/* global main arguments */
int glargc;
char **glargv;
/* function error indicator */
int fcnerr;
char *outofmem="Out of Memory Error.\n";
char *cutoff=" - - (no more lines available) - -\n";
/*------------ dynamic structure for coping DL to memory -------------*/
/* Blocks of memory for storing the disklist */
#define BUFBLKS 20
#define BLKSIZE 10000
char *bufferblock[BUFBLKS],*bufptr=NULL;
int bufcount=-1, chrcount=BLKSIZE+1;
void init_bufblks(), free_bufblks();
/*------------ dynamic structure for listing the volume names --------*/
/* used in recursive do_ls call also */
struct disk
{
char name[LINELEN];
struct disk *next;
};
struct disk *firstdisk,*diskptr;
#define INIT_DISKNAMES firstdisk=diskptr=NULL
#define FREE_DISKNAMES free_disknames()
void free_disknames();
/*----------------------------------------------------------------------*/
char *strstr(), *strtoupper(), *getstr();
void putstr();
char *skrunch(), *getenv();
void unskrunch(), get_dlpath();
struct FileHandle *opendl(), *opentmp();
char *strchr(), *malloc();
extern struct FileHandle *Open();
void finddisk();
/* finddisk uses this */
char dirlist[NUMLINES][LINELEN];
int update(), remove(), loaddl(), savedl(), sdir(), newdl();
void update_free(), ls_free(), remove_free();
void main(argc,argv)
int argc;
char *argv[];
{
glargv=argv;
glargc=argc;
if( (confh=Output())==NULL )
exit(1);
if( argc==1)
{
putstr(HELPTEXT1);
putstr(HELPTEXT2);
putstr(HELPTEXT3);
exit(0);
}
dldisk=getenv("env:dldisk",dldisk);
dltemp=getenv("env:dltemp",dltemp);
sdir_pat=getenv("env:dldrive",sdir_pat);
get_dlpath();
if( *argv[1]=='-' )
{
switch( *(argv[1]+1) )
{
case 'd': if( sdir(0) )
putstr("SaveDir failed!\n");
break;
case 'a': if( sdir(1) )
putstr("SaveDir failed!\n");
break;
case 's': if( savedl() )
putstr("SaveDL failed!\n");
break;
case 'l': if( loaddl() )
putstr("LoadDL failed!\n");
break;
case 'u': if( update() )
putstr("Update failed!\n");
break;
case 'r': if( remove() )
putstr("Remove failed!\n");
break;
case 'n': if( newdl() )
putstr("Empty DiskList created (Save if in RAM).\n");
break;
default : putstr("Unknown Option.\n");
}
}
else finddisk();
}
char *getenv(fullpath,var)
char *fullpath, *var;
{
struct FileLock *lock,*Lock();
struct FileHandle *fh;
char *buffer;
int len;
if( lock=Lock(fullpath,(long)ACCESS_READ) )
{
UnLock(lock);
if( !(fh=Open(fullpath,(long)MODE_OLDFILE)) )
return var;
if( !(buffer=(char *)malloc(MAXPATHLEN+1)) )
{
putstr(outofmem);
Close(fh);
return var;
}
len=Read(fh,buffer,(long)MAXPATHLEN);
Close(fh);
*(buffer+len)='\0';
return buffer;
}
return var;
}
void finddisk()
{
int kase=0, thisone=0, line=0;
int i;
char *p;
if( !(fdl=opendl((long)MODE_OLDFILE)) )
return;
/* Converts non-case sensitive keywords to upper case */
for(i=1; i<glargc; i++)
if( *glargv[i]!='!' )
strtoupper(glargv[i]);
/* get line of DiskList */
while( getstr(buffer,fdl) !=NULL )
{
/* first checks for a startchar of a dirlist */
if( strchr(buffer,(char)STARTCHAR) )
{
if( thisone )
{
/* print the directory */
line--;
for(i=0; i<line; i++)
unskrunch(dirlist[i]);
/* if at the end of the dirlist array- prints 'cut off' */
if( line==NUMLINES-1 )
putstr(cutoff);
thisone=0;
}
line=1;
}
if( line )
{
/* Copies the line in buffer to the stored dirlist */
strncpy(dirlist[line-1],buffer,MAXBUF);
if( ++line > NUMLINES )
line--;
/* Checks for given keywords */
if( thisone==0 )
for(i=1; i<glargc; i++)
{
if( *glargv[i]=='!' )
{
p=glargv[i]+1;
kase=1;
}
else
{
p=glargv[i];
kase=0;
}
if( strstr(buffer,p,kase) )
thisone=1;
else
{
thisone=0;
break;
}
}
}/* if(line) */
} /* while( get next buffer) */
if( thisone )
{
line--;
for(i=0; i<line; i++)
unskrunch(dirlist[i]);
/* if at the end of the dirlist array- prints 'cut off' */
if( line==NUMLINES-1 )
putstr(cutoff);
}
Close(fdl);
}
#define update_cleanup(x) { update_free(); return x; }
update()
{
int i;
if( !(fdl=opendl((long)MODE_OLDFILE)) )
return 1;
if( !(ftmp=opentmp((long)MODE_OLDFILE)) )
{
Close(fdl);
return 0;
}
INIT_DISKNAMES;
init_bufblks();
/* finds the disks names in TempDL */
while( getstr(buffer,ftmp) !=NULL )
{
if( strstr(buffer,STARTSTR,1) )
{
skrunch(buffer);
if( storename(buffer) )
update_cleanup(3)
}
}
if( fcnerr )
update_cleanup(10)
if( storedl() )
update_cleanup(4)
Seek(ftmp,0L,(long)OFFSET_BEGINNING);
/* store TempDL in memory */
while( getstr(buffer,ftmp) !=NULL )
if( store( skrunch(buffer) ) )
update_cleanup(5)
if( fcnerr )
update_cleanup(6);
Close(fdl);
if( !(fdl=opendl((long)MODE_NEWFILE)) )
{
Close(ftmp);
FREE_DISKNAMES;
free_bufblks();
return 7;
}
/* write the in memory disklist to the one in ram: */
for(i=0; i<=bufcount; i++)
if( fputstr(bufferblock[i],fdl) )
update_cleanup(8)
Close(ftmp);
if( !(ftmp=opentmp((long)MODE_NEWFILE)) )
update_cleanup(9)
update_free();
return 0;
}
void update_free()
{
Close(fdl);
Close(ftmp);
FREE_DISKNAMES;
free_bufblks();
}
#define remove_cleanup(x) { remove_free(); return x; }
remove()
{
int i;
if( !(fdl=opendl((long)MODE_OLDFILE)) )
return 2;
INIT_DISKNAMES;
init_bufblks();
/* finds the disk name in DiskList */
while( getstr(buffer,fdl) !=NULL )
{
if( strstr(buffer,glargv[2],1) )
{
if( storename(buffer) )
remove_cleanup(3)
}
}
if( fcnerr )
remove_cleanup(4);
Seek(fdl,0L,(long)OFFSET_BEGINNING);
if( storedl() )
remove_cleanup(5)
Close(fdl);
if( !(fdl=opendl((long)MODE_NEWFILE)) )
{
FREE_DISKNAMES;
free_bufblks();
return 6;
}
/* write the in memory disklist to the one in ram: */
for(i=0; i<=bufcount; i++)
if( fputstr(bufferblock[i],fdl) )
remove_cleanup(7)
remove_free();
return 0;
}
void remove_free()
{
Close(fdl);
FREE_DISKNAMES;
free_bufblks();
}
/* loads the DiskList into memory but leaves out the directories in the
diskname list, pointed to by firstdisk */
storedl()
{
int storeit=1; /* saving this directory */
/* doesn't store directories that are in the temp file */
while( getstr(buffer,fdl) !=NULL )
{
if( strchr(buffer,(char)STARTCHAR) )
{
storeit=1;
diskptr=firstdisk;
while(diskptr)
{
if( strstr(buffer,diskptr->name,1) )
{
storeit=0;
break;
}
diskptr=diskptr->next;
}
}
if(storeit)
if( store(buffer) )
return 1;
}
return fcnerr;
}
/* Saves the name of a disk in a linked list structure */
storename(buffer)
char *buffer;
{
if( diskptr==NULL )
{
if( (firstdisk=(struct disk *)malloc(sizeof(struct disk)) )==NULL)
{
putstr(outofmem);
return 1;
}
diskptr=firstdisk;
strncpy(diskptr->name,buffer,MAXBUF);
diskptr->next=NULL;
}
else
{
if( (diskptr->next=(struct disk *)malloc(sizeof(struct disk)) )==NULL)
{
putstr(outofmem);
return 2;
}
diskptr=diskptr->next;
strncpy(diskptr->name,buffer,MAXBUF);
diskptr->next=NULL;
}
return 0;
}
void free_disknames()
{
struct disk *p;
while(firstdisk)
{
p=firstdisk->next;
free(firstdisk);
firstdisk=p;
}
}
/* prints line to stdout unskrunched */
/* format [BYTE]=> [SKRUNCHAR] [# of spaces ] */
void unskrunch(line)
char *line;
{
char output[LINELEN], *p;
int i;
p=output;
while(*line)
{
switch((int)*line)
{
case SKRUNCHAR : line++;
for(i=SKRUNOFFS; i<(int)*line; i++)
*(p++)=' ';
break;
case STARTCHAR : strncpy(p,STARTSTR,MAXBUF);
p+=strlen(STARTSTR);
break;
default : *(p++)=*line;
}
line++;
}
*p='\0';
putstr(output);
}
char *skrunch(line)
char *line;
{
char skbuf[LINELEN],*p;
int spaces=0;
/* first tokenizes the STARTSTR/XnSTR if in line */
tokenize(line,STARTSTR,STARTCHAR);
/* this is the compaction of >2 spaces */
p=skbuf;
while( *line )
{
if( *line==' ' )
spaces++;
else
{
if( spaces )
if( spaces>2 )
{
*(p++)=(char)SKRUNCHAR;
*(p++)=(char)(spaces+SKRUNOFFS);
spaces=0;
}
else
{
*(p++)=' ';
if( spaces>1 ) *(p++)=' ';
spaces=0;
}
*p=*line;
p++;
}
line++;
}
*p='\0';
strncpy(buffer,skbuf,MAXBUF);
return buffer;
}
/* will tokenize first occurance of STR in LINE */
tokenize(line,str,chr)
char *line,*str;
int chr;
{
char *p,*q;
if( p=strstr(line,str,1) )
{
q=p+strlen(str);
*p=(char)chr;
strncpy(p+1,q,MAXBUF);
return 1;
}
return 0;
}
/* Uses: chrcount bufcount bufferblock[] bufptr */
/* stores line to memory */
store(buffer)
char *buffer;
{
int i;
i=strlen(buffer);
chrcount+=i;
if( chrcount>=BLKSIZE )
{
*bufptr='\0';
chrcount=i;
if( (++bufcount)>=BUFBLKS )
{
putstr("Error: DiskList too large (Increase buffer size in source).\n");
return 1;
}
if( (bufferblock[bufcount]=(char *)malloc(BLKSIZE) )==NULL)
{
putstr(outofmem);
return 2;
}
bufptr=bufferblock[bufcount];
}
strncpy(bufptr,buffer,MAXBUF);
bufptr+=i;
return 0;
}
void init_bufblks()
{
bufptr=NULL;
bufcount=-1;
chrcount=BLKSIZE+1;
}
void free_bufblks()
{
int i;
for(i=1; i<=bufcount; i++)
free(bufferblock[i]);
}
/* OK, this is not quite a true strstr() with case switch.
The sub string must be in upper case if kase=0 (?!sorry) */
char *strstr(str,sub,kase)
char *str,*sub;
int kase;
{
int length;
length=strlen(sub);
if( kase )
str=strchr(str,*sub);
else
str=strchr(strtoupper(str),*sub);
while( str )
{
if( strncmp(str,sub,length) )
str++;
else
return str;
str=strchr(str,*sub);
}
return NULL;
}
char *strtoupper(s)
char *s;
{
register char *p = s;
while(*p)
{
*p = toupper(*p);
p++;
}
return(s);
}
void get_dlpath()
{
struct FileLock *lock,*Lock();
if( lock=Lock(dltemp,(long)ACCESS_READ) )
{
dlpath=dltemp;
UnLock(lock);
}
else
dlpath=dldisk;
}
struct FileHandle *opendl(mode)
long mode;
{
struct FileHandle *fdl;
if( (fdl=Open(dlpath,mode))==NULL)
{
putstr("Error: Could not open DiskList\n");
return 0;
}
return fdl;
}
#define MODE_APPEND 1000L
struct FileHandle *opentmp(mode)
long mode;
{
struct FileHandle *ftmp;
struct FileLock *lock,*Lock();
int seek=0;
if( mode==MODE_APPEND)
{
if( lock=Lock(tempdl,(long)ACCESS_READ) )
{
UnLock(lock);
mode=(long)MODE_OLDFILE;
seek=1;
}
else
mode=(long)MODE_NEWFILE;
}
if( (ftmp=Open(tempdl,mode))==NULL)
{
putstr("Error: Could not open RAM:TempDL\n");
return 0;
}
if( seek )
Seek(ftmp,0L,(long)OFFSET_END);
return ftmp;
}
sdir(recur)
int recur;
{
char *p;
if( glargc>2 )
p=glargv[2];
else
p=sdir_pat;
if( !(ftmp=opentmp(MODE_APPEND)) )
return 1;
if( do_ls(p,ftmp,recur) )
{
Close(ftmp);
return 2;
}
Close(ftmp);
return 0;
}
#define ls_cleanup(x) { ls_free(lock,f_info); return x; }
do_ls(pat,fh,recur)
char *pat;
struct FileHandle *fh;
int recur;
{
struct FileLock *lock=NULL, *Lock();
struct FileInfoBlock *f_info;
char *s, *tempstr;
int slen, isadir, col, patchg=0, firstrun=1;
char *spaces1, *spaces2;
struct disk *nextdir;
char basename[80], tempname[80];
/* strings of 18 & 36 spaces for formatting output */
/* 012345678901234567 */
spaces1=" ";
/* 0123456789012345678901234567890123456 */
spaces2=" ";
INIT_DISKNAMES;
nextdir=NULL;
strncpy(tempname,"/",2);
tempstr=tempname+1;
if((f_info=(struct FileInfoBlock *)
AllocMem((long)sizeof(struct FileInfoBlock),0L))==0)
{
putstr(outofmem);
FREE_DISKNAMES;
return 1;
}
do
{
if( firstdisk )
{
while( *(nextdir->name)=='/' )
{
strncpy(basename,(nextdir->name)+1,79);
strncpy(basename+strlen(basename),"/",2);
nextdir=nextdir->next;
if( !nextdir )
ls_cleanup(0)
}
strncpy(tempname+1,basename,78);
slen=strlen(tempname);
strncpy(tempname+slen,nextdir->name,79-slen);
if( storename(tempname) )
ls_cleanup(1);
pat=tempname+1;
}
do
{
if( firstrun )
{
if(patchg==1)
{
patchg=2;
strncpy(tempstr,f_info->fib_FileName,78);
slen=strlen(tempstr);
tempstr[slen]=':';
strncpy(tempstr+slen+1,s+4,78-slen);
pat=tempstr;
}
else if( strchr(pat,':')<strchr(pat,'\0')-1 )
{
patchg=2;
if( !(strncmp(pat,"df0:",4) && strncmp(pat,"df1:",4)) )
{
patchg=1;
strncpy(tempstr,pat,4);
*(tempstr+4)='\0';
s=pat;
pat=tempstr;
}
}
}
if((lock=Lock(pat,(long)ACCESS_READ))==0)
ls_cleanup(2)
if((Examine(lock,f_info))==0)
ls_cleanup(3)
}
while( patchg==1 );
firstrun=0;
if( fputstr(STARTSTR,fh) )
ls_cleanup(4)
if( firstdisk )
{
fputstr(tempname+1,fh);
fputstr ("\n",fh);
}
else
{
if( patchg )
{
patchg=0;
if( fputstr(pat,fh) )
ls_cleanup(5)
fputstr ("\n",fh);
strcpy(basename,pat,79);
slen=strlen(basename);
basename[slen++]='/';
basename[slen]='\0';
}
else
{
if( fputstr(f_info->fib_FileName,fh) )
ls_cleanup(6)
fputstr (":\n",fh);
strncpy(basename,f_info->fib_FileName,78);
slen=strlen(basename);
basename[slen++]=':';
basename[slen]='\0';
}
}
col=0;
while( (ExNext(lock,f_info))!=0)
{
s=f_info->fib_FileName;
slen=strlen(s);
isadir= (f_info->fib_DirEntryType>0);
if((col == 3) && slen >18) {
fputstr("\n",fh);
col = 0;
}
if (isadir)
fputstr ("\033[33m ",fh);
else
fputstr (" ",fh);
if (slen >18) {
if( fputstr(s,fh) )
ls_cleanup(7)
col += 2;
if( fputstr(spaces2+slen,fh) )
ls_cleanup(8)
}
else {
if( fputstr(s,fh) )
ls_cleanup(9)
if( fputstr(spaces1+slen,fh) )
ls_cleanup(10)
col++;
}
if( isadir && recur )
if(storename(s))
ls_cleanup(1);
if (isadir)
fputstr("\033[0m",fh);
if (col > 3) {
fputstr("\n",fh);
col = 0;
}
}
fputstr("\n",fh);
if( col )
fputstr("\n",fh);
UnLock(lock);
lock=NULL;
if( nextdir )
nextdir=nextdir->next;
else
nextdir=firstdisk;
}
while( nextdir );
ls_free(lock,f_info);
return 0;
}
void ls_free(lock,f_info)
struct FileLock *lock;
struct FileInfoBlock *f_info;
{
if( lock )
UnLock(lock);
FreeMem(f_info,(long)sizeof(struct FileInfoBlock));
FREE_DISKNAMES;
}
void putstr(str)
char *str;
{
Write(confh,str,(long)strlen(str));
}
fputstr(str,fh)
char *str;
struct FileHandle *fh;
{
long len;
len=(long)strlen(str);
if( Write(fh,str,len)==len)
return 0;
return 1;
}
/* must be used in the WHILE( GETSTR()!=NULL) fashion */
char *getstr(line,f)
char *line;
struct FileHandle *f;
{
static char *buffer, *bufptr;
static int last_read;
int len, n=MAXBUF;
char temp, *p, empty='\0';
if( !buffer )
{
if( (buffer=(char *)AllocMem((long)CP_BUFF+1,0L))==0)
{
putstr(outofmem);
fcnerr=1;
return (char *)0;
}
bufptr=∅
}
while(1)
if( p=strchr(bufptr,'\n') )
{
temp=*(++p);
*p='\0';
strncpy(line,bufptr,n);
*p=temp;
bufptr=p;
return line;
}
else
{
strncpy(line,bufptr,n);
len=strlen(line);
n-=len;
line+=len;
if( last_read )
{
FreeMem(buffer,CP_BUFF);
buffer=0;
last_read=0;
return (char *)0;
}
else
if( (len=Read(f,buffer,CP_BUFF)) <1 )
last_read=1;
else
{
last_read= len!=CP_BUFF;
bufptr=buffer;
*(buffer+len)='\0';
}
}
}
savedl()
{
if( update() )
return 1;
if( strcmp(dlpath,dldisk) )
{
if( copy(dlpath,dldisk) )
return 1;
DeleteFile(dlpath);
DeleteFile(tempdl);
}
return 0;
}
loaddl()
{
if( strcmp(dltemp,dlpath) )
if( copy(dlpath,dltemp) )
return 1;
return 0;
}
newdl()
{
struct FileHandle *fh;
putstr("Are you sure? ");
Read(confh,buffer,LINELEN);
if( *buffer=='y' )
{
if( fh=Open(dlpath,(long)MODE_NEWFILE) )
{
Close(fh);
return 0;
}
return 1;
}
return 0;
}
copy(src,dest)
char *src,*dest;
{
struct FileHandle *sfh,*dfh;
char *buffer;
int len;
if((sfh=Open(src,(long)MODE_OLDFILE))==0)
return 1;
if((dfh=Open(dest,(long)MODE_NEWFILE))==0)
{
Close(sfh);
return 2;
}
if( (buffer=(char *)AllocMem(CP_BUFF,0L))==0)
{
Close(sfh);
Close(dfh);
putstr(outofmem);
return 3;
}
do
{
len=Read(sfh,buffer,CP_BUFF);
Write(dfh,buffer,(long)len);
}
while( len!=0 );
FreeMem(buffer,CP_BUFF);
Close(sfh);
Close(dfh);
return 0;
}