home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / EVENTS / ICEST12.ZIP / ICESTAT.C < prev    next >
C/C++ Source or Header  |  1996-07-03  |  13KB  |  501 lines

  1. /*
  2.    ICESTAT.C - iceStat v1.2
  3.    Copyright (C) 1996 by Albert Vernon and Joshua Hines.
  4.    You may use any of this code that you wish, as long as you
  5.    give credit to us.  If you use the spin function,
  6.    you must give credit to Jon Rickher.  If you use any of the
  7.    multitasker aware functions, you must give credit to Wayne Bell.
  8.  
  9.    Most of this code is ANSI C compatible.
  10.    It will compile successfully under Borland's Turbo C++ v3.00
  11.    for DOS.  You may have to make minor modifications for other
  12.    compilers.
  13.  
  14.    last modification:  03 July 1996
  15. */
  16.  
  17. #pragma warn -aus
  18.  
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <sys\stat.h>
  23. #include <sys\types.h>
  24. #include <time.h>
  25. #include <dos.h>
  26.  
  27. /* vardec.h is a header file from the WWIV software by Wayne Bell.
  28.    You need to include a copy of vardec.h from WWIV version 4.22
  29.    or greater.  Versions v4.23+ may require additional header files.
  30.    Read the compiler's error message to find out which one(s).
  31. */
  32. #include "vardec.h"
  33.  
  34.  
  35. userrec thisuser;  /* userrec data structure defined in vardec.h */
  36. char    ansi,            /* ansi enabled? */
  37.         data[81],        /* data dir with trailing backslash */
  38.         systemname[51];
  39. int     usernum,
  40.         multitasker;
  41. void    show_help (void),
  42.         goxy (int x, int y),
  43.         left (int amount),
  44.         display_data (void),
  45.         spin (unsigned char *s),
  46.         detect_multitask (void),
  47.         giveup_timeslice (void),
  48.         win_pause (void),
  49.         dv_pause (void);
  50. int     test_ansi (char *filename),
  51.         display (char *filename),
  52.         read_chaintxt (char *filename),
  53.         read_userlst (void),
  54.         get_dos_version (void),
  55.         get_win_version (void),
  56.         get_dv_version (void);
  57.  
  58. FILE    *chaintxt,
  59.         *userlst;
  60.  
  61. /*=========================================================================*/
  62.  
  63. void main (int argc, char *argv[])
  64. {
  65.  
  66.     if (argc < 2)
  67.     {
  68.         show_help();
  69.         exit (1);
  70.     }
  71.  
  72.     if (!test_ansi(argv[1])) /* if they don't have ANSI, simply exit */
  73.         exit (1);
  74.  
  75.     detect_multitask();
  76.  
  77.     printf ("\n\x1b[0;31m▄▒ \x1b[0;1;31miceStat\x1b[0;1;33m:\x1b[0;31m░ \x1b[0;1mWould you like to view your statistics? \x1b[0;31m░\x1b[0;1;33m (\x1b[0;1my\x1b[0;1;33m/\x1b[0;1mN): ");
  78.     if ( !noyes() )
  79.     {
  80.         puts ("\n");
  81.         exit (0);
  82.     }
  83.     if (!read_chaintxt(argv[1]))
  84.     {
  85.         printf ("\n## Error:  unable to read data from %s. \n", argv[1]);
  86.         exit (2);
  87.     }
  88.  
  89.     if (!read_userlst())
  90.     {
  91.         printf ("\n## Error:  unable to read data from %sUSER.LST. \n", data);
  92.         exit (2);
  93.     }
  94.  
  95.     printf ("\x1b[2J"); /* clear screen */
  96.     if (!display ("ICESTAT.ANS"))
  97.     {
  98.         printf ("\n## Error:  unable to display ICESTAT.ANS. \n");
  99.         exit (2);
  100.     }
  101.  
  102.     display_data ();
  103.     printf ("\x1b[2J"); /* clear screen */
  104. }
  105.  
  106. /*===========================================================================
  107.  goxy moves the cursor to a specific point on the screen using
  108.    ANSI escape sequences.
  109. ===========================================================================*/
  110.  
  111. void goxy(int x, int y)
  112. {
  113.     printf ("\x1b[%d;%dH", y, x);
  114. }
  115.  
  116. /*===========================================================================
  117.  left uses ANSI escape sequences to cause the cursor to move left a
  118.    specified amount.
  119. ===========================================================================*/
  120.  
  121. void left(int amount)
  122. {
  123.     printf ("\x1b[%dD", amount);
  124. }
  125.  
  126. /*===========================================================================
  127.  test_ansi examines CHAIN.TXT to determine if the user has ANSI graphics
  128.    support turned on.
  129. ===========================================================================*/
  130.  
  131. int test_ansi (char *filename)
  132. {
  133.     char    buffer[81],
  134.             ansi_status;
  135.     register int i;
  136.  
  137.     if ((chaintxt = fopen(filename, "rt")) == NULL)
  138.       {
  139.         printf ("\n## Error:  unable to read data from %s. \n", filename);
  140.         exit (2);
  141.       }
  142.  
  143.     for (i = 1; i < 14; i++)   /* this loop moves to line #14 */
  144.         fgets (buffer, 80, chaintxt);
  145.     ansi_status = getc (chaintxt);
  146.     fclose (chaintxt);
  147.     if (ansi_status != '0')
  148.         return 1;
  149.     else
  150.         return 0;
  151. }
  152.  
  153. /*=========================================================================*/
  154.  
  155. void show_help (void)
  156. {
  157.     printf ("\n\niceStat v1.2 \n");
  158.     printf ("Copyright (C) 1996 by Albert Vernon & Joshua Hines\n");
  159.     printf ("Beta testing by Troy Lancaster, Jim Nunn, & Kyle Miller. \n");
  160.     printf ("Additional thanks to Wayne Bell & Jon Rickher. \n");
  161.     printf ("Compiled under Turbo C++ v3.00 on %s \n", __DATE__);
  162.     printf ("Syntax as a logon event or chain is: \n");
  163.     printf ("    ICESTAT %1 \n");
  164.     printf ("This program is FREEWARE and may be freely used and copied. \n");
  165. }
  166.  
  167. /*===========================================================================
  168. display outputs the contents of a specificed file to standard output
  169.    device by block reading the file into memory, then block writing the
  170.    memory buffer to stdout.
  171. ===========================================================================*/
  172.  
  173. int     display (char *filename)
  174. {
  175.     FILE    *fp;
  176.     struct  stat    buff;
  177.     char    *membuf;
  178.  
  179.     if ((fp = fopen(filename, "rb")) == NULL)
  180.       return(0);
  181.  
  182.     stat(filename, &buff);
  183.  
  184.     if ((membuf = malloc(buff.st_size + 1024)) == NULL) {
  185.       printf("\ncannot allocate memory\n");
  186.       fclose(fp);
  187.       return(0);
  188.     }
  189.  
  190.     fread( (void *)membuf, buff.st_size, 1, fp);
  191.     fwrite( (void *)membuf, buff.st_size, 1, stdout);
  192.     fclose(fp);
  193.     free(membuf);
  194.     return(1);
  195. }
  196.  
  197. /*===========================================================================
  198.  read_chaintxt reads in data from specific lines of the specified
  199.    file name.
  200. ===========================================================================*/
  201.  
  202. int  read_chaintxt (char *filename)
  203. {
  204.     char    temp[7];
  205.     int     i;
  206.  
  207.     if ((chaintxt = fopen(filename, "rt")) == NULL)
  208.       return (0);
  209.  
  210.     fgets (temp, 6, chaintxt);   /* grab first line and */
  211.     usernum = atoi (temp);       /* put it into usernum */
  212.  
  213.     for (i = 1; i < 18; i++)                 /* grab data dir off line #18 */
  214.         fgets (data, 81, chaintxt);
  215.     data[strlen (data) - 1] = '\0';
  216.  
  217.     for (i = 18; i < 22; i++)  /* grab system name off line #22 */
  218.         fgets (systemname, 51, chaintxt);
  219.     systemname[strlen (systemname) - 1] = '\0';
  220.  
  221.     fclose (chaintxt);
  222.     return (1);
  223. }
  224. /*=========================================================================*/
  225.  
  226. int  read_userlst (void)
  227. {
  228.     char    path[128];
  229.     long    size;
  230.  
  231.     size = sizeof (userrec);
  232.  
  233.     sprintf (path, "%sUSER.LST", data);
  234.     if ((userlst = fopen (path, "rb")) == NULL)
  235.       return (0);
  236.  
  237.     fseek (userlst, size * (long) (usernum), SEEK_SET);
  238.     fread (&thisuser, size, 1, userlst);
  239.  
  240.     fclose (userlst);
  241.     return (1);
  242. }
  243.  
  244. /*=========================================================================*/
  245.  
  246. void    display_data (void)
  247. {
  248.     time_t now;  /* holds time data */
  249.     int throwaway;
  250.  
  251.     time (&now);  /* fill structure with current time info */
  252.  
  253.  
  254.     printf ("\x1b[1;37;44m");  /* set color to white on blue */
  255.     goxy (44, 4);  printf ("%s #%u", thisuser.name, usernum);
  256.     printf ("\x1b[1;37;40m");  /* set color to white on black */
  257.  
  258.     goxy (12, 10); printf ("%s", ctime (&now));
  259.     goxy (19, 11); printf (systemname);
  260.     goxy (17, 13); printf (thisuser.city);
  261.     goxy (18, 14); printf ("%u bps", thisuser.lastrate);
  262.     goxy (22, 15); printf ("%.0f minutes", thisuser.timeon / 60);
  263.     goxy (19, 16); printf ("%u", thisuser.sl);
  264.     goxy (28, 17); printf ("%u", thisuser.dsl);
  265.     goxy (8, 18);  printf ("%c", thisuser.sex);
  266.     goxy (8, 19);  printf ("%u", thisuser.age);
  267.     goxy (15, 20); printf ("%s", thisuser.laston);
  268.     goxy (17, 21); printf ("%u", thisuser.waiting);
  269.     goxy (67, 13); printf ("%u", thisuser.msgpost);
  270.     goxy (66, 14); printf ("%u", thisuser.uploaded);
  271.     goxy (66, 15); printf ("%luK", thisuser.uk);
  272.     goxy (68, 16); printf ("%u", thisuser.downloaded);
  273.     goxy (68, 17); printf ("%luK", thisuser.dk);
  274.     goxy (63, 18); printf ("%u", thisuser.logons);
  275.     goxy (62, 19); printf ("%lu", (unsigned long) (thisuser.emailsent
  276.                                   + thisuser.emailnet
  277.                                   + thisuser.feedbacksent) );
  278.     goxy (52, 21);
  279.     if (thisuser.forwardusr)
  280.         printf ("%u@%u", thisuser.forwardusr, thisuser.forwardsys);
  281.     else
  282.         printf ("<not forwarded>");
  283.  
  284.     goxy (35, 22);
  285.     while ( !kbhit() )
  286.     {
  287.         printf ("\x1b[1;34;40mPRESS A KEY");  /* switch color to blue */
  288.         left (11);
  289.         spin ("PRESS A KEY");
  290.         left (11);
  291.     }
  292.     throwaway = getch();
  293.     printf ("\x1b[0m");  /* reset colors */
  294. }
  295.  
  296. /*===========================================================================
  297.    spin is a slightly modified version of Jon Rickher's spin function from
  298.    his ENHANCE.C.  If you use this function, you >must< give credit
  299.    to Jon Rickher.
  300. ===========================================================================*/
  301.  
  302. void spin (unsigned char *s)
  303. {
  304.     register int i = 0,
  305.                  dly = 18;
  306.  
  307.     printf ("\x1b[1;36;40m");  /* switch color to cyan */
  308.     while (s[i])
  309.     {
  310.         /* this loop runs inside of a loop which is controlled by the
  311.            kbhit() function.  The kbhit() function is VERY multitasker
  312.            unfriendly.  The giveup_timeslice function compensates for
  313.            that.  Otherwise systems running a multitasker would come
  314.            to a grinding halt whenever the spinning cursor was
  315.            being displayed.  */
  316.  
  317.         giveup_timeslice();
  318.         delay(dly); putchar('/');  left(1);
  319.         delay(dly); putchar('-');  left(1);
  320.         delay(dly); putchar('\\'); left(1);
  321.         delay(dly); putchar('|');  left(1);
  322.         delay(dly); putchar(s[i]); delay(dly);
  323.         i++;
  324.     }
  325. }
  326.  
  327. /*===========================================================================
  328.    noyes returns 1 if a YES response is indicated, 0 if a NO response
  329.    is indicated.  A CR counts as a NO response.
  330. ===========================================================================*/
  331.  
  332. int noyes (void)
  333. {
  334.     int inchar;
  335.  
  336. repeat:
  337.     giveup_timeslice();
  338.     inchar = toupper (getch());
  339.     if (inchar == 'Y')
  340.         return 1;
  341.     else if ( (inchar == 'N') || (inchar == '\r') )
  342.         return 0;
  343.     else goto repeat;
  344. }
  345.  
  346. /*===========================================================================
  347. The code from here to the end of the file is copyright by Wayne Bell,
  348. the author of WWIV BBS software.  Wayne has granted permission for these
  349. functions to be freely used and distributed.  So you are welcome to
  350. use them in any of your programs, but you must give him the appropriate
  351. credit.
  352. ===========================================================================*/
  353.  
  354. #define MT_DESQVIEW 0x01
  355. #define MT_WINDOWS  0x02
  356. #define MT_OS2      0x04
  357.  
  358.  
  359. /* 
  360.    This function must be called at the beginning of your program,
  361.    before you first call giveup_timeslice() .
  362. */
  363.  
  364. void detect_multitask(void)
  365. {
  366.   get_dos_version();
  367.   get_win_version();
  368.   get_dv_version();
  369. }
  370.  
  371. /*=========================================================================*/
  372.  
  373. int get_dos_version(void)
  374. {
  375.   _AX=0x3000;
  376.   geninterrupt(0x21);
  377.   if(_AX%256 >=10) {
  378.     multitasker |= MT_OS2;
  379.   }
  380.   return(_AX);
  381. }
  382.  
  383. /*=========================================================================*/
  384.  
  385. int get_dv_version(void)
  386. {
  387.   int v;
  388.  
  389.   _AX=0x2b01;
  390.   _CX=0x4445;
  391.   _DX=0x5351;
  392.   geninterrupt(0x21);
  393.   if (_AL == 0xff) {
  394.     return 0;
  395.   } else {
  396.     v=_BX;
  397.     multitasker |= MT_DESQVIEW;
  398.     return v;
  399.   }
  400. }
  401.  
  402. /*=========================================================================*/
  403.  
  404. int get_win_version(void)
  405. {
  406.   int v=0;
  407.  
  408. /*
  409.  *  push  bp
  410.  *  push  es
  411.  *  push  bx
  412.  */
  413.   __emit__(0x55, 0x06, 0x53);
  414.  
  415.   _AX=0x352f;
  416.   geninterrupt(0x21);
  417.   _AX=_ES;
  418.  
  419.   if (_AX | _BX) {
  420.  
  421.     _AX=0x1600;
  422.     geninterrupt(0x2f);
  423.  
  424.     v=_AX;
  425.     if (v%256<=1)
  426.       v=0;
  427.   }
  428.  
  429. /*
  430.  * pop bx
  431.  * pop es
  432.  * pop bp
  433.  */
  434.   __emit__(0x5b, 0x07, 0x5d);
  435.  
  436.   if (v!=0)
  437.     multitasker |= MT_WINDOWS;
  438.   return(v);
  439. }
  440.  
  441. /*=========================================================================*/
  442.  
  443. void giveup_timeslice(void)
  444. {
  445.   if (multitasker) {
  446.     switch (multitasker) {
  447.       case 1 : /* DESQView pause */
  448.           dv_pause();
  449.           break;
  450.       case 2 : /* Windows pause */
  451.           win_pause();
  452.           break;
  453.       case 3 : /* Win or DV pause */
  454.           win_pause();
  455.           break;
  456.       case 4:  /* OS/2 pause */
  457.           _AX=0x1680;
  458.           geninterrupt(0x2f);
  459.           break;
  460.       case 5:
  461.       case 6:
  462.       case 7:
  463.           delay(17);
  464.           win_pause();
  465.           break;
  466.       default: 
  467.           puts ("Unrecognized multitasker");
  468.           break;
  469.     }
  470.   }
  471. }
  472.  
  473. /*=========================================================================*/
  474.  
  475. void dv_pause(void)
  476. {
  477.   _AX=0x101a;
  478.   geninterrupt(0x15);
  479.   _AX=0x1000;
  480.   geninterrupt(0x15);
  481.   _AX=0x1025;
  482.   geninterrupt(0x15);
  483. }
  484.  
  485. /*=========================================================================*/
  486.  
  487. void win_pause(void)
  488. {
  489.   __emit__(0x55, 0xb8, 0x80, 0x16, 0xcd, 0x2f, 0x5d);
  490. /*
  491.  * push bp
  492.  * mov ax,0x1680
  493.  * int 0x2f
  494.  * pop bp
  495.  */
  496. }
  497.  
  498. /*==END OF FILE ===========================================================*/
  499.  
  500.  
  501.