
 /* file sizenote.c */
 /* compile using Lattice C 5.02 using lc -O -L -cs sizenote.c */

 #include <string.h>
 #include <proto/exec.h>
 #include <proto/dos.h>
 #include <stdlib.h>
 #include <stdio.h>

 int recflg;
 int testflg;
 int clearflg;
 int breakflg;

 extern int __stdargs onbreak(int (*func)());
 int breakfunc(void);
 void usage(char **argv);
 void flagtest(char c,char **argv);
 int Notate(char *dirname,BPTR dirlock,struct FileInfoBlock *info);

 void main(int argc,char **argv)
     {
     BPTR lock;
     struct FileInfoBlock *info;
     int error,i; 

     if(onbreak(breakfunc))
 	{
 	printf("Couldn't set break trap!\n");
	exit(10);
	}

    recflg=FALSE;
    testflg=FALSE;
    clearflg=FALSE;
    breakflg=FALSE;

    if(argc == 3)
	{
	i=0;
	if(argv[1][i++]!='-')
	    {
	    usage(argv);
	    exit(10);
	    }
	while(argv[1][i]!='\0')
	    flagtest(argv[1][i++],argv);
	}
    else
	if(argc != 2)
	    {
	    usage(argv);
	    exit(10);
	    }

    DOSBase=OpenLibrary("dos.library",0);

    if(!DOSBase)
	{
	printf("Can't open DOS Library!\n");
	exit(10);
	}

    lock=Lock(argv[argc-1],ACCESS_READ);

    if(!lock)
	{
	printf("Invalid directory name!\n");
	usage(argv);
	CloseLibrary(DOSBase);
	exit(10);
	}

    info=AllocMem(sizeof(struct FileInfoBlock),0);
    if(!info)
	{
	printf("Not enough free memory!\n");
	UnLock(lock);
	CloseLibrary(DOSBase);
	exit(10);
	}

    if(!Examine(lock,info))
	{
	printf("Couldn't get information for directory!\n");
	FreeMem(info,sizeof(struct FileInfoBlock));
	UnLock(lock);
	CloseLibrary(DOSBase);
	exit(10);
	}

    if(info->fib_DirEntryType <= 0)
	{
	printf("File %s is not a directory!\n",argv[argc-1]);
	FreeMem(info,sizeof(struct FileInfoBlock));
	UnLock(lock);
	CloseLibrary(DOSBase);
	exit(10);
	}

    error=Notate(argv[argc-1],lock,info);
    FreeMem(info,sizeof(struct FileInfoBlock));
    UnLock(lock);
    CloseLibrary(DOSBase);
    exit(error);
    }


 int Notate(char *dirname,BPTR dirlock,struct FileInfoBlock *info)
    {
    char filename[100],note[80],*temp,*notetemp;
    struct FileInfoBlock *nextinfo;
    BPTR nextlock;
    int error;

    temp=stpcpy(filename,dirname);
    if(temp[-1] != ':')
	temp=stpcpy(temp,"/");
    notetemp=stpcpy(note,"[33m                    ");
    if(clearflg)
	*note='\0';

    while(ExNext(dirlock,info) && !breakflg)
	{
	stpcpy(temp,info->fib_FileName);

	if(info->fib_DirEntryType <= 0)
	    {
	    sprintf(notetemp,"%10d[m",info->fib_Size);
	    if(testflg)
		{
		if(strcmp(note,info->fib_Comment))
		    {
		    if(clearflg)
			{
			printf("File [32m%s[m has a filenote:\n",filename);
			printf("[33m  %s[m\n\n",info->fib_Comment);
			}
		    else
			printf("File [32m%s[m has changed length!!!\n",filename);
		    }
		}
	    else
		SetComment(filename,note);
	    }
	else
	    if(recflg)
		{
		nextlock=Lock(filename,ACCESS_READ);
		if(!nextlock)
		    {
		    printf("Can't lock directory %s\n",filename);
		    return(10);
		    }

		nextinfo=AllocMem(sizeof(struct FileInfoBlock),0);
		if(!nextinfo)
		    {
		    printf("Not enough free memory!\n");
		    UnLock(nextlock);
		    return(10);
		    }

		if(!Examine(nextlock,nextinfo))
		    {
		    printf("Couldn't get information for directory %s\n",filename);
		    UnLock(nextlock);
		    FreeMem(nextinfo,sizeof(struct FileInfoBlock));
		    return(10);
		    }

		error=Notate(filename,nextlock,nextinfo);
		FreeMem(nextinfo,sizeof(struct FileInfoBlock));
		UnLock(nextlock);
		if(error)
		    return(error);
		}
	chkabort();
	}

    if(IoErr() != ERROR_NO_MORE_ENTRIES && !breakflg)
	{
	printf("Error parsing through directory!\n");
	return(10);
	}

    return(0);
    }

 void usage(char **argv)
    {
    printf("\nSizeNote Version 1.0 by Ross Martin and Bill Williford\n\n");
    printf("Usage:  %s [-[c][r][t]] directory\n\n",argv[0]);
    printf("This program saves the filesize of all files in the directory\n");
    printf("as a filenote that can be seen by AmigaDOS List so that file\n");
    printf("based viruses can be caught.\n\n");
    printf("Option -c causes filenotes to be cleared.\n\n");
    printf("Option -r causes the entire directory tree to be affected.\n\n");
    printf("Option -t causes no filenotes to be written, but a test is made\n");
    printf("to be sure that no file sizes have changed.\n");
    printf("(Useful for in your startup-sequence...)\n\n");
    printf("Options -ct and -crt print the names of all files with filenotes.\n");
    printf("No filenotes are changed.\n\n");
    }

 void flagtest(char c,char **argv)
    {
    switch(c)
	{
	case 't':
	    testflg=TRUE;
	    break;
	case 'c':
	    clearflg=TRUE;
	    break;
	case 'r':
	    recflg=TRUE;
	    break;
	default:
	    printf("Invalid options!!!\n");
	    usage(argv);
	    exit(10);
	}
    }

 int breakfunc(void)
    {
    breakflg=TRUE;
    printf("\n\n[m**** BREAK ****\n\n");
    return 0;
    }

