/*
   umsreport.lib  by Christian Rütgers chr@quack.westfalen.de '95

   ! Abweichung vom Report-Generierung 0.5
   report.reply kann einen Reply Namen als auch eine Reply Adresse enthalten.
   Das Format ist "Name,Adresse". Der Teil bis zum Komma ist der Name. Wenn
   ein Komma vorhanden ist, wird der Teil danach als Reply Adresse verwendet.
   So kann in einer lokalen Umgebung der Reply an einen spezifizierten User
   gehen, aber auch in einer vernetzten Umgebung an einen User auf einem
   anderen Rechner.

   ! Bitte die Bemerkungen, die mit ! anfangen beachten!

   Erweiterungen und Fehlermeldungen sind erwünscht. In jedem Fall eine
   Mail an mich!

   Bitte die Kommentare zu den Funktionen beachten. Anwendung siehe
   umssupporttest.c

*/

// includes: ------------------------------------------------------------------
# include "umssuplibinternal.h"
# include "include/libraries/umssuplib.h"


// defines: ------------------------------------------------------------------
# define REP_SUBJECT   0
# define REP_TONAME    1
# define REP_TOADDR    2
# define REP_GROUP     3
# define REP_FOLDER    4
# define REP_TEXT      5
# define REP_REFID     6
# define REP_REFNUM    7
# define REP_REPLYNAME 8
# define REP_REPLYADDR 9
# define REP_COMMENT  10
# define REP_NOUPDATE 11
# define REP_SOFTLINK 12

# define TEMPLATE "NAME/A,ADRESSE"
# define OPT_RDANAME  0
# define OPT_RDAADDR  1
# define OPT_COUNT    2

// globals: ------------------------------------------------------------------
extern struct Library *UMSBase;

extern int err;
extern char *umserr;

struct UMSReport *rpt;


// protos: ------------------------------------------------------------------
LONG __saveds __asm ArexxQueryDummy(void);
int __saveds __asm UMSSupportWriteReport(register __a0 struct UMSReport *rpt, register __d3 UMSMsgNum refmsgnum, register __d4 char *RefID, register __d5 char *Subj, register __d6 char *Text);
struct UMSReport *__saveds __asm UMSSupportInitReport(register __d2 UMSUserAccount account, register __d3 char *UserName, register __d4 char *ToolName, register __d5 char *Vstring);
void __saveds __asm UMSSupportFreeReport(register __a0 struct UMSReport *rpt);

/* ------------------------------------------------------------------------ */

/*
  refmsgnum ist die Messagenumber der referierten Mitteilung oder NULL.
  RefID ist die ID der referierten Mitteilung oder NULL.
  Subj ist der Betreff der Fehlermeldung. Der Name des Programms wird vorangestellt.
  Text ist die Fehlermeldung.

  Report geht in eine Gruppe, wenn report.group angegeben.
  Report geht in PM-Folder, wenn report.folder und report.name angegeben.
  Report als PM, wenn nicht report.folder aber report.name angegeben.
  Bsp.: report.name und report.group angegeben: Report in Gruppe und als
        PM.

  Result: 0 bei Fehler
*/

int __saveds __asm
UMSSupportWriteReport(register __a0 struct UMSReport *rpt, register __d3 UMSMsgNum refmsgnum, register __d4 char *RefID, register __d5 char *Subj, register __d6 char *Text)
   {
   struct TagItem errtags[]={ UMSTAG_WSubject,  NULL,         /* REP_SUBJECT  0 */
                              UMSTAG_WToName,   NULL,         /* REP_TONAME   1 */
                              UMSTAG_WToAddr,   NULL,         /* REP_TOADDR   2 */
                              UMSTAG_WGroup,    NULL,         /* REP_GROUP    3 */
                              UMSTAG_WFolder,   NULL,         /* REP_FOLDER   4 */
                              UMSTAG_WMsgText,  NULL,         /* REP_TEXT     5 */
                              UMSTAG_WReferID,  NULL,         /* REP_REFID    6 */
                              UMSTAG_WChainUp,  NULL,         /* REP_REFNUM    7 */
                              UMSTAG_WReplyName,NULL,         /* REP_REPLYNAME 8 */
                              UMSTAG_WReplyAddr,NULL,         /* REP_REPLYADDR 9 */
                              UMSTAG_WComments ,NULL,         /* REP_COMMENT  10 */
                              UMSTAG_WNoUpdate, NULL,         /* REP_NOUPDATE 11 */
                              UMSTAG_WSoftLink, NULL,         /* REP_SOFTLINK 12 */
                              TAG_DONE, 		   NULL};
   char TmpSubj[260];
   UMSMsgNum MsgNum=0;
   
   strcpy(umserr,"\0");

   if(rpt->WriteReport==0)
      return(1);

   if (!*Subj || !*Text) {
      err=ERR_VAR_MISSED;
      return(0);
      }

   sprintf(TmpSubj,"%s: %s", rpt->ToolName, Subj);
   errtags[REP_SUBJECT].ti_Data=(ULONG) TmpSubj;
   errtags[REP_COMMENT].ti_Data=(ULONG) rpt->Comment;
   errtags[REP_NOUPDATE].ti_Data=(ULONG) rpt->SetUnread;
   errtags[REP_REPLYNAME].ti_Data=(ULONG) rpt->ReplyName;
   errtags[REP_REPLYADDR].ti_Data=(ULONG) rpt->ReplyAddr;
   errtags[REP_TEXT].ti_Data=(ULONG) Text;

   if (rpt->ReportName) {
      errtags[REP_TONAME].ti_Data=(ULONG) rpt->ReportName;
      if (rpt->ReportAddr) {
         errtags[REP_TOADDR].ti_Data=(ULONG) rpt->ReportAddr;
         }
      }
   if(refmsgnum) {
      // Nachricht mit refmsgnum vorhanden?
      if(!UMSSearchTags(rpt->report_account, UMSTAG_RMsgNum, refmsgnum, TAG_DONE)) {
         if(RefID)
            // wenn refmsgnum nicht vorhanden zumindest RefID setzen.
            errtags[REP_REFID].ti_Data=(ULONG) RefID;
         }
      else
         errtags[REP_REFNUM].ti_Data=(ULONG) refmsgnum;
      }
   else if(RefID)
      errtags[REP_REFID].ti_Data=(ULONG) RefID;

   if(rpt->ReportGroup) {
      // schreibe Report in Gruppe
      errtags[REP_GROUP].ti_Data=(ULONG) rpt->ReportGroup;
      MsgNum=WriteUMSMsg(rpt->report_account,(struct TagItem *)errtags);
      if (!MsgNum) {
         err=ERR_CANOT_WRITE;
         strcpy(umserr,UMSErrTxt(rpt->report_account));
         return(0);
         }
      }

   if(rpt->ReportName) {
      // Schreibe Report an User und ggfs. in Folder
      errtags[REP_FOLDER].ti_Data=(ULONG) rpt->ReportFolder;
      errtags[REP_GROUP].ti_Data=NULL;
      errtags[REP_SOFTLINK].ti_Data=MsgNum;
      MsgNum=WriteUMSMsg(rpt->report_account,(struct TagItem *)errtags);
      if (!MsgNum) {
         err=ERR_CANOT_WRITE;
         strcpy(umserr,UMSErrTxt(rpt->report_account));
         return(0);
         }
      }
   return(1);
   }

/* ------------------------------------------------------------------------ */
/*
   Username ist der Name an den Replys auf einen Report gesendet werden. Es
   kann nur eine lokale Adresse sein!
   Username ist der Name des eingeloggten Users oder NULL.
   Wenn report.reply gesetzt, wird dessen Inhalt in replyname und ggf.
   replyadress eingetragen.
   Wenn report.reply nicht gesetzt ist, wird Username genommen, wenn der auch
   nicht gesetzt ist der Defaulname "Sysop".

   ToolName ist der Name des Tools, von dem ein Report stammt. Wenn ein
   Konfig- Variable (report.<tool>(.xx)) vorhanden sein soll, muß <tool> identisch
   mit ToolName sein. (z.B. ToolName = m2ums, Intuinews, setfolder ...)

   Result: 0 bei Fehler
*/

// >>> username scheint obsolete, rausschmeißen!

struct UMSReport * __saveds __asm
UMSSupportInitReport(register __d2 UMSUserAccount account, register __d3 char *UserName, register __d4 char *ToolName, register __d5 char *Vstring)
   {
   LONG rda_result[OPT_COUNT];
   /* My custom RDArgs */
   struct RDArgs *rdargs;

   char *charpnt;
   char buffer[256], varname[100];

   if (!account || !*ToolName || !*Vstring) {
      // Die drei muessen da sein!
      err=ERR_VAR_MISSED;
      return(0);
      }

   // erste Inits--------------------------------------------------------------------------------

   rpt = malloc(sizeof(struct UMSReport));
   if (!rpt) {
      err=ERR_NOMEM;
      return(0);
      }

   rpt->report_account = account;

   rpt->ToolName = malloc(strlen(ToolName)+1);
   if (!rpt->ToolName) {
      UMSSupportFreeReport(rpt);
      err=ERR_NOMEM;
      return(0);
      }
   strcpy(rpt->ToolName,ToolName);

   rpt->Comment = malloc(strlen(Vstring)+100);
   if (!rpt->Comment) {
      UMSSupportFreeReport(rpt);
      err=ERR_NOMEM;
      return(0);
      }
   sprintf(rpt->Comment,"Report made by:%s",Vstring);


   // report.user--------------------------------------------------------------------------------

   rpt->ReportAddr=NULL;
   rpt->ReportName=NULL;
   sprintf(varname,"report.%s.user",ToolName);
	charpnt=ReadUMSConfigTags(account,UMSTAG_CfgName, varname,TAG_DONE);
	if(!charpnt)
      charpnt=ReadUMSConfigTags(account,UMSTAG_CfgName,"report.user",TAG_DONE);
	if(charpnt) {
      rda_result[0] = 0L;
      rda_result[1] = 0L;

      strcpy(buffer,charpnt);
      FreeUMSConfig(account,charpnt);

      if (rdargs = (struct RDArgs *)AllocDosObject(DOS_RDARGS, NULL)) {
          strcat(buffer,"\n");
          rdargs->RDA_Source.CS_Buffer = buffer;
          rdargs->RDA_Source.CS_Length = (LONG)strlen(rdargs->RDA_Source.CS_Buffer);
          rdargs->RDA_Flags  = RDAF_NOPROMPT;

          // parse config line
          if (ReadArgs(TEMPLATE, rda_result, rdargs)) {
              if(rda_result[OPT_RDANAME]) {
                 rpt->ReportName = malloc(strlen((UBYTE *) rda_result[OPT_RDANAME])+1);
                 if (!rpt->ReportName) {
                    FreeArgs(rdargs);
                    FreeDosObject(DOS_RDARGS, rdargs);
                    UMSSupportFreeReport(rpt);
                    err=ERR_REPUSER;
                    return(0);
                    }
                 else
                    strcpy(rpt->ReportName,(UBYTE *) rda_result[OPT_RDANAME]);
              }
              else
                 rpt->ReportName=NULL;
              if(rda_result[OPT_RDAADDR]) {
                 rpt->ReportAddr = malloc(strlen((UBYTE *) rda_result[OPT_RDAADDR])+1);
                 if (!rpt->ReportAddr) {
                    FreeArgs(rdargs);
                    FreeDosObject(DOS_RDARGS, rdargs);
                    UMSSupportFreeReport(rpt);
                    err=ERR_REPUSER;
                    return(0);
                    }
                 else
                    strcpy(rpt->ReportAddr,(UBYTE *) rda_result[OPT_RDAADDR]);
              }
              else
                 rpt->ReportAddr=NULL;
          FreeArgs(rdargs);
          }
          else {
            Fault(IoErr(), NULL, buffer, 250);
            strcpy(umserr,buffer);
            FreeDosObject(DOS_RDARGS, rdargs);
            UMSSupportFreeReport(rpt);
            err=ERR_CONFIGERR;
            return(0);
            }
       FreeDosObject(DOS_RDARGS, rdargs);
       }
   }


   // report.replyto--------------------------------------------------------------------------------
   /*
     Wenn report.reply gesetzt, ist Inhalt replyname und ggf. replyadress.
     Wenn Variable nicht gesetzt, wird Username genommen, wenn der auch
     nicht gesetzt ist der Defaulname "Sysop".
   */

   rpt->ReplyName=NULL;
   rpt->ReplyAddr=NULL;
   sprintf(varname,"report.%s.replyto",ToolName);
	charpnt=ReadUMSConfigTags(account,UMSTAG_CfgName, varname,TAG_DONE);
	if(!charpnt)
      charpnt=ReadUMSConfigTags(account,UMSTAG_CfgName,"report.replyto",TAG_DONE);
	if(charpnt) {
      rda_result[0] = 0L;
      rda_result[1] = 0L;

      strcpy(buffer,charpnt);
      FreeUMSConfig(account,charpnt);

      if (rdargs = (struct RDArgs *)AllocDosObject(DOS_RDARGS, NULL)) {
          strcat(buffer,"\n");
          rdargs->RDA_Source.CS_Buffer = buffer;
          rdargs->RDA_Source.CS_Length = (LONG)strlen(rdargs->RDA_Source.CS_Buffer);
          rdargs->RDA_Flags  = RDAF_NOPROMPT;

          // parse config line
          if (ReadArgs(TEMPLATE, rda_result, rdargs)) {
              if(rda_result[OPT_RDANAME]) {
                 rpt->ReplyName = malloc(strlen((UBYTE *) rda_result[OPT_RDANAME])+1);
                 if (!rpt->ReplyName) {
                    FreeArgs(rdargs);
                    FreeDosObject(DOS_RDARGS, rdargs);
                    UMSSupportFreeReport(rpt);
                    err=ERR_REPREPLY;
                    return(0);
                    }
                 else
                    strcpy(rpt->ReplyName,(UBYTE *) rda_result[OPT_RDANAME]);
              }
              else
                 rpt->ReplyName=NULL;
              if(rda_result[OPT_RDAADDR]) {
                 rpt->ReplyAddr = malloc(strlen((UBYTE *) rda_result[OPT_RDAADDR])+1);
                 if (!rpt->ReplyAddr) {
                    FreeArgs(rdargs);
                    FreeDosObject(DOS_RDARGS, rdargs);
                    UMSSupportFreeReport(rpt);
                    err=ERR_REPREPLY;
                    return(0);
                    }
                 else
                    strcpy(rpt->ReplyAddr,(UBYTE *) rda_result[OPT_RDAADDR]);
              }
              else
                 rpt->ReplyAddr=NULL;
          FreeArgs(rdargs);
          }
          else {
            Fault(IoErr(), NULL, buffer, 250);
            strcpy(umserr,buffer);
            FreeDosObject(DOS_RDARGS, rdargs);
            UMSSupportFreeReport(rpt);
            err=ERR_CONFIGERR;
            return(0);
            }
       FreeDosObject(DOS_RDARGS, rdargs);
       }
   }

   /*
   ReplyTo:  <Wert aus "Report.Reply">. Wenn dieser nicht gesetzt ist, auf
             <Wert aus "Report.User">. Wenn dieser auch nicht gesetzt ist,
             auf "Sysop".
   */
   if(!rpt->ReplyName) {
      if(rpt->ReportName) {
         rpt->ReplyName = malloc(strlen(rpt->ReportName)+1);
         if (!rpt->ReplyName) {
            UMSSupportFreeReport(rpt);
            err=ERR_NOMEM;
            return(0);
            }
         strcpy(rpt->ReplyName, rpt->ReportName);
         if(rpt->ReportAddr) {
            rpt->ReplyAddr = malloc(strlen(rpt->ReportAddr)+1);
            if (!rpt->ReplyAddr) {
               UMSSupportFreeReport(rpt);
               err=ERR_NOMEM;
               return(0);
               }
            strcpy(rpt->ReplyAddr, rpt->ReportAddr);
            }
         else {
            rpt->ReplyAddr=NULL;
            }
         }
      else {
         rpt->ReplyName = malloc(strlen("Sysop")+1);
         if (!rpt->ReplyName) {
            UMSSupportFreeReport(rpt);
            err=ERR_NOMEM;
            return(0);
            }
         strcpy(rpt->ReplyName, "Sysop");
         }
      }


   // report.folder--------------------------------------------------------------------------------

   sprintf(varname,"report.%s.folder",ToolName);
	charpnt=ReadUMSConfigTags(account,UMSTAG_CfgName, varname,TAG_DONE);
	if(!charpnt)
   	charpnt=ReadUMSConfigTags(account,UMSTAG_CfgName,"report.folder",TAG_DONE);
	if(charpnt) {
      rpt->ReportFolder = malloc(strlen(charpnt)+1);
      if (!rpt->ReportFolder) {
         FreeUMSConfig(account,charpnt);
         UMSSupportFreeReport(rpt);
         err=ERR_REPFOLDER;
         return(0);
         }
      else
         strcpy(rpt->ReportFolder, charpnt);
		FreeUMSConfig(account,charpnt);
		}
	else
      rpt->ReportFolder = NULL;


   // report.group--------------------------------------------------------------------------------

   sprintf(varname,"report.%s.group",ToolName);
	charpnt=ReadUMSConfigTags(account,UMSTAG_CfgName, varname,TAG_DONE);
	if(!charpnt)
   	charpnt=ReadUMSConfigTags(account,UMSTAG_CfgName,"report.group",TAG_DONE);
	if(charpnt) {
      rpt->ReportGroup = malloc(strlen(charpnt)+1);
      if (!rpt->ReportGroup) {
         FreeUMSConfig(account,charpnt);
         UMSSupportFreeReport(rpt);
         err=ERR_REPGROUP;
         return(0);
         }
      else
         strcpy(rpt->ReportGroup, charpnt);
		FreeUMSConfig(account,charpnt);
		}
	else
      rpt->ReportGroup= NULL;


   // report.<toolname>--------------------------------------------------------------------------------

   sprintf(buffer,"report.%s",ToolName);
	charpnt=ReadUMSConfigTags(account,UMSTAG_CfgName,buffer,TAG_DONE);
	if(charpnt) {
		//if(!stricmp(charpnt,"NO") || !stricmp(charpnt,"FALSE"))
		if(*charpnt=='N' || *charpnt=='n')
         rpt->WriteReport=0;
		else
		   rpt->WriteReport=1;
		FreeUMSConfig(account,charpnt);
		}
	else
	   rpt->WriteReport=1;


   // Defaultname --------------------------------------------------------------------------------
   /*
      Wenn weder Gruppe noch Name Defaultname setzen.
   */
	if(!rpt->ReportGroup && !rpt->ReportName) {
      rpt->ReportName = malloc(strlen("Sysop")+1);
      if (!rpt->ReportName) {
         UMSSupportFreeReport(rpt);
         err=ERR_NOMEM;
         return(0);
         }
      strcpy(rpt->ReportName, "Sysop");
	   }


   // set unread --------------------------------------------------------------------------------
   /*
      testen, ob rpt->ReportName ein Exporter ist. In dem Fall Report-
      nachrichten auf unread setzen.
   */
   rpt->SetUnread=0;
   if(rpt->ReportName) {
		charpnt=ReadUMSConfigTags(account,UMSTAG_CfgName,"EXPORT",TAG_DONE);
		// User ist *kein* Exporter, darum unread setzen
		if(!charpnt)
         rpt->SetUnread=1;
		FreeUMSConfig(account,charpnt);
		}

#ifdef  MWDEBUG
   MWReport("End of reportinit", MWR_FULL);  /* Generate a memory usage report */
#endif

   return(rpt);
   }

/* ------------------------------------------------------------------------ */

void __saveds __asm
UMSSupportFreeReport(register __a0 struct UMSReport *rpt)
   {
   if(rpt) {
      if(rpt->ToolName)
         free(rpt->ToolName);
      if(rpt->Comment)
         free(rpt->Comment);
      if(rpt->ReplyName)
         free(rpt->ReplyName);
      if(rpt->ReplyAddr)
         free(rpt->ReplyAddr);
      if(rpt->ReportName)
         free(rpt->ReportName);
      if(rpt->ReportAddr)
         free(rpt->ReportAddr);
      if(rpt->ReportGroup)
         free(rpt->ReportGroup);
      if(rpt->ReportFolder)
         free(rpt->ReportFolder);
      free(rpt);
      }
   }


/* ------------------------------------------------------------------------ */

LONG __saveds __asm ArexxQueryDummy(void)
  {
  return (1);
  }
