/*
** ShortWho
** by Kelly Cochran
** Last Updated: Mon Sep 07 22:59:10 1998
*/

const char *version = "\0$VER: ShortWho v2.3 "__AMIGADATE__;

void     do_who_display(short i,BOOL conf);
BOOL     IsAbort( void );

struct MainPort        *myp;		/* Pointer to CNet port--ALL info!	*/
struct PortData        *z;
struct Library         *CNetBase  = NULL;
struct Library         *CNet4Base = NULL;
struct Library         *CNetCBase = NULL;
struct CNetCContext    *context   = NULL;
struct RangeContext    rc;
char **bm;

void do_who(void)       /* return nothing, and don't take an arg */
{

/* Definitions */

   BOOL conf = FALSE;         /* Do we have a +?      */
   char *oldwhere;            /* Pointer to oldWhere  */
   int i;                     /* need for the loop    */

/* End of definitions */

   oldwhere = z->MyDoing;     /* Set the old Where    */
   CNC_SetDoing("Short WHO");     /* Set the new Where    */

   CNC_PutText("\n");             /* Header Stuff         */
   CNC_PutText("q1Port User Name             Where\n");
   CNC_PutText("c4==== ===================== ===============q1\n");

   if (z->user1.MyPrivs.ABits & CONFCON_FLAG)
      conf = TRUE;      /* Do I have conference control? */

   if(CNetFindRange(z->pitem[1],0,myp->HiPort,&rc))
   {
      if(IsAbort())
         return;
      while((i = CNetNextRange(&rc)) >= 0)
         do_who_display(i,conf);
   }
   else
   {
      for(i = 0; i <= myp->HiPort;i++)
         do_who_display(i,conf);
   }

   switch(z->user1.HelpLevel)    /* Check user help level   */
   {
      case 0:
         CNC_PutText("\n   cbm cc= cdYou're Muffling this Port.\n");
         if (conf)
            CNC_PutText("   cbM cc= caThey're trying to Muffle You.\n");
         CNC_PutText("   cbh cc= cdYou're Hiding from this Port.\n");
         if (conf)
            CNC_PutText("   cbH cc= caThey're trying to Hide from You.\n");
         CNC_PutText("   cb+ cc= c9User Has Conference Control.\n");
         CNC_PutText("   cbS cc= c9User Has SuperUser Control.\n");
         break;

      case 1:
         CNC_PutText("\ncbm cf= cbMuffledcf, cbh cf= cbHiddencf, cb+ cf= cbConf. Control\n");
         break;

      default:
         break;
   }

   CNC_SetDoing(oldwhere);     /* Set old where back to normal  */
}

void do_who_display(short i, BOOL conf)
{
   int iuc;                   /* InterUserConf flags  */
   int iuc2;                  /* More IUC             */
   int idle;                  /* Time idle            */
   char spec = ' ';           /* +/H/h/M/m flag       */
   char buf  [ 64 ] = "";     /* Temp buffer (array of 64 chars) */
   char *handle;              /* Pointer to handle    */
   char *where;               /* Pointer to Where     */

   if (!myp->pc[i].online)          /* if port ~= loaded then iterate   */
      return;
   handle = myp->PortZ[i]->user1.Handle;
   where  = myp->PortZ[i]->MyDoing;
   idle   = myp->PortZ[i]->TimeIdle/10;   /* Pull user data */

   if (idle > 1)       /* Check to see how long they've been idle   */
   {
      if (idle > 59)    /* If more than one hour....  */
         sprintf(buf,"Idle c1%.1f c6Hours",(float)idle/60);
      else
         sprintf(buf,"Idle c1%.1f c6Mins",(float)(myp->PortZ[i]->TimeIdle)/10);
   }
   iuc  = z->IUCBits[i];                     /* My flags against other ports  */
   iuc2 = myp->PortZ[i]->IUCBits[z->InPort]; /* Their flags against my port   */
   if ((iuc & PORTRIGHT_MUFFLED) || (iuc2 & PORTRIGHT_MUFFLED))
      spec = *bm[923];    /* I'm muffling them, or they muffle me   */
   if ((iuc & PORTRIGHT_HIDDEN) && (i != z->InPort))
      spec = *bm[921];    /* I'm hiding from then, and it's not my port   */
   if ((iuc2 & PORTRIGHT_MUFFLED) && (conf && (i != z->InPort)))
      spec = *bm[925];    /* They're muffling me and I have a + and it's not my port */
   if (!myp->PortZ[i]->id)
   {
      if (myp->gc.SkipIdlePorts)    /* If we skip idle ports, iterate   */
         return;
      else                          /* else, just put bbstext line 903  */
         handle = myp->FirstTT->bm[902];
   }
   if (iuc2 & PORTRIGHT_HIDDEN)     /* They're/I'm hiding from me... */
   {
      spec = *bm[921];                   /* flag if I'm hiding from me    */
      if (i != z->InPort)           /* If it's not me..              */
      {
         spec = 'H';                /* flag if they're hiding from me*/
         if (!conf)                 /* If I don't have a +           */
         {
            if (myp->gc.SkipIdlePorts)       /* If hiding, iterate if no show idle  */
               return;                       /* else, fake an idle as below   */
            handle = myp->FirstTT->bm[902];  /* bbstext #903   */
            where  = myp->FirstTT->bm[906];  /* bbstext #907   */
            spec   = ' ';                    /* since I can't see them
                                                I can't see this either */
         }
      }
   }
   if ((myp->PortZ[i]->user1.MyPrivs.ABits & CONFCON_FLAG) && (i != z->InPort))
      spec = *bm[924]; /* if their user has conf and it's not my port..   */
   if (myp->PortZ[i]->user1.MyPrivs.ABits2 & SUPERUSER_FLAG)
      spec = *bm[947]; /* if their user has conf and it's not my port..   */
   sprintf(z->ABuffer,"%2d c6%cc7 %-21s c6%-24.24sq1\n",i,spec,handle,idle > 1 ? buf:where);
   /* formatted printf to temp buffer */                                /* comparison ? if true : if ~true */
   CNC_PutA();
   /* Print temp buffer */
}

/************************************************************************
 *                             Main routine                             *
 ************************************************************************/
void main( int argc, char **argv )
{
   if((argc < 2) || !(CNetCBase = OpenLibrary("cnetc.library", 4L)))
   {
      return;
   }

   if(!(CNetBase = OpenLibrary( "cnet.library", 4 )))
   {
      CloseLibrary(CNetCBase);
      return;
   }

   if(!(CNetBase = OpenLibrary( "cnet4.library", 4 )))
   {
      CloseLibrary(CNetBase);
      CloseLibrary(CNetCBase);
      return;
   }

   if(!(context = CNC_InitContext(argv[1])))
   {
      CloseLibrary(CNetCBase);
      CloseLibrary(CNet4Base);
      CloseLibrary(CNetBase);
      return;
   }

   z   = context->z;
   myp = context->myp;
   bm  = z->bm;

   do_who();

   CNC_ShutDown(NULL);
   CNC_DisposeContext();
   CloseLibrary(CNetCBase);
   CloseLibrary(CNet4Base);
   CloseLibrary(CNetBase);

   return;
}

BOOL IsAbort( void )    /* the actual function that checks for space or slash */
{
	CNC_CheckFlowControl();
	if (z->PrintFlags >=1)
	{
   	if (z->PrintFlags == 1)
         CNC_PutText(bm[1065]);
		if (z->PrintFlags > 1)
         CNC_PutText(bm[1064]);
		return TRUE;
	}
   return FALSE;
}
