/*  LASTON.C
 *---------------------------------------------------------------------------
 *
 *  RBBS Callers File Lister
 *
 *  10-22-90
 *
 */
#include <stdio.h>
#include <io.h>
#include <alloc.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

typedef unsigned int uint;
typedef unsigned char uchar;

#define TRUE    1
#define FALSE   0

#define BLUE    "[0;1;34m"
#define RED     "[0;1;31m"
#define WHITE   "[0;1;37m"
#define YELLOW  "[0;1;33m"
#define CYAN    "[0;1;36m"

struct LStruct
   {
   char       users_name[32];
   char       city_state[25];
   char       date_time[20];
   };

char *mix_case(char * );
char *trim(char * );

void main(int argc ,char *argv[] )
{
   FILE   *fpcall;
   int    i, len;
   char   one_rec[129];
   uint   recs_in_file;
   uint   max_callers = 5;
   uint   num_callers = 0;
   uint   num_excluded = 0;
   int    name_len = -1;
   int    city_len = -1;
   int    date_len = -1;
   int    same_caller;
   int    display_dupes = FALSE;
   struct LStruct *last_on;
   char   excluded[20][32];
   char   last_caller[32];
   char   *color1_default = RED;
   char   *color2_default = YELLOW;
   char   *color3_default = WHITE;
   char   *color4_default = CYAN;
   char   *color5_default = BLUE;

   if (argc < 2 )
      {
      printf("Usage: LASTON <Callers> [/NCx] [/Xn] [/DD] [/FCx] [/TCx] [/UCx] [/CCx] [/DCx]\n" );
      printf("       /NCx - Display x callers (defaults to 5)\n" );
      printf("       /Xn  - Exclude callers with the name n\n" );
      printf("                Use a '_' in place of a ' ' in name, i.e. /XTom_Collins\n" );
      printf("       /DD  - Display duplicate callers (default is to not display 'em)\n" );
      printf("       /FC  - Set frame color string to x\n" );
      printf("                LASTON puts this between a ESC '[' and an 'm'\n" );
      printf("                i.e. /FC1;37 results in the ANSI string ESC [1;37m\n" );
      printf("       /TC  - Set title color string to x\n" );
      printf("       /UC  - Set user's name color string to x\n" );
      printf("       /CC  - Set user's City/State color string to x\n" );
      printf("       /DC  - Set user's date on color string to x\n" );
      printf("\n" );
      printf("Ex: LASTON c:\\rbbs\\callers /NC10 /XTom_Collins /dd /CC1;34\n" );
      return;
      }

   printf("LASTON v1.10 - Super Dooper RBBS Last Callers List Maker, by Tom Collins\n\n" );

   fpcall = fopen(strupr(argv[1] ) ,"rb" );
   if (fpcall == NULL )
      {
      printf("Can't Find Callers File %s... Aborted.\n" ,argv[1] );
      return;
      }

   for (i = 2; i < argc; i++ )
      {
      if (strncmp(strupr(argv[i] ) ,"/NC" ,3 ) == 0 )
         {
         max_callers = atoi(&argv[i][3] );
         if (max_callers < 1 || max_callers > 25 )
            {
            max_callers = 5;
            }
         }
      else if (strncmp(argv[i] ,"/DD" ,3 ) == 0 )
         {
         display_dupes = TRUE;
         }
      else if (strncmp(argv[i] ,"/X" ,2 ) == 0 && num_excluded < 20 )
         {
         int j;

         for (j = 2; argv[i][j] != '\0'; j++ )
            {
            if (argv[i][j] == '_' )
               {
               argv[i][j] = ' ';
               }
            }
         strcpy(excluded[num_excluded] ,mix_case(&argv[i][2] ) );
         num_excluded++;
         }
      else if (argv[i][0] == '/' && argv[i][2] == 'C' &&
               strchr("FTUCD" ,argv[i][1] ) != NULL )
         {
         char c;
         int j;

         j = strlen(argv[i] );
         c = argv[i][1];

         strcpy(&argv[i][2] ,&argv[i][3] );

         argv[i][0]   = '\x1B';
         argv[i][1]   = '[';
         argv[i][j-1] = 'm';
         argv[i][j]   = '\0';

         switch (c )
            {
            case 'F': color1_default = argv[i]; break;
            case 'T': color2_default = argv[i]; break;
            case 'U': color3_default = argv[i]; break;
            case 'C': color4_default = argv[i]; break;
            case 'D': color5_default = argv[i]; break;
            }
         }
      }

   last_on = (struct LStruct *) calloc(sizeof(struct LStruct ) ,max_callers );

   last_caller[0] = '\0';

   recs_in_file = (uint) (filelength(fileno(fpcall ) ) / 64L);

   printf("Reading %s... " ,argv[1] );

   for (i = recs_in_file-1; i >= 0 && num_callers < max_callers; i-- )
      {
      same_caller = FALSE;

      /*
       * Read a callers record
       */
      fseek(fpcall ,((long)i)*64L ,SEEK_SET );
      if (fread(one_rec ,64 ,1 ,fpcall ) != 1 )
         {
         break;
         }
      if (one_rec[0] != ' ' )
         {
         char *p1, *p2, *p3;

         one_rec[64] = '\0';
         strlwr(one_rec );

         /*
          * If the current record is a header, read the
          * previous record, too.
          */
         if (((p1 = strstr(one_rec ,"on at" ) ) == NULL ) || (--i < 0 ) )
            {
            continue;
            }
         *p1 = '\0';

         strcpy(last_on[num_callers].users_name ,mix_case(trim(one_rec ) ) );
         if (strcmp(last_on[num_callers].users_name ,last_caller ) == 0 )
            {
            same_caller = TRUE;
            }
         strcpy(last_caller ,last_on[num_callers].users_name );

         fseek(fpcall ,((long)i)*64L ,SEEK_SET );
         if (fread(&one_rec[64] ,64 ,1 ,fpcall ) != 1 )
            {
            break;
            }
         one_rec[128] = '\0';
         strlwr(p1+1 );

         if (same_caller && !display_dupes )
            {
            continue;
            }
         else if (num_excluded != 0 )
            {
            int i, found = FALSE;

            for (i = 0; i < num_excluded; i++ )
               {
               if (strcmp(last_on[num_callers].users_name ,excluded[i] ) == 0 )
                  {
                  found = TRUE;
                  break;
                  }
               }
            if (found )
               continue;
            }

         if ((p2 = strstr(p1+5 ,"from" ) ) == NULL )
            {
            continue;
            }

         *p2 = '\0';
         strcpy(last_on[num_callers].date_time ,strupr(trim(p1+5 ) ) );

         if ((p3 = strstr(p2+4 ,"baud" ) ) == NULL )
            {
            continue;
            }

         /*
          * Find the last comma before the baud rate
          */
         while (p3 > p2+4 )
            {
            if (*p3 == ',' )
               break;
            p3--;
            }

         if (p3 == p2+4 )
            {
            continue;
            }

         *p3 = '\0';
         strcpy(last_on[num_callers].city_state ,mix_case(trim(p2+4 ) ) );

         num_callers++;
         }
      }

   fclose(fpcall );

   for (i = 0; i < num_callers; i++)
      {
      len = strlen(last_on[i].users_name );
      if (len > name_len )
         {
         name_len = len;
         }
      len = strlen(last_on[i].city_state );
      if (len > city_len )
         {
         city_len = len;
         }
      len = strlen(last_on[i].date_time );
      if (len > date_len )
         {
         date_len = len;
         }
      }

   if (num_callers == 0 )
      {
      printf("No Previous Callers... Done.\n" );
      return;
      }

   printf("Writing Output Files... " );

   for (i = 0; i < 3; i++)
      {
      int    j, k;
      FILE   *fpout;
      char   single_line[81];
      char   double_line[81];
      char   fmt[80];
      char   temp1[10];
      char   temp2[10];
      char   temp3[10];
      char   *color1 = "";
      char   *color2 = "";
      char   *color3 = "";
      char   *color4 = "";
      char   *color5 = "";
      char   *filename = "LASTONG";
      char   single_line_char = '\xC4';
      char   double_line_char = '\xCD';

      switch (i )
         {
         case 0:
            single_line_char = '-';
            double_line_char = '=';
            filename = "LASTON";
            break;
         case 1:
            break;
         case 2:
            color1 = color1_default;
            color2 = color2_default;
            color3 = color3_default;
            color4 = color4_default;
            color5 = color5_default;
            filename = "LASTONC";
            break;
         }

      fpout = fopen(filename ,"wt" );

      memset(single_line ,single_line_char ,79 );
      memset(double_line ,double_line_char ,79 );

      len = (71 - name_len - city_len - date_len ) / 2;

      for (j = 0; j < len; j++)
         {
         fmt[j] = single_line[j] = double_line[j] = ' ';
         }

      k = name_len + city_len + date_len + len + 8;

      single_line[k] = double_line[k] = '\0';

      sprintf(&fmt[j] ,"%s%%-%ss    %s%%-%ss    %s%%%ss\n" ,
              color3 ,itoa(name_len ,temp1 ,10 ) ,
              color4 ,itoa(city_len ,temp2 ,10 ) ,
              color5 ,itoa(date_len ,temp3 ,10 ) );

      fprintf(fpout ,"\n%s%s\n" ,color1 ,double_line );
      fprintf(fpout ,"                          %sThe Last %i Callers Were...\n" ,color2, num_callers );
      fprintf(fpout ,"%s%s\n" ,color1 ,single_line );

      for (j = 0; j < num_callers; j++)
         {
         fprintf(fpout ,fmt ,last_on[j].users_name ,
                             last_on[j].city_state ,
                             last_on[j].date_time );
         }

      fprintf(fpout ,"%s%s\n%s{PB\n" ,color1 ,single_line ,i==2? "[0m" : "" );

      fclose(fpout );
      }

   printf("Done.\n" );
}

/*
 *----------------------------------------------------------------------------
 *
 */
char *mix_case(char *s )
{
   int i, upper = TRUE;

   for (i = 0; s[i] != '\0'; i++ )
      {
      if (upper )
         {
         s[i] = toupper(s[i] );
         upper = FALSE;
         }
      else
         {
         s[i] = tolower(s[i] );
         }
      if (strchr(" ,.-;:" ,s[i] ) != NULL )
         {
         upper = TRUE;
         }
      }
   return(s );
}

/*
 *---------------------------------------------------------------------------
 *
 */
char *trim(char *s )
{
   int i = 0;

   while (s[i] == ' ' )
      i++;

   if (i != 0 )
      {
      strcpy(s ,&s[i] );
      }
   i = strlen(s );
   if (i != 0 )
      {
      i--;
      while (s[i] == ' ' && i >= 0 )
         {
         s[i] = '\0';
         }
      }
   return(s );
}

