/*
**	$VER: rlserv.c 1.1 (08.02.94)
**
**	rlogin.service functions
**
**	© Copyright 1994 by Norbert Püschel
**	All Rights Reserved
*/

#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/utility.h>
#include <clib/accounts_protos.h>
#include <pragmas/accounts_pragmas.h>
#include <clib/svc_protos.h>
#include <pragmas/svc_pragmas.h>

#include <envoy/errors.h>
#include <envoy/services.h>
#include <dos/var.h>
#include <dos/dostags.h>

#include <string.h>

#include <debug.h>

void __saveds __asm LIBGetServiceAttrsA(register __a0 struct TagItem *tags)

{
  STRPTR name;

  name = (STRPTR)GetTagData(SVCAttrs_Name,0,tags);
  if(name) strcpy(name,"Remote Login");
}
  
void __saveds __asm LIBSetServiceAttrsA(register __a0 struct TagItem *tags)

{}

void __saveds __asm LIBAttemptShutdown(register __a0 STRPTR *why,
                                       register __d0 ULONG when)

{}

extern void handler_func(void);

LONG getstr(BPTR fh,STRPTR buff,LONG len)

{
  LONG c;

  while(--len > 0) {
    c = FGetC(fh);
    if(c == ',' || c == ' ' || c == '\t' || c == '\n' || c == -1) break;
    *(buff++) = c;
  }
  *buff = '\0';
  if(c == ' ' || c == '\t') c = '\n';
  return(c);
}

ULONG checkuser(STRPTR uname,STRPTR pwd)

{
  struct Library *AccountsBase;
  struct UserInfo *user;
  struct GroupInfo *group;
  ULONG retval = ENVOYERR_NORESOURCES;
  BPTR prefs;
  LONG c;

  AccountsBase = OpenLibrary("accounts.library",37);
  if(AccountsBase) {
    user = AllocUserInfo();
    if(user) {
      retval = VerifyUser(uname,pwd,user);
      debug2("rlogin.service: VerifyUser: %ld\n",retval);
      if(retval == 0) {
        prefs = Open("ENV:Envoy/rlogin.prefs",MODE_OLDFILE);
        if(prefs) {
          do {
            c = getstr(prefs,user->ui_UserName,32);
            if(user->ui_UserID) {
              retval = strcmp(uname,user->ui_UserName);
            }
            else {
              retval = Stricmp("nobody",user->ui_UserName);
            }
            if(retval == 0) break;
          } while(c != '\n' && c != -1);
          if(retval && c != -1) {
            group = AllocGroupInfo();
            if(group) {
              strcpy(user->ui_UserName,uname); /* restore userinfo */
              do {
                c = getstr(prefs,group->gi_GroupName,32);
                group->gi_GroupID = 0;
                retval = MemberOf(group,user);
                if(retval == 0) break;
              } while(c != '\n' && c != -1);
              FreeGroupInfo(group);
              if(retval) retval = ENVOYERR_UNKNOWNMEMBER;
            }
            else retval = ENVOYERR_NORESOURCES;
          }
          Close(prefs);
        }
        else retval = ENVOYERR_NORESOURCES;
      }
      FreeUserInfo(user);
    }
    CloseLibrary(AccountsBase);
  }
  return(retval);
}

/* handler startup packet:

   Arg1 = user name
   Arg2 = password
   Arg3 = host name
   Arg4 = entity name buffer

*/

ULONG __saveds __asm LIBStartServiceA(register __a0 struct TagItem *tags)

{
  ULONG retval;
  struct Process *handler;
  STRPTR uname,pwd,ename,hname;

  debug("StartService\n");

  uname = (STRPTR)GetTagData(SSVC_UserName,0,tags);
  pwd   = (STRPTR)GetTagData(SSVC_Password,0,tags);
  hname = (STRPTR)GetTagData(SSVC_HostName,0,tags);
  ename = (STRPTR)GetTagData(SSVC_EntityName,0,tags);

  if(uname == 0 || pwd == 0 || hname == 0 || ename == 0) {
    return(ENVOYERR_NULLPTR);
  }

  if(retval = checkuser(uname,pwd)) return(retval);

  debug("Checkuser OK\n");

  handler = CreateNewProcTags(NP_Entry,handler_func,
                              NP_Name,"Remote Shell Handler",
                              NP_Priority,0,
                              NP_WindowPtr,-1,
                              NP_Cli,TRUE,
                              TAG_DONE);

  if(handler) {
    debug("Handler created\n");
    if(!DoPkt4(&(handler->pr_MsgPort),0,(LONG)uname,(LONG)pwd,
       (LONG)hname,(LONG)ename)) {
      retval = IoErr();
      debug2("Handler failed: %ld\n",retval);
    }
  }
  else retval = ENVOYERR_NORESOURCES;
 
  return(retval);
}
