Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. #include <_ansi.h>
  2. #include <reent.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <sys/types.h>
  7. #include <sys/time.h>
  8. #include "local.h"
  9.  
  10. #define sscanf siscanf  /* avoid to pull in FP functions. */
  11.  
  12. static char __tzname_std[11];
  13. static char __tzname_dst[11];
  14. static char *prev_tzenv = NULL;
  15.  
  16. _VOID
  17. _DEFUN (_tzset_unlocked_r, (reent_ptr),
  18.         struct _reent *reent_ptr)
  19. {
  20.   char *tzenv;
  21.   unsigned short hh, mm, ss, m, w, d;
  22.   int sign, n;
  23.   int i, ch;
  24.   __tzinfo_type *tz = __gettzinfo ();
  25.  
  26.   if ((tzenv = _getenv_r (reent_ptr, "TZ")) == NULL)
  27.       {
  28.         _timezone = 0;
  29.         _daylight = 0;
  30.         _tzname[0] = "GMT";
  31.         _tzname[1] = "GMT";
  32.         free(prev_tzenv);
  33.         prev_tzenv = NULL;
  34.         return;
  35.       }
  36.  
  37.   if (prev_tzenv != NULL && strcmp(tzenv, prev_tzenv) == 0)
  38.     return;
  39.  
  40.   free(prev_tzenv);
  41.   prev_tzenv = _malloc_r (reent_ptr, strlen(tzenv) + 1);
  42.   if (prev_tzenv != NULL)
  43.     strcpy (prev_tzenv, tzenv);
  44.  
  45.   /* ignore implementation-specific format specifier */
  46.   if (*tzenv == ':')
  47.     ++tzenv;  
  48.  
  49.   if (sscanf (tzenv, "%10[^0-9,+-]%n", __tzname_std, &n) <= 0)
  50.     return;
  51.  
  52.   tzenv += n;
  53.  
  54.   sign = 1;
  55.   if (*tzenv == '-')
  56.     {
  57.       sign = -1;
  58.       ++tzenv;
  59.     }
  60.   else if (*tzenv == '+')
  61.     ++tzenv;
  62.  
  63.   mm = 0;
  64.   ss = 0;
  65.  
  66.   if (sscanf (tzenv, "%hu%n:%hu%n:%hu%n", &hh, &n, &mm, &n, &ss, &n) < 1)
  67.     return;
  68.  
  69.   tz->__tzrule[0].offset = sign * (ss + SECSPERMIN * mm + SECSPERHOUR * hh);
  70.   _tzname[0] = __tzname_std;
  71.   tzenv += n;
  72.  
  73.   if (sscanf (tzenv, "%10[^0-9,+-]%n", __tzname_dst, &n) <= 0)
  74.     { /* No dst */
  75.       _tzname[1] = _tzname[0];
  76.       _timezone = tz->__tzrule[0].offset;
  77.       _daylight = 0;
  78.       return;
  79.     }
  80.   else
  81.     _tzname[1] = __tzname_dst;
  82.  
  83.   tzenv += n;
  84.  
  85.   /* otherwise we have a dst name, look for the offset */
  86.   sign = 1;
  87.   if (*tzenv == '-')
  88.     {
  89.       sign = -1;
  90.       ++tzenv;
  91.     }
  92.   else if (*tzenv == '+')
  93.     ++tzenv;
  94.  
  95.   hh = 0;  
  96.   mm = 0;
  97.   ss = 0;
  98.  
  99.   n  = 0;
  100.   if (sscanf (tzenv, "%hu%n:%hu%n:%hu%n", &hh, &n, &mm, &n, &ss, &n) <= 0)
  101.     tz->__tzrule[1].offset = tz->__tzrule[0].offset - 3600;
  102.   else
  103.     tz->__tzrule[1].offset = sign * (ss + SECSPERMIN * mm + SECSPERHOUR * hh);
  104.  
  105.   tzenv += n;
  106.  
  107.   for (i = 0; i < 2; ++i)
  108.     {
  109.       if (*tzenv == ',')
  110.         ++tzenv;
  111.  
  112.       if (*tzenv == 'M')
  113.         {
  114.           if (sscanf (tzenv, "M%hu%n.%hu%n.%hu%n", &m, &n, &w, &n, &d, &n) != 3 ||
  115.               m < 1 || m > 12 || w < 1 || w > 5 || d > 6)
  116.             return;
  117.          
  118.           tz->__tzrule[i].ch = 'M';
  119.           tz->__tzrule[i].m = m;
  120.           tz->__tzrule[i].n = w;
  121.           tz->__tzrule[i].d = d;
  122.          
  123.           tzenv += n;
  124.         }
  125.       else
  126.         {
  127.           char *end;
  128.           if (*tzenv == 'J')
  129.             {
  130.               ch = 'J';
  131.               ++tzenv;
  132.             }
  133.           else
  134.             ch = 'D';
  135.          
  136.           d = strtoul (tzenv, &end, 10);
  137.          
  138.           /* if unspecified, default to US settings */
  139.           /* From 1987-2006, US was M4.1.0,M10.5.0, but starting in 2007 is
  140.            * M3.2.0,M11.1.0 (2nd Sunday March through 1st Sunday November)  */
  141.           if (end == tzenv)
  142.             {
  143.               if (i == 0)
  144.                 {
  145.                   tz->__tzrule[0].ch = 'M';
  146.                   tz->__tzrule[0].m = 3;
  147.                   tz->__tzrule[0].n = 2;
  148.                   tz->__tzrule[0].d = 0;
  149.                 }
  150.               else
  151.                 {
  152.                   tz->__tzrule[1].ch = 'M';
  153.                   tz->__tzrule[1].m = 11;
  154.                   tz->__tzrule[1].n = 1;
  155.                   tz->__tzrule[1].d = 0;
  156.                 }
  157.             }
  158.           else
  159.             {
  160.               tz->__tzrule[i].ch = ch;
  161.               tz->__tzrule[i].d = d;
  162.             }
  163.          
  164.           tzenv = end;
  165.         }
  166.      
  167.       /* default time is 02:00:00 am */
  168.       hh = 2;
  169.       mm = 0;
  170.       ss = 0;
  171.       n = 0;
  172.      
  173.       if (*tzenv == '/')
  174.         sscanf (tzenv, "/%hu%n:%hu%n:%hu%n", &hh, &n, &mm, &n, &ss, &n);
  175.  
  176.       tz->__tzrule[i].s = ss + SECSPERMIN * mm + SECSPERHOUR  * hh;
  177.      
  178.       tzenv += n;
  179.     }
  180.  
  181.   __tzcalc_limits (tz->__tzyear);
  182.   _timezone = tz->__tzrule[0].offset;  
  183.   _daylight = tz->__tzrule[0].offset != tz->__tzrule[1].offset;
  184. }
  185.  
  186. _VOID
  187. _DEFUN (_tzset_r, (reent_ptr),
  188.         struct _reent *reent_ptr)
  189. {
  190.   TZ_LOCK;
  191.   _tzset_unlocked_r (reent_ptr);
  192.   TZ_UNLOCK;
  193. }
  194.