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

#include <devices/tpt.h>

#include <dlg/dlg.h>
#include <dlg/user.h>
#include <dlg/msg.h>
#include <dlg/input.h>
#include <dlg/menu.h>
#include <dlg/resman.h>
#include <dlg/log.h>
#include <dlg/file.h>

#include <link/io.h>

#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/dlg.h>

#include <pragmas/dlg.h>

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


void  main(int , char **);
int   HandleBuiltIn(UBYTE);
void _CXBRK(void);

void  AAdd_User(void);
BYTE  Get_UserName(char *);
BOOL  Area_Check(long);
BOOL  Area_Append(long);
void  UList_Area(void);
LONG  ADelete_User(char *, long);
void  ACopy_Users(void);
BOOL  EditUserArea(long, char *);
void  AA_Flags(struct Msg_Log *);


#define INSTACK RStruct.Command_Stack[0]
#define STK     RStruct.Command_Stack
#define HOT     UserDat.Hot_Keys

struct USER_DATA  UserDat;
struct Ram_File   RStruct;
struct UserInfo   ui      = {&UserDat, &RStruct};
struct Query      q       = {NULL, NULL, NULL, NULL, NULL, 0, 0, 0};
struct Msg_Log    Log;
struct Msg_Area   Area;
char              Ext[4];

char              MenuName[13] = "FILEU_Main";
char              Overlay      =  FALSE;
char              exitflag     =  FALSE;

struct NewShortMenu Menu[8] = {{"Abort",1},
                               {"FILEU_Add",1},
                               {"FILEU_AreaCopy",1},
                               {"FILEU_Delete",1},
                               {"FILEU_Edit",1},
                               {"FILEU_Exit",1},
                               {"FILEU_List",1},
                               {"FILEU_ListArea",1}
                              };

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

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

{char *s;
 char *stack = NULL;

 sout = Output();
 if (!(DLGBase = OpenLibrary(DLGNAME, DLGVERSION)))  exit(5);

 while(--argc>0)
      {s = *++argv;
       if (*s++=='-')
          {while(*s)
                {switch(toupper(*s))
                       {case 'O':  Overlay = TRUE;
                                   break;

                        case 'S':  if (!--argc)  break;
                                   stack=*++argv;
                                   break;

                        case 'M':  if (!--argc)  break;
                                   strncpy(MenuName,*++argv,12);
                                   MenuName[12] = 0;
                                   break;
                       }
                 s++;
                }
          }
      }


 if (GetDevName(Ext) == -1)            _CXBRK();
 if (!ReadUser(&RStruct,&UserDat,Ext))  _CXBRK();
 if (stack)                             InsertStack(STK, stack);

 if (!(ls = GetLang(Ext)))             _CXBRK();
 SA = ls->strings;

 WriteLog(SYSOP_CONFIG, RStruct.Name, Ext, SA[537]);

 while(!exitflag)
      {Chk_Abort();

       if (MenuInput(MenuName,Ext,"FILEU",Menu,8,HandleBuiltIn,&UserDat,&RStruct,UserDat.Help_Level,NULL)==MENUNOTFOUND)
           _CXBRK();
      }

 _CXBRK();
}


int HandleBuiltIn(UBYTE cmd)

{SHORT  area;
 char   string[128];
 char   name  [40];
 struct USER_DATA TempUser;

 switch(cmd)
       {case 0:                                     /* Abort */
                exitflag = TRUE;
                break;

        case 1:                                     /* FILEU_Add */
                AAdd_User();
                break;

        case 2:                                     /* FILEU_AreaCopy */
                ACopy_Users();
                break;

        case 3:                                     /* FILEU_Delete */
                area = IntQuery(SA[538], 1, 9999, 0, &ui);
                AFPrintf(NULL, sout, "\n\n");
                if (!area)   break;

                for(;;)
                   {if (Get_UserName(name))
                       {AFPrintf(&UserDat, sout, SA[539]);
                        break;
                       }

                    if (ADelete_User(name, area))
                        AFPrintf(&UserDat, sout, SA[540]);
                      else
                        AFPrintf(&UserDat, sout, SA[541]);
                   }
                break;

        case 4:                                     /* FILEU_Edit */
                if (Get_UserName(name))
                   {AFPrintf(&UserDat, sout, SA[542]);
                    break;
                   }
                EditUserArea(IntQuery(SA[543], 1, 9999, 0, &ui), name);
                break;

        case 5:                                 /* FILEU_Exit */
               _CXBRK();
                break;

        case 6:                                 /* FILEU_ListArea */
                UList_Area();
                break;

        case 7:                                 /* FILEU_List */
                if (Get_UserName(name))
                   {AFPrintf(&UserDat, sout, SA[542]);
                    break;
                   }

                ASPrintf(NULL, string, "USER:%s/User.data", name);
                UnderScore(string);
                GetFirstStruct(string, (char *)&TempUser, sizeof(TempUser));
                ListAreas(name, &TempUser, 1, 0);
                AFPrintf(NULL, sout, "\n");
                break;
       }

 return(TRUE);
}


void _CXBRK(void)

{WriteRam(&RStruct, Ext);

 if (!Overlay) ChainProgram("DLG:Menu", Ext);
 CloseLibrary(DLGBase);

 exit(0);
}


void AAdd_User(void)

{SHORT area;

 area = IntQuery(SA[544], 1, 9999, 0, &ui);
 AFPrintf(NULL, sout, "\n\n");
 if (!area)
    {AFPrintf(&UserDat, sout, SA[542]);
     return;
    }

 if (!ReadArea(area, &Area, 1))
    {AFPrintf(&UserDat, sout, SA[545]);
     return;
    }

 for(;;)
    {char retval;
  
     if ((retval=Get_UserName(Log.Name))==-1)
        {AFPrintf(&UserDat, sout, SA[539]);
         return;
        }

     if (retval==1)  continue;
     if (!Area_Check(area))
        {AFPrintf(&UserDat, sout, SA[546]);
         continue; 
        }

     Log.High_Mess = 0;
     Log.uflag     = 0;
     Log.dflag     = 0;
     Log.special   = TRUE;
     if (Area_Append(area))
         AFPrintf(&UserDat, sout, SA[547]);
       else
         AFPrintf(&UserDat, sout, SA[548]);
    }
}


BYTE Get_UserName(char *name)

{long zflag;

 q.prompt     = SA[549];
 q.string     = name;
 q.valid      = NULL;
 q.length     = 36;
 q.typelength = 255;
 q.flags      = QUERY_CAPITAL;
 zflag        = DLGQuery(&q, &ui);
 AFPrintf(NULL, sout, "\n\n");
 if (!zflag)  return(-1);

 Upper(name);
 if (CheckUser(name) != 1)
    {AFPrintf(&UserDat, sout, SA[550], name);
     return(1);
    }

 return(0);
}


BOOL Area_Check(long area)

{char filename[80];

 ASPrintf(NULL, filename,"FILE:%d/User.File",area);
 if (GetStruct(filename,(char *)&Log,sizeof(Log),36))
     return(1);

 return(0);
}


BOOL Area_Append(long area)

{char filename[80];

 ASPrintf(NULL, filename,"FILE:%d/User.File",area);
 if (AddStruct(filename,(char *)&Log,sizeof(Log),36)==-1)
     return(FALSE);

 return(TRUE);
}


void UList_Area(void)

{SHORT area;
 int   fp;
 char  filename[80];

 area = IntQuery(SA[557], 1, 9999, 0, &ui);
 AFPrintf(NULL, sout, "\n\n");
 if (!area)
    {AFPrintf(&UserDat, sout, SA[542]);
     return;
    }

 if (!ReadArea(area, &Area, 1))
    {AFPrintf(&UserDat, sout, SA[545]);
     return;
    }

 ASPrintf(NULL, filename,"FILE:%d/User.File",area);
 if ((fp = open(filename,O_RDONLY)) == EOF)
    {AFPrintf(&UserDat, sout, SA[558]);
     return;
    }

 AFPrintf(&UserDat, sout, SA[559]);
 AFPrintf(&UserDat, sout, SA[560]);

 while(read(fp,&Log,sizeof(Log)) == sizeof(Log))
      {AFPrintf(&UserDat, sout, SA[561],Log.Name,Log.High_Mess);
       AFPrintf(&UserDat, sout, SA[562], (Log.dflag&Enter_Priv)?'U':'-',
                                        (Log.dflag&Download_Priv)?'D':'-',    
                                        (Log.dflag&Kill_Priv)?'K':'-',
                                        (Log.dflag&Hurl_Priv)?'T':'-',
                                        (Log.dflag&Sysop_Access)?'S':'-');

       AFPrintf(&UserDat, sout, SA[563], (Log.uflag&Enter_Priv)?'U':'-',
                                        (Log.uflag&Download_Priv)?'D':'-',    
                                        (Log.uflag&Kill_Priv)?'K':'-',
                                        (Log.uflag&Hurl_Priv)?'T':'-',
                                        (Log.uflag&Sysop_Access)?'S':'-');
      }

 AFPrintf(&UserDat, sout, SA[564]);
 close(fp);
 Pause();
}


LONG ADelete_User(char *name, long area)

{char filename[80];

 ASPrintf(NULL, filename,"FILE:%d/User.File",area);

 strcpy(Log.Name,name);
 Upper(Log.Name);

 return(DeleteStruct(filename,(char *)&Log,sizeof(Log),36));
}


void ACopy_Users(void)

{SHORT area1;
 SHORT area2;
 int   fp;
 char filename[80];

 if (!(area1 = IntQuery(SA[565], 1, 9999, 0, &ui)))
    {AFPrintf(&UserDat, sout, SA[566]);
     return;
    }

 AFPrintf(NULL, sout, "\n\n");
 if (!(area2 = IntQuery(SA[567], 1, 9999, 0, &ui)))
    {AFPrintf(&UserDat, sout, SA[566]);
     return;
    }

 AFPrintf(NULL, sout, "\n\n");

 ASPrintf(NULL, filename,"File:%d/User.File",area1);
 if ((fp = open(filename,O_RDONLY)) == EOF)
    {AFPrintf(&UserDat, sout, SA[568]);
     return;
    }

 while(read(fp,&Log,sizeof(Log)) == sizeof(Log))
      {AFPrintf(&UserDat, sout, SA[569],Log.Name);
       Log.High_Mess = 0;
       Log.special   = 1;

       Area_Append(area2);
       AFPrintf(&UserDat, sout, SA[570]);
      }

 AFPrintf(NULL, sout, "\n");
 close(fp);
}


BOOL EditUserArea(long area, char *name)

{char filename[80];

 AFPrintf(NULL, sout, "\n\n");
 if (!ReadArea(area, &Area, 1))  return(TRUE);

 ASPrintf(NULL, filename, "FILE:%d/User.file", area);

 strcpy(Log.Name, name);
 Upper(Log.Name);

 if (GetStruct(filename,(char *)&Log,sizeof(Log),36))
    {AFPrintf(&UserDat, sout, SA[571]);
     return(FALSE);
    }

 AA_Flags(&Log);
 if (AddStruct(filename,(char *)&Log,sizeof(Log),36)==-1)
    {AFPrintf(&UserDat, sout, SA[572]);
     return(FALSE);
    }

 return(TRUE);
}


void AA_Flags(struct Msg_Log *log)

{char inp[2];

 AFPrintf(&UserDat, sout, SA[551]);

 q.prompt     = SA[552];
 q.string     = inp;
 q.length     = 1;
 q.typelength = 1;
 q.flags      = QUERY_UPCASE;
 DLGQuery(&q, &ui);
 if (inp[0]=='-')  {log->dflag |=  Enter_Priv; log->uflag &= ~Enter_Priv;}
 if (inp[0]=='+')  {log->uflag |=  Enter_Priv; log->dflag &= ~Enter_Priv;}
 if (inp[0]== 0)   {log->dflag &= ~Enter_Priv; log->uflag &= ~Enter_Priv;}

 q.prompt     = SA[553];
 q.string     = inp;
 q.length     = 1;
 q.typelength = 1;
 q.flags      = QUERY_UPCASE;
 DLGQuery(&q, &ui);
 if (inp[0]=='-')  {log->dflag |=  Download_Priv; log->uflag &= ~Download_Priv;}
 if (inp[0]=='+')  {log->uflag |=  Download_Priv; log->dflag &= ~Download_Priv;}
 if (inp[0]== 0)   {log->dflag &= ~Download_Priv; log->uflag &= ~Download_Priv;}

 q.prompt     = SA[554];
 q.string     = inp;
 q.length     = 1;
 q.typelength = 1;
 q.flags      = QUERY_UPCASE;
 DLGQuery(&q, &ui);
 if(inp[0]=='-')  {log->dflag |= Kill_Priv; log->uflag &= ~Kill_Priv;}
 if(inp[0]=='+')  {log->uflag |= Kill_Priv; log->dflag &= ~Kill_Priv;}
 if(inp[0]== 0)   {log->dflag &= ~Kill_Priv; log->uflag &= ~Kill_Priv;}

 q.prompt     = SA[555];
 q.string     = inp;
 q.length     = 1;
 q.typelength = 1;
 q.flags      = QUERY_UPCASE;
 DLGQuery(&q, &ui);
 if(inp[0]=='-')  {log->dflag |=  Hurl_Priv; log->uflag &= ~Hurl_Priv;}
 if(inp[0]=='+')  {log->uflag |=  Hurl_Priv; log->dflag &= ~Hurl_Priv;}
 if(inp[0]== 0)   {log->dflag &= ~Hurl_Priv; log->uflag &= ~Hurl_Priv;}

 q.prompt     = SA[556];
 q.string     = inp;
 q.length     = 1;
 q.typelength = 1;
 q.flags      = QUERY_UPCASE;
 DLGQuery(&q, &ui);
 if(inp[0]=='-')  {log->dflag |=  Sysop_Access; log->uflag &= ~Sysop_Access;}
 if(inp[0]=='+')  {log->uflag |=  Sysop_Access; log->dflag &= ~Sysop_Access;}
 if(inp[0]== 0)   {log->dflag &= ~Sysop_Access; log->uflag &= ~Sysop_Access;}

 AFPrintf(NULL, sout, "\n\n");
}
