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

  1. /*
  2.    ICESTAT.C - iceStat v1.1
  3.    Copyright (C) 1995 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:  11 June 1995
  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;34m▄▒ \x1b[0;1;34miceStat\x1b[0;1;33m:\x1b[0;34m░ \x1b[0;1mWould you like to view your statistics? \x1b[0;34m░\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.1 \n");
  158.     printf ("Copyright (C) 1995 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;34;40m"); /* set color to blue */
  255.     goxy (23, 5);  printf (systemname);
  256.     goxy (16, 6);  printf ("%s", ctime (&now));
  257.     goxy (20, 9);  printf ("%s #%u", thisuser.name, usernum);
  258.     goxy (23, 10); printf (thisuser.city);
  259.     goxy (26, 11); printf ("%u", thisuser.msgpost);
  260.     goxy (24, 12); printf ("%ubps", thisuser.lastrate);
  261.     goxy (25, 13); printf ("%luK", thisuser.uk);
  262.     goxy (25, 14); printf ("%luK", thisuser.dk);
  263.     goxy (28, 15); printf ("%.0f minutes", thisuser.timeon / 60);
  264.     goxy (25, 16);
  265.     if (thisuser.forwardusr)
  266.         printf ("%u@%u", thisuser.forwardusr, thisuser.forwardsys);
  267.     else
  268.         printf ("<not forwarded>");
  269.     goxy (22, 17); printf ("%u", thisuser.logons);
  270.     goxy (22, 18); printf ("%lu", (unsigned long) (thisuser.emailsent
  271.                                   + thisuser.emailnet
  272.                                   + thisuser.feedbacksent) );
  273.     goxy (52, 11); printf ("%c", thisuser.sex);
  274.     goxy (52, 12); printf ("%u", thisuser.age);
  275.     goxy (63, 13); printf ("%u", thisuser.sl);
  276.     goxy (70, 14); printf ("%u", thisuser.dsl);
  277.     goxy (63, 15); printf ("%u", thisuser.uploaded);
  278.     goxy (63, 16); printf ("%u", thisuser.downloaded);
  279.     goxy (59, 17); printf ("%s", thisuser.laston);
  280.     goxy (61, 18); printf ("%u", thisuser.waiting);
  281.  
  282.     goxy (35, 22);
  283.  
  284.     while ( !kbhit() )
  285.     {
  286.         printf ("\x1b[1;34;40mPRESS A KEY");  /* switch color to blue */
  287.         left (11);
  288.         spin ("PRESS A KEY");
  289.         left (11);
  290.     }
  291.     throwaway = getch();
  292.     printf ("\x1b[0;0;40m");  /* reset colors */
  293. }
  294.  
  295. /*===========================================================================
  296.    spin is a slightly modified version of Jon Rickher's spin function from
  297.    his ENHANCE.C.  If you use this function, you >must< give credit
  298.    to Jon Rickher.
  299. ===========================================================================*/
  300.  
  301. void spin (unsigned char *s)
  302. {
  303.     register int i = 0,
  304.                  dly = 18;
  305.  
  306.     printf ("\x1b[1;36;40m");  /* switch color to cyan */
  307.     while (s[i])
  308.     {
  309.         /* this loop runs inside of a loop which is controlled by the
  310.            kbhit() function.  The kbhit() function is VERY multitasker
  311.            unfriendly.  The giveup_timeslice function compensates for
  312.            that.  Otherwise systems running a multitasker would come
  313.            to a grinding halt whenever the spinning cursor was
  314.            being displayed.  */
  315.  
  316.         giveup_timeslice();
  317.         delay(dly); putchar('/');  left(1);
  318.         delay(dly); putchar('-');  left(1);
  319.         delay(dly); putchar('\\'); left(1);
  320.         delay(dly); putchar('|');  left(1);
  321.         delay(dly); putchar(s[i]); delay(dly);
  322.         i++;
  323.     }
  324. }
  325.  
  326. /*===========================================================================
  327.    noyes returns 1 if a YES response is indicated, 0 if a NO response
  328.    is indicated.  A CR counts as a NO response.
  329. ===========================================================================*/
  330.  
  331. int noyes (void)
  332. {
  333.     int inchar;
  334.  
  335. repeat:
  336.     giveup_timeslice();
  337.     inchar = toupper (getch());
  338.     if (inchar == 'Y')
  339.         return 1;
  340.     else if ( (inchar == 'N') || (inchar == '\r') )
  341.         return 0;
  342.     else goto repeat;
  343. }
  344.  
  345. /*===========================================================================
  346. The code from here to the end of the file is copyright by Wayne Bell,
  347. the author of WWIV BBS software.  Wayne has granted permission for these
  348. functions to be freely used and distributed.  So you are welcome to
  349. use them in any of your programs, but you must give him the appropriate
  350. credit.
  351. ===========================================================================*/
  352.  
  353. #define MT_DESQVIEW 0x01
  354. #define MT_WINDOWS  0x02
  355. #define MT_OS2      0x04
  356.  
  357.  
  358. /* 
  359.    This function must be called at the beginning of your program,
  360.    before you first call giveup_timeslice() .
  361. */
  362.  
  363. void detect_multitask(void)
  364. {
  365.   get_dos_version();
  366.   get_win_version();
  367.   get_dv_version();
  368. }
  369.  
  370. /*=========================================================================*/
  371.  
  372. int get_dos_version(void)
  373. {
  374.   _AX=0x3000;
  375.   geninterrupt(0x21);
  376.   if(_AX%256 >=10) {
  377.     multitasker |= MT_OS2;
  378.   }
  379.   return(_AX);
  380. }
  381.  
  382. /*=========================================================================*/
  383.  
  384. int get_dv_version(void)
  385. {
  386.   int v;
  387.  
  388.   _AX=0x2b01;
  389.   _CX=0x4445;
  390.   _DX=0x5351;
  391.   geninterrupt(0x21);
  392.   if (_AL == 0xff) {
  393.     return 0;
  394.   } else {
  395.     v=_BX;
  396.     multitasker |= MT_DESQVIEW;
  397.     return v;
  398.   }
  399. }
  400.  
  401. /*=========================================================================*/
  402.  
  403. int get_win_version(void)
  404. {
  405.   int v=0;
  406.  
  407. /*
  408.  *  push  bp
  409.  *  push  es
  410.  *  push  bx
  411.  */
  412.   __emit__(0x55, 0x06, 0x53);
  413.  
  414.   _AX=0x352f;
  415.   geninterrupt(0x21);
  416.   _AX=_ES;
  417.  
  418.   if (_AX | _BX) {
  419.  
  420.     _AX=0x1600;
  421.     geninterrupt(0x2f);
  422.  
  423.     v=_AX;
  424.     if (v%256<=1)
  425.       v=0;
  426.   }
  427.  
  428. /*
  429.  * pop bx
  430.  * pop es
  431.  * pop bp
  432.  */
  433.   __emit__(0x5b, 0x07, 0x5d);
  434.  
  435.   if (v!=0)
  436.     multitasker |= MT_WINDOWS;
  437.   return(v);
  438. }
  439.  
  440. /*=========================================================================*/
  441.  
  442. void giveup_timeslice(void)
  443. {
  444.   if (multitasker) {
  445.     switch (multitasker) {
  446.       case 1 : /* DESQView pause */
  447.           dv_pause();
  448.           break;
  449.       case 2 : /* Windows pause */
  450.           win_pause();
  451.           break;
  452.       case 3 : /* Win or DV pause */
  453.           win_pause();
  454.           break;
  455.       case 4:  /* OS/2 pause */
  456.           _AX=0x1680;
  457.           geninterrupt(0x2f);
  458.           break;
  459.       case 5:
  460.       case 6:
  461.       case 7:
  462.           delay(17);
  463.           win_pause();
  464.           break;
  465.       default: 
  466.           puts ("Unrecognized multitasker");
  467.           break;
  468.     }
  469.   }
  470. }
  471.  
  472. /*=========================================================================*/
  473.  
  474. void dv_pause(void)
  475. {
  476.   _AX=0x101a;
  477.   geninterrupt(0x15);
  478.   _AX=0x1000;
  479.   geninterrupt(0x15);
  480.   _AX=0x1025;
  481.   geninterrupt(0x15);
  482. }
  483.  
  484. /*=========================================================================*/
  485.  
  486. void win_pause(void)
  487. {
  488.   __emit__(0x55, 0xb8, 0x80, 0x16, 0xcd, 0x2f, 0x5d);
  489. /*
  490.  * push bp
  491.  * mov ax,0x1680
  492.  * int 0x2f
  493.  * pop bp
  494.  */
  495. }
  496.  
  497. /*==END OF FILE ===========================================================*/
  498.  
  499.  
  500.