 /*
  * read the aliases file looking for a particular alias.  returns a struct
  * describing that alias if found or NULL if not found (or an error occurs).
  * format of lines in the alias file are:
  * 
  * ; indicates start of a comment
  * 
  * <alias> <service name> <pin> <max message> <max page>
  */

#include "memory.h"

#define TEMPLATE "NAME/A,SERVICE/A,PIN/A,MAXMSG/N/A,MAXPAGE/N/A"
  enum templateArgs {
	  ARG_NAME,
	  ARG_SERVICE,
	  ARG_PIN,
	  ARG_MAXMSG,
	  ARG_MAXPAGE,
	  ARG_sizeof
  };

#define INPUT_BUFFER_SIZE (1024)

PagerAlias_t *__saveds __asm FindPagerAlias(register __a0 PagerHandle_t * ph, register __a1 STRPTR aliasName)
{
	PrivatePagerAlias_t *pals;
	PagerAlias_t *als;
	ULONG line = 0;
	STRPTR inputBuffer, ptr;
	struct RDArgs *ArgsPtr, *MyArgs;
	char *ArgArray[ARG_sizeof];
	BOOL leave;
	BPTR fh;

	ObtainSemaphore(&ph->ph_Sema);

	/* first look to see if we have already read this alias in */

	for (pals = (PrivatePagerAlias_t *) ph->ph_AliasList.mlh_Head;
	     pals->pals_Node.mln_Succ;
	     pals = (PrivatePagerAlias_t *) pals->pals_Node.mln_Succ)
		if (stricmp(aliasName, pals->pals_Alias.als_Name) == 0) {
			pals->pals_UseCount++;
			ReleaseSemaphore(&ph->ph_Sema);
			return &pals->pals_Alias;
		}

	/*
	 * oh, well.  need to read the aliases file to find information on
	 * this aliases
	 */

	als = NULL;

	if (inputBuffer = MyAllocVec(INPUT_BUFFER_SIZE)) {
		/* try and open the aliases file */

		if (fh = Open("pager:aliases", MODE_OLDFILE)) {
			/* loop reading lines looking for the alias desired */

			leave = FALSE;

			while (leave == FALSE && FGets(fh, inputBuffer, INPUT_BUFFER_SIZE - 1)) {
				line++;

				/*
				 * check to make sure the line isn't all
				 * blank
				 */

				ptr = inputBuffer;
				while (isspace(*ptr))
					ptr++;

				if (!*ptr)
					continue;

				/*
				 * check for comment character at beginning
				 * of line
				 */

				if (*ptr == ';')
					continue;

				/* setup to call ReadArgs() to parse the line */

				if (MyArgs = (struct RDArgs *)AllocDosObject(DOS_RDARGS, TAG_DONE)) {
					MyArgs->RDA_Flags |= RDAF_NOPROMPT;
					MyArgs->RDA_Source.CS_Buffer = inputBuffer;
					MyArgs->RDA_Source.CS_Length = strlen(inputBuffer);
					MyArgs->RDA_Source.CS_CurChr = 0L;

					memset((char *)ArgArray, 0, sizeof(ArgArray));
					if (ArgsPtr = ReadArgs(TEMPLATE, (LONG *)&ArgArray, MyArgs)) {
						if (stricmp(aliasName, ArgArray[ARG_NAME]) == 0) {

							/*
							 * we've found the
							 * alias so allocate
							 * and fill in a
							 * alias structure
							 */
							leave = TRUE;

							if (pals = (PrivatePagerAlias_t *) MyAllocVec(sizeof(PrivatePagerAlias_t) + strlen(ArgArray[ARG_NAME]) + strlen(ArgArray[ARG_SERVICE]) + strlen(ArgArray[ARG_PIN]) + 3)) {
								pals->pals_Handle = ph;
								pals->pals_UseCount = 1;
								AddTail((struct List *)&ph->ph_AliasList, (struct Node *)&pals->pals_Node);

								als = &pals->pals_Alias;

								als->als_Name = (STRPTR)&als[1];
								als->als_Service = als->als_Name + strlen(ArgArray[ARG_NAME]) + 1;
								als->als_PIN = als->als_Service + strlen(ArgArray[ARG_SERVICE]) + 1;

								strcpy(als->als_Name, ArgArray[ARG_NAME]);
								strcpy(als->als_Service, ArgArray[ARG_SERVICE]);
								strcpy(als->als_PIN, ArgArray[ARG_PIN]);
								als->als_MaxMessageLen = *((LONG *)ArgArray[ARG_MAXMSG]);
								als->als_MaxPageLen = *((LONG *)ArgArray[ARG_MAXPAGE]);
							}
						}

						FreeArgs(ArgsPtr);
					}
					else {
						Fault(IoErr(), NULL, inputBuffer, INPUT_BUFFER_SIZE - 1);
						ULog(ph, -1, "Error in aliases file - line %ld: %s", line, inputBuffer);
						leave = TRUE;
					}

					FreeDosObject(DOS_RDARGS, MyArgs);
				}
			}

			Close(fh);
		}
		else
			ULog(ph, -1, "Couldn't open aliases file");

		MyFreeVec(inputBuffer);
	}

	ReleaseSemaphore(&ph->ph_Sema);

	return als;
}

void __saveds __asm FreePagerAlias(register __a0 PagerAlias_t * als)
{
	PrivatePagerAlias_t *pals;

	if (als) {
		pals = (PrivatePagerAlias_t *) ((size_t) als - offsetof(PrivatePagerAlias_t, pals_Alias));

		ObtainSemaphore(&pals->pals_Handle->ph_Sema);

		if (--pals->pals_UseCount == 0) {
			Remove((struct Node *)&pals->pals_Node);
			MyFreeVec(pals);
		}

		ReleaseSemaphore(&pals->pals_Handle->ph_Sema);
	}
}
