/*
          Asn - Perform logical device and environment var assigns
                from a list file.

          Original effort by Fabio Rossetti.

          (c) 1989 by Fabio Rossetti

	  To compile under Lattice C v5.0x use:

		lc -O -v -cus asn
		blink lib:cres.o asn.o to asn lib lib:a.lib lib:lc.lib sd nd

*/

#include <exec/types.h>
#include <exec/memory.h>
#include <exec/libraries.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <libraries/arpbase.h>
#include <arpfunctions.h>
#include <proto/exec.h>
		

/* assign list file buffer */
#define BUFSIZE 4096
#define DEFAULT_FILE "DEVS:AssignList"

/* flag values */
#define SPLIT_COMMENT 3		
#define SPLIT_NAME 2
#define OKAY 1
#define ASSIGNEM 1
#define DONTASSIGNEM 0

/* token identifiers */
#define NAME 0
#define VALUE 1

struct ArpBase *ArpBase;
BPTR fh,FH;
struct Process *Pr;

TEXT Token[2][256]; /* buffers to hold token names (devices, var names & values) */
TEXT Env[108] = "ENV:"; /* buffer to hold filename of 1.3 ENV: variable */

/* Trick to keep code down to size */
VOID MemCleanup()
{
}
/* as above */
VOID _main(Line)
STRPTR Line;

{
	
	STRPTR argv;
	LONG retcod;

	REGISTER TEXT *Fil,*Buf,*i,*EndOfBuf;
	REGISTER LONG count,Pos=0;
	struct {
		unsigned StOfBuf : 2;
		unsigned Do : 1;
		unsigned TokenType : 1;
		} St;

	St.StOfBuf=OKAY;
	
	Pr = (struct Process*)FindTask(NULL);
	
	if(!(ArpBase = (struct ArpBase*)OpenLibrary(ArpName,ArpVersion))){
			Pr->pr_Result2=ERROR_INVALID_RESIDENT_LIBRARY;
			exit(RETURN_FAIL);
			}
	
	/* parse command line */

		argv =  NULL;

	while(*Line > ' ')
		++Line;

	/* don't need argc */
	(VOID)GADS(++Line,
		strlen(Line),
		"Usage: Asn [AssignListFile]",
		&argv,
		"FILE");


	/* use default file if no argument's given */
	Fil = (argv == NULL) ? DEFAULT_FILE  : argv;

	if (!(fh=ArpOpen(Fil,MODE_OLDFILE))) 
		{
		 retcod=IoErr();
		 Printf("Error: Couldn't open %s\n",Fil);
		 CloseLibrary((struct Library*)ArpBase);
		 Pr->pr_Result2=retcod;

		exit(RETURN_ERROR);
		}

	if (!(Buf=(TEXT *)ArpAllocMem(BUFSIZE,MEMF_PUBLIC | MEMF_CLEAR)))
		{
		Puts("No memory!");
		CloseLibrary((struct Library*)ArpBase);
		Pr->pr_Result2=ERROR_NO_FREE_STORE; 
		exit(RETURN_FAIL);
		}

	while (count = Read(fh,Buf,BUFSIZE)) {
	
	/* point end of actually read data */
	EndOfBuf = (TEXT *) Buf+count;

	/* scan file buffer */	
	for (i=Buf;i < EndOfBuf; i++) {
	
	/* Check for ^C */
	if (SetSignal(0,0) & SIGBREAKF_CTRL_C) {
			Puts("***BREAK");
			CloseLibrary((struct Library*)ArpBase);
			exit(RETURN_WARN);
			}
		
		/* skip comments */
		if (((*i == '/') && (*(i+1) == '*')) ||
				 St.StOfBuf == SPLIT_COMMENT) {		
			while(!((i >= EndOfBuf) ||
				((*i == '*') && (*(i+1) == '/')))) i++;
			if (i >= EndOfBuf) St.StOfBuf = SPLIT_COMMENT;
			if ((*i == '*') && (*(i+1) == '/')) {
					St.StOfBuf = OKAY;
					i+=2;
					}
			}

		St.Do = DONTASSIGNEM;

		if (((*i >=33) && (*i <=126)) || (St.StOfBuf == SPLIT_NAME)) {
			while(!((i>=EndOfBuf) || (*i <33) || (*i >126))) 
				Token[St.TokenType][Pos++] = *i++;
			if (i>=EndOfBuf) St.StOfBuf = SPLIT_NAME;
			else {
				St.StOfBuf = OKAY;
				if ((*i <33) || (*i >126)) {
				Token[St.TokenType][Pos] = '\0';
				if (St.TokenType==NAME) {
					St.TokenType = VALUE;
					St.Do = DONTASSIGNEM;
							}
				else {
					St.TokenType = NAME;
					St.Do = ASSIGNEM;
					}
				Pos = 0;
					}
			
				}
			}

		/* do device-var assignment */
		if (St.Do == ASSIGNEM) {
			/* ARP/MANX var */
			if ((Toupper(Token[NAME][0]) == 'M') &&
	 			(Token[NAME][1] == '_')      &&
				(Token[NAME][2] != '\0')) {if
				((!(Setenv(&(Token[NAME][2]),Token[VALUE])))) 
				Printf("Error: Unable to set ARP/MANX var %s as %s\n",
						&(Token[NAME][2]),
						Token[VALUE]); }	

			/* 1.3 environment var */
			else if ((Toupper(Token[NAME][0]) == 'E') &&
 					(Token[NAME][1] == '_')   &&
					(Token[NAME][2] != '\0') ) {
			strcat(Env,&(Token[NAME][2]));
			if (!(FH = ArpOpen(Env,MODE_NEWFILE)) || 
				!(Write(FH,Token[VALUE],
					strlen(Token[VALUE]))))
				Printf("Error: Unable to set environment var %s as %s\n",
						&(Token[NAME][2]),
						Token[VALUE]);
				/* reset var filename buffer */	
				Env[4] = '\0';
				}
			/* logical device assign */	
			else {
				/* strip colon in logical device name */
				Token[NAME][strlen(Token[NAME])-1] = '\0';
				if (!(Assign( Token[NAME],
				  Token[VALUE]) == ASSIGN_OK)){
				Printf ("Error: Unable to assign %s: to %s\n",
						Token[NAME],
						Token[VALUE]);	
				}
				}
			}			
			}
	}

	 CloseLibrary((struct Library*)ArpBase);	
}
