#include "sumstl.h"


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

static char VersionString[] = "\0$VER: sumsset "VERSION" ("__DATE__"), written by Stefan Stuntz, Public Domain";

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 },
	{ "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
// ------------

VOID chkabort(VOID) {}
#define ABORTED (SetSignal(0,0) & SIGBREAKF_CTRL_C)


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

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

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

	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(RETURN_FAIL);
			}
			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(RETURN_FAIL);
			}
			if (b->global) GlobalClear|=b->bit;
			else           UserClear  |=b->bit;
		}
	}

	if (UmsBase = OpenLibrary("ums.library",9))
	{
		if (acc = UMSLogin(argv[1],argv[2]))
		{
			if (UmsFilter(acc,filter,FALSE)!=-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);
				}

				printf("%5d Msgs (%s).\n",anz,filter);
			}
			else printf("\7Invalid filter specified.\n");

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

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

	return(erg);
}
