#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
#include <fcntl.h>
#include <fctype.h>
#include <sys/stat.h>
#include <exec/types.h>
#include <libraries/dosextens.h>

#include <dlg/dlg.h>
#include <dlg/cron.h>
#include <dlg/resman.h>
#include <dlg/user.h>
#include <dlg/broadcast.h>

#include <devices/tpt.h>

#include <link/io.h>
#include <link/lang.h>

#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/diskfont.h>
#include <proto/graphics.h>

#include <clib/alib_protos.h>

#include <proto/dlg.h>

#include <pragmas/dlg.h>

#include <private/Version.h>
#define  ObjRev "1"
const UBYTE version[]="\0$VER: RemoveUser " BUILDVER "." ObjRev " ©" COPYRIGHT " by Digerati Dreams "__AMIGADATE__;


void   main      (int, char**);
void   removebbs (void);
BOOL   write_file(char *, char *);
BOOL   UserOnline(char *);
void  _CXBRK     (void);
BOOL   Break     (long);

extern struct DosLibrary *DOSBase;

BPTR               sout;
struct Library    *DLGBase=NULL;
char             **SA;

char             Ext[80];
struct Ram_File  RStruct;
struct USER_DATA UserDat;


void main(int argc, char *argv[])

{if (argc < 2)                                       exit(5);
 if (!(DLGBase = OpenLibrary(DLGNAME, DLGVERSION)))  exit(5);
 if (!(SA = getlang(NULL)))                          exit(5);

 strcpy(Ext, *++argv);
 if (!ReadUser(&RStruct, &UserDat, Ext))  exit(5);

 sout = Output();
 removebbs();
_CXBRK();
}


void removebbs()

{long  a;
 long  retval;
 char  cronstr[20];

 ASPrintf(NULL, cronstr, "%s_RemoveUser", Ext);
 SetProgramName(cronstr);

 ASPrintf(NULL, cronstr, "*REMOVEUSER %s*", Ext);
 CronEvent(DELEVENT, 0, cronstr);

 if (UserOnline(Ext))
    {retval=TUnSetFlags(T_PAUSED,Ext);

     if (retval<0L)
        {AFPrintf(NULL, sout, SA[1766]);
         return;
        }

     if (!(retval & T_FROZEN))  write_file("DLGCONFIG:Text/2MinWarn.txt",Ext);

     for(a = 0; a<24; a++)
        {chkabort();

         if (!UserOnline(Ext))
            {AFPrintf(NULL, sout, SA[1767]);
             return;
            }

         Delay(250L);
        }

     retval=TUnSetFlags(T_PAUSED, Ext);
     if (retval<0L)  return;

     if (retval & T_FROZEN)
        {if (!UserOnline(Ext))  return;
         chkabort();
         Break(RStruct.CLI);
        }

     chkabort();
     write_file("DLGCONFIG:Text/0MinWarn.txt", Ext);
     TSetFlags(T_DO_PEND,Ext);
     TKill(Ext);
    }

 return;
}


BOOL write_file(char *filename, char *portname)

{ULONG  filesize;
 char  *buffer;

 if (FileSize(filename, &filesize) == -1)  return(-1);
 if (!(buffer = malloc(filesize+1)))       return(-1);

 GetFirstStruct(filename, buffer, filesize);
 buffer[filesize] = 0;

 BroadCast(portname, buffer, BCIMPORTANTMSG);
 free(buffer);

 return(0);
}


BOOL UserOnline(char *port)

{long            retval;
 struct PortInfo istruct;

 istruct.port = port;

 retval = GetPortInfo(&istruct);
 if (retval == RMNOERR)
    {if (!strcmp(istruct.passwd,"BBS"))
        {FreePortInfo(&istruct);
         return(1);
        }

     FreePortInfo(&istruct);
    }

 return(0);
}

void _CXBRK()

{CloseLibrary(DLGBase);
 exit(0);
}


BOOL Break(long task)

{struct MsgPort **array;
 struct Task     *task_id;
 long             num_tasks;

 char             exestr[80];

 array     = (struct MsgPort **)BADDR(((struct RootNode *)DOSBase->dl_Root)->rn_TaskArray);
 num_tasks = (long)array[0];

 if (task <= num_tasks)
    {Forbid();

     if (array[task])
        {task_id = array[task]->mp_SigTask;
         Signal(task_id, SIGBREAKF_CTRL_C);
        }

     Permit();
    }

 ASPrintf(NULL, exestr, "Break %d", task);
 Execute(exestr, 0, 0);
 return(TRUE);
}
