#define UmsBase UMSBase

#include <exec/types.h>

#include <utility/hooks.h>

#include <clib/exec_protos.h>
#ifdef _DCC
#include <proto/exec.h>
#else
#include <pragmas/exec_pragmas.h>
#endif

#include <libraries/ums.h>
#include <clib/ums_protos.h>
#ifdef _DCC
#include <proto/ums.h>
#else
#include <pragmas/ums_pragmas.h>
#include <dos.h>
#endif

#include <dos/dos.h>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "umsfilter.h"


// Version String
// --------------

static char VersionString[] = "$VER: sumsset 2.3 (03.11.93)";

static char UsageString[] = "\
 Usage: sumsset <user> <password> <filter> <setbits> [<clrbits>]\n\
  <user>    : user name.\n\
  <password>: user's password.\n\
  <filter>  : filter specification.\n\
  <setbits> : bits to set (bit spec string).\n\
  <clrbits> : bits to clear (bit spec string).\n\
";


// Globals
// -------

struct Library *UMSBase = NULL;
UMSUserAccount acc = NULL;

struct BitSpec
{
	char *name;
	LONG bit;
	BOOL global;
} BitSpecs[] =
{
	{ "Archive"    , UMSUSTATF_Archive    ,FALSE },
	{ "Junk"       , UMSUSTATF_Junk       ,FALSE },
	{ "PostPoned"  , UMSUSTATF_PostPoned  ,FALSE },
	{ "Selected"   , UMSUSTATF_Selected   ,FALSE },
	{ "Old"        , UMSUSTATF_Old        ,FALSE },
	{ "WriteAccess", UMSUSTATF_WriteAccess,FALSE },
	{ "ReadAccess" , UMSUSTATF_ReadAccess ,FALSE },
	{ "ViewAccess" , UMSUSTATF_ViewAccess ,FALSE },
 	{ "Owner"      , UMSUSTATF_Owner      ,FALSE },
	{ "UFlag0"     , (1<<0 )              ,FALSE },
	{ "UFlag1"     , (1<<1 )              ,FALSE },
	{ "UFlag2"     , (1<<2 )              ,FALSE },
	{ "UFlag3"     , (1<<3 )              ,FALSE },
	{ "UFlag4"     , (1<<4 )              ,FALSE },
	{ "UFlag5"     , (1<<5 )              ,FALSE },
	{ "UFlag6"     , (1<<6 )              ,FALSE },
	{ "UFlag7"     , (1<<7 )              ,FALSE },
	{ "UFlag8"     , (1<<8 )              ,FALSE },
	{ "UFlag9"     , (1<<9 )              ,FALSE },
	{ "UFlagA"     , (1<<10)              ,FALSE },
	{ "UFlagB"     , (1<<11)              ,FALSE },
	{ "UFlagC"     , (1<<12)              ,FALSE },
	{ "UFlagD"     , (1<<13)              ,FALSE },
	{ "UFlagE"     , (1<<14)              ,FALSE },
	{ "UFlagF"     , (1<<15)              ,FALSE },
	{ "Deleted"    , UMSGSTATF_Deleted    ,TRUE  },
	{ "Expired"    , UMSGSTATF_Expired    ,TRUE  },
	{ "Exported"   , UMSGSTATF_Exported   ,TRUE  },
	{ "Orphan"     , UMSGSTATF_Orphan     ,TRUE  },
	{ "Link"       , UMSGSTATF_Link       ,TRUE  },
	{ "HardLink"   , UMSGSTATF_HardLink   ,TRUE  },
	{ NULL,0,0 }
};


struct BitSpec *FindBit(char *name)
{
	struct BitSpec *b=BitSpecs;
	while (b->name)
	{
		if (!stricmp(b->name,name)) return(b);
		b++;
	}
	return(NULL);
}


// CTRL-C Stuff
// ------------

int brk(void)
{
	return(0);
}

#define ABORTED (SetSignal(0,0) & SIGBREAKF_CTRL_C)


// Main Function
// -------------

int main(int argc,char *argv[])
{
	char *filter;
	int erg = 20;
	int anz = -1;
	int fi;
	LONGBITS GlobalSet=0,GlobalClear=0,UserSet=0,UserClear=0;

	onbreak(brk);

	if (argc<5 || argv[1][0]=='?' || argc>6)
	{
		struct BitSpec *b=BitSpecs;
		int i=0;
		fprintf(stderr,"\33[1m%s\33[0m, written by Stefan Stuntz, Public Domain.\n%s",&VersionString[6],UsageString);
		fprintf(stderr,"  bit-specs : ");
		while (b->name)
		{
			fprintf(stderr,"%s%c ",b->name,(b+1)->name ? ',' : '.');
			b++;
			if (++i==6) { i=0; fprintf(stderr,"\n              "); }
		}
		fprintf(stderr,"\n");
		return(5);
	}

	filter=argv[3];

	if (*argv[4])
	{
		char *arg;
		char *buf=strdup(argv[4]);
		struct BitSpec *b;
		for (arg = strtok(buf, ","); arg; arg = strtok(NULL, ","))
		{
			if (!(b=FindBit(arg)))
			{
				fprintf(stderr,"\7Invalid bit spec: \"%s\"\n",arg);
				return(20);
			}
			if (b->global) GlobalSet|=b->bit;
			else           UserSet  |=b->bit;
		}
	}

	if (argc==6 && *argv[5])
	{
		char *arg;
		char *buf=strdup(argv[5]);
		struct BitSpec *b;
		for (arg = strtok(buf, ","); arg; arg = strtok(NULL, ","))
		{
			if (!(b=FindBit(arg)))
			{
				fprintf(stderr,"\7Invalid bit spec: \"%s\"\n",arg);
				return(20);
			}
			if (b->global) GlobalClear|=b->bit;
			else           UserClear  |=b->bit;
		}
	}

	if (UMSBase = OpenLibrary("ums.library",10))
	{
		if (acc = UMSLogin(argv[1],argv[2]))
		{
			if (!(fi = UmsFilterExpression(filter,acc,0,0,1)))
			{
				if (GlobalSet || GlobalClear)
				{
					anz=UMSSelectTags(acc,
			       UMSTAG_SelReadLocal  ,TRUE,
			       UMSTAG_SelMask       ,1,
			       UMSTAG_SelMatch      ,1,
			       UMSTAG_SelWriteGlobal,TRUE,
			       UMSTAG_SelSet        ,GlobalSet,
			       UMSTAG_SelUnset      ,GlobalClear,
			       TAG_DONE);
				}

				if (UserSet || UserClear)
				{
					anz=UMSSelectTags(acc,
			       UMSTAG_SelReadLocal  ,TRUE,
			       UMSTAG_SelMask       ,1,
			       UMSTAG_SelMatch      ,1,
			       UMSTAG_SelSet        ,UserSet,
			       UMSTAG_SelUnset      ,UserClear,
			       TAG_DONE);
				}

				if (anz==-1)
				{
					anz=UMSSelectTags(acc,
			       UMSTAG_SelReadLocal  ,TRUE,
			       UMSTAG_SelMask       ,1,
			       UMSTAG_SelMatch      ,1,
			       TAG_DONE);
				}

				printf("%5ld Msgs (%s).\n",anz,filter);
				erg = 0;
			}
			else printf("\7Expression Error %ld\n",fi);

			UMSLogout(acc);
		}
		else printf("\7UMS-Login failed.\n");

		CloseLibrary(UMSBase);
	}
	else printf("\7Could not open ums.library V10.\n");

	return(erg);
}
