/*
 * changes from sumsset 2.5 to sumsset_umssupport made by
 *    chr@quack.westfalen.de (22.1.96)
 *
 * sumset V 2.5 in a version, who use the umssupport.library. Only the
 * function UMSSupportFilterExpression() from the lib will be used.
 *
 * (sorry, I haven't a newer code from sumstools.)
 */


#define UmsBase UMSBase

#include <exec/types.h>

#include <utility/hooks.h>

#include <clib/exec_protos.h>
#include <pragmas/exec_pragmas.h>

#include <libraries/dos.h>
#include <clib/dos_protos.h>
#include <pragmas/dos_pragmas.h>
#include <dos.h>

#include <libraries/ums.h>
#include <clib/ums_protos.h>
#include <pragmas/ums_pragmas.h>

#include <dos/dos.h>
#include <dos/rdargs.h>

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

//# include <pragmas/umssup_pragma.h>
//# include <proto/umssup_proto.h>
# include <libraries/umssuplib.h>



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

static char VersionString[] = "$VER: sumsset_umssupport 2.5 (22.1.96)";

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\n\
";


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

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


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

struct Library *UMSBase = NULL;
struct Library *DOSBase = NULL;
struct Library *UMSSupportBase;

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

	onbreak(brk);

	if (DOSBase = OpenLibrary("dos.library", 37L))
	{
      if (UMSSupportBase = (struct Library *) OpenLibrary("umssupport.library",0))
      {
			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");
			}

			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);
							CloseLibrary(UMSSupportBase);
							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);
							CloseLibrary(UMSSupportBase);
							return(20);
						}
						if (b->global) GlobalClear|=b->bit;
						else           UserClear  |=b->bit;
					}
				}
   
				if (UMSBase = OpenLibrary("ums.library",11))
				{
					if (acc = UMSRLogin((char *)opts[OPT_SERVER],(char *)opts[OPT_USER],(char *)opts[OPT_PASSWORD]))
					{
						if (!(fi = UMSSupportFilterExpression((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,
						       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,(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);
				CloseLibrary(UMSSupportBase);
				return(RETURN_ERROR);
			}

         CloseLibrary(UMSSupportBase);
		}
      else
         fprintf(stderr,"\7Could not open umssupport.library.\n");
		CloseLibrary(DOSBase);
	}
	else
		fprintf(stderr,"\7Could not open dos.library.\n");

   if(UMSBase) 
      CloseLibrary((struct Library *) UMSBase);
	return(erg);
}
