home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / xuptime.zip / uptime.c < prev    next >
C/C++ Source or Header  |  1998-08-29  |  10KB  |  359 lines

  1. /* Program:   XUPTIME OS/2 1.1
  2.    Platform:  OS/2
  3.    Compilers: Borland C, EMX GNU C, IBM C-Set
  4.    Compile:   $(CC) uptime.c
  5.    Purpose:   Print the uptime of the machine based on the creation date
  6.               of the swap file. In contrast too tools querying the uptime
  7.               timer of OS/2, this can also cover uptimes > ~ 50 days.
  8.    Author:    Tobias Ernst, tobi@bland.fido.de
  9.    License:   Public Domain
  10. */
  11.  
  12. #define INCL_DOSFILEMGR
  13. #define INCL_DOSMISC
  14. #define INCL_DOSDATETIME
  15. #include <os2.h>
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19.  
  20. #define eatwhite(cp) { while (*(cp) == ' ' || *(cp) == '\n' || *(cp) == '\t') { (cp)++; } }
  21.  
  22.  
  23.  
  24. /* get_boot_drive: get the drive letter of this OS/2 system's boot drive */
  25.  
  26. char get_boot_drive(void)
  27. {
  28.     ULONG StartIndex = QSV_BOOT_DRIVE;
  29.     ULONG LastIndex = QSV_BOOT_DRIVE;
  30.     UCHAR DataBuf[4];
  31.     ULONG DataBufLen = 4;
  32.     APIRET rc;
  33.  
  34.     rc = DosQuerySysInfo(StartIndex, LastIndex, DataBuf, DataBufLen);
  35.     if (rc != 0)
  36.     {
  37.         fprintf(stderr, "DosQuerySysInfo returned %ld\n", rc);
  38.         exit(0);
  39.     }
  40.     return (DataBuf[0] + 'A' -1);
  41. }
  42.  
  43.  
  44.  
  45. /* get_swap_file: get the name of the swap file of this OS/2 system by
  46.                   parsing it's config.sys file.  */
  47.  
  48. char *get_swap_file(void)
  49. {
  50.     char configsys[] = "X:\\CONFIG.SYS";
  51.     char buffer[256], *cp, *swap_file = NULL;
  52.     FILE *f;
  53.     int i;
  54.  
  55.     configsys[0] = get_boot_drive();
  56.     if ((f = fopen(configsys, "r")) == NULL)
  57.     {
  58.         fprintf (stderr, "Could not open %s for reading.\n", configsys);
  59.         exit(0);
  60.     }
  61.     while ( (cp = fgets(buffer, 256, f)) != NULL)
  62.     {
  63.         eatwhite(cp);
  64.         if (!strnicmp(cp, "SWAPPATH", 8))
  65.         {
  66.             cp += 8;
  67.             eatwhite(cp);
  68.             if (*cp == '=')
  69.             {
  70.                 cp++;
  71.                 eatwhite(cp);
  72.                 for (i = 0;
  73.                      cp[i] != ' ' && cp[i] != '\t'
  74.                      && cp[i] != '\n' && cp[i] != '\0';
  75.                      i++);
  76.                 swap_file = malloc(i + 13);
  77.                 strncpy(swap_file, cp, i);
  78.                 if (swap_file[i - 1] != '\\')
  79.                 {
  80.                     swap_file[i++] = '\\';
  81.                 }
  82.                 strcpy(swap_file + i, "SWAPPER.DAT");
  83.  
  84.                 return (swap_file);
  85.             }
  86.         }
  87.  
  88.         /* eat rest of line if it was > 256 chars */
  89.         while (*buffer && buffer[strlen(buffer) - 1] != '\n')
  90.         {
  91.             if (fgets(buffer, 256, f) == NULL)
  92.             {
  93.                 break;
  94.             }
  95.         }
  96.     }
  97.     fprintf (stderr, "%s does not contain a SWAPPATH statement.\n", configsys);
  98.     exit(0);
  99.     return 0;
  100. }
  101.  
  102.  
  103. /* is_leap_year: tests if the specified year (4 digit) is a leap year */
  104.  
  105. int is_leap_year(unsigned year)
  106. {
  107.     if (!((year % 100) % 4))
  108.     {
  109.         if (!(year % 100))
  110.         {
  111.             if (!(year % 400))
  112.             {
  113.                 return 1;
  114.             }
  115.             else
  116.             {
  117.                 return 0;
  118.             }
  119.         }
  120.         else
  121.         {
  122.             return 1;
  123.         }
  124.     }
  125.     else
  126.     {
  127.         return 0;
  128.     }
  129. }
  130.  
  131.  
  132. /* n_days_in_month: returns the number of days in a certain month */
  133.  
  134. int n_days_in_month(unsigned month, unsigned year)
  135. {
  136.     switch (month)
  137.     {
  138.     case 1:
  139.     case 3:
  140.     case 5:
  141.     case 7:
  142.     case 8:
  143.     case 10:
  144.     case 12:
  145.         return 31;
  146.     case 4:
  147.     case 6:
  148.     case 9:
  149.     case 11:
  150.         return 30;
  151.     case 2:
  152.         return (is_leap_year(year)) ? 29 : 28;
  153.     }
  154.     return 0;
  155. }
  156.  
  157.  
  158.  
  159. /* n_days_since_1900: returns the number of days that have passed since
  160.                       1/1/1900 */
  161.  
  162. unsigned long n_days_since_1900(int dd, int md, int yd)
  163. {
  164.   int d=1,m,y;
  165.   unsigned long ds=0;
  166.  
  167.   for (y = 1900; y<yd; y++)
  168.   {
  169.       ds += is_leap_year(y) ? 366 : 365;
  170.   }
  171.   for (m=1; m<md; m++)
  172.   {
  173.       ds += n_days_in_month(m, y);
  174.   }
  175.   ds += dd - d;
  176.   return ds;
  177. }
  178.  
  179.  
  180. /* get_uptime: returns the age of the swap file in seconds */
  181.  
  182. unsigned long get_uptime_from_swapfile(char *swapfile, int verbose)
  183. {
  184.     FILEFINDBUF3 InfoBuf;
  185.     HDIR hDir = 0x0001;
  186.     ULONG cSearch = 1;
  187.     ULONG usAttrib;
  188.     APIRET rc;
  189.     DATETIME DateTime;
  190.     unsigned long uptime;
  191.  
  192.     rc = DosFindFirst((UCHAR *)swapfile,
  193.                       &hDir,
  194.                       FILE_SYSTEM | FILE_HIDDEN | FILE_READONLY,
  195.                       &InfoBuf,
  196.                       sizeof InfoBuf,
  197.                       &cSearch,
  198.                       FIL_STANDARD);
  199.  
  200.     if (rc != 0)
  201.     {
  202.         fprintf(stderr, "DosFindFirst returned %ld\n", rc);
  203.         exit(0);
  204.     }
  205.  
  206.     DosFindClose(hDir);
  207.  
  208.     rc = DosGetDateTime(&DateTime);
  209.  
  210.     if (rc != 0)
  211.     {
  212.         fprintf(stderr, "DosGetDateTime returned %ld\n", rc);
  213.         exit (0);
  214.     }
  215.  
  216.     uptime  = n_days_since_1900(DateTime.day, DateTime.month, DateTime.year);
  217.     uptime -= n_days_since_1900(InfoBuf.fdateCreation.day,
  218.                                 InfoBuf.fdateCreation.month,
  219.                                 InfoBuf.fdateCreation.year + 1980);
  220.     uptime *= (60L * 60L * 24L);
  221.  
  222.     uptime +=   (ULONG)DateTime.hours * 60L * 60L
  223.               + (ULONG)DateTime.minutes * 60L
  224.               + (ULONG)DateTime.seconds;
  225.     uptime -=    (ULONG)InfoBuf.ftimeCreation.hours * 60L * 60L
  226.               + (ULONG)InfoBuf.ftimeCreation.minutes * 60L
  227.               + (ULONG)InfoBuf.ftimeCreation.twosecs * 2L;
  228.  
  229.  
  230.     if (verbose)
  231.     {
  232.         printf ("OS/2 swap file used:    %s\n", swapfile);
  233.         printf ("Swapfile creation date: %02d/%02d/%04d, %02d:%02d\n",
  234.            InfoBuf.fdateCreation.month, InfoBuf.fdateCreation.day,
  235.            InfoBuf.fdateCreation.year + 1980,
  236.            InfoBuf.ftimeCreation.hours, InfoBuf.ftimeCreation.minutes);
  237.         printf ("Last modification:      %02d/%02d/%04d, %02d:%02d\n",
  238.            InfoBuf.fdateLastWrite.month, InfoBuf.fdateLastWrite.day,
  239.            InfoBuf.fdateLastWrite.year + 1980,
  240.            InfoBuf.ftimeLastWrite.hours, InfoBuf.ftimeLastWrite.minutes);
  241.         printf ("Last read access:       %02d/%02d/%04d, %02d:%02d\n",
  242.            InfoBuf.fdateLastAccess.month, InfoBuf.fdateLastAccess.day,
  243.            InfoBuf.fdateLastAccess.year + 1980,
  244.            InfoBuf.ftimeLastAccess.hours, InfoBuf.ftimeLastAccess.minutes);
  245.         printf ("Current date is:        %02d/%02d/%04d, %02d:%02d\n",
  246.            DateTime.month, DateTime.day, DateTime.year,
  247.            DateTime.hours, DateTime.minutes);
  248.         printf ("-------------------------------------------------\n");
  249.     }
  250.  
  251.     return uptime;
  252. }
  253.  
  254.  
  255.  
  256. /* get_uptime_from_os2_timer: get the "uptime" from QSV_MS_COUNT */
  257.  
  258. unsigned long get_uptime_from_os2_timer(int verbose)
  259. {
  260.     ULONG StartIndex = QSV_MS_COUNT;
  261.     ULONG LastIndex = QSV_MS_COUNT;
  262.     ULONG ms_count;
  263.     ULONG DataBufLen = 4;
  264.     APIRET rc;
  265.  
  266.     rc = DosQuerySysInfo(StartIndex, LastIndex,
  267.                          (UCHAR *)(&ms_count), DataBufLen);
  268.     if (rc != 0)
  269.     {
  270.         fprintf(stderr, "DosQuerySysInfo returned %ld\n", rc);
  271.         exit(0);
  272.     }
  273.  
  274.     if (verbose)
  275.     {
  276.         printf ("Milliseconds passed since last timer wrap: %lu\n", ms_count);
  277.         printf ("Note: There is no way to determine how many times the timer has wrapped,\n");
  278.         printf ("so the calculated uptime value below may be incorrect.\n\n");
  279.     }
  280.     return ms_count / (ULONG)1000;
  281. }
  282.  
  283.  
  284. void print_help(void)
  285. {
  286.     printf ("XUPTIME OS/2 1.1 written by Tobias Ernst (tobi@bland.fido.de)\n");
  287.     printf ("=============================================================\n\n");
  288.     printf ("An extended uptime meter for OS/2 that can handle uptimes greater than 50 days.\n\n");
  289.     printf ("Usage:\n");
  290.     printf ("         xuptime [-h] [-?] [-2] [-v]\n\n");
  291.     printf ("Meaning of the options:\n");
  292.     printf ("         -h   Print this help scren\n");
  293.     printf ("         -?   Same as -h\n");
  294.     printf ("         -2   Query uptime from OS/2 system timer. This does only work if the\n");
  295.     printf ("              uptime is < 50 days. If you do NOT specify this parameter, the\n");
  296.     printf ("              uptime is calculated from the creation date of the swap file,\n");
  297.     printf ("              which will also work for uptimes >= 50 days.\n");
  298.     printf ("         -v   Print more verbose information (only works if -2 not specified).\n\n");
  299. }
  300.  
  301. int main(int argc, char **argv)
  302. {
  303.     int i, verbose = 0, use_os2_timer = 0;
  304.     char *s;
  305.     unsigned long uptime, days, hours, minutes, seconds;
  306.     char *hostname = getenv("HOSTNAME");
  307.  
  308.  
  309.     for (i = 1; i < argc; i++)
  310.     {
  311.         if (argv[i][0] == '-' || argv[i][0] == '/')
  312.         {
  313.             switch(argv[i][1])
  314.             {
  315.             case 'h':
  316.             case '?':
  317.                 print_help();
  318.                 exit(0);
  319.             case 'v':
  320.                 verbose = 1;
  321.                 break;
  322.             case '2':
  323.                 use_os2_timer = 1;
  324.                 break;
  325.             }
  326.         }
  327.     }
  328.  
  329.     if (use_os2_timer)
  330.     {
  331.         uptime = get_uptime_from_os2_timer(verbose);
  332.     }
  333.     else
  334.     {
  335.         s = get_swap_file();
  336.         uptime = get_uptime_from_swapfile(s, verbose);
  337.     }
  338.  
  339.     if (hostname == NULL)
  340.     {
  341.         hostname = "localhost";
  342.     }
  343.  
  344.     days    = uptime / (60L * 60L * 24L);
  345.     uptime  = uptime % (60L * 60L * 24L);
  346.     hours   = uptime / (60L * 60L);
  347.     uptime  = uptime % (60L * 60L);
  348.     minutes = uptime / (60L);
  349.     seconds = uptime % (60L);
  350.  
  351.     printf ("%s: uptime is %ld day%s, %02ld:%02ld hours and %02ld second%s\n",
  352.             hostname, days, "s" + (days == 1), hours,
  353.             minutes, seconds, "s" + (seconds == 1));
  354.  
  355.     free(s);
  356.     return days;
  357. }
  358.  
  359.