
#include <utility/hooks.h>

#include "sumstl.h"

#include <stdio.h>

#ifdef __SASC
#include <dos.h>
#endif

#include "umsfilter.h"

/* SMAKE */


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

static char VersionString[] = "$VER: sumsset 2.8 "__AMIGADATE__;

static char UsageString[] = "\
   U=User     : user name.\n\
   P=Password : user's password.\n\
  FI=Filter   : filter specification.\n\
  SB=SetBits  : bits to set (bit spec string).\n\
  CB=ClrBits  : bits to clear (bit spec string).\n\
   S=Server   : server name.\n\
  FU=ForUser  : modify flags for this user\n\
   Q=Quiet    : work quietly\n\n\
";


// Template
// --------

static char *TemplateString = "U=User/A,P=Password/A,FI=Filter/A,SB=SetBits/A,CB=ClrBits,S=Server/K,FU=ForUser/K,Q=Quiet/S";
enum opts {
	OPT_USER, OPT_PASSWORD, OPT_FILTER, OPT_SETBITS, OPT_CLRBITS, OPT_SERVER,
	OPT_FORUSER, OPT_QUIET, OPT_COUNT};
static LONG opts[OPT_COUNT];


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

extern struct DosLibrary *DOSBase;

struct Library *UMSBase = NULL;
UMSAccount 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[])
{
	int erg = 20;
	int anz = -1;
	int fi;
	LONGBITS GlobalSet=0,GlobalClear=0,UserSet=0,UserClear=0;
	struct RDArgs *args_ptr;

	onbreak(brk);

	if (argc<2 || *argv[1] == '?')
	{
		struct BitSpec *b=BitSpecs;
		int i=0;
		fprintf(stderr,"\33[1m%s\33[0m, written by Stefan Stuntz, Public Domain.\n\nTemplate: %s\n%s",&VersionString[6],TemplateString,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\n");
	}

	{
		int i;

		for (i=0; i<OPT_COUNT; i++)
		opts[i]=NULL;
	}

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

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

		if (UMSBase = OpenLibrary(UMSNAME,UMSVERSION))
		{
			if (acc = UMSRLogin((char *)opts[OPT_SERVER],(char *)opts[OPT_USER],(char *)opts[OPT_PASSWORD]))
			{
				if (!(fi = UmsFilterExpression((char *)opts[OPT_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,
				       opts[OPT_FORUSER]?
                                       UMSTAG_SelWriteUser:
                                       TAG_IGNORE           ,opts[OPT_FORUSER],
				       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);
					}

					if (!opts[OPT_QUIET]) printf("%5ld Msgs (%s).\n",anz,(char *)opts[OPT_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");

		FreeArgs(args_ptr);
	}
	else
	{
		PrintFault(IoErr(), NULL);
		return(RETURN_ERROR);
	}

	return(erg);
}
