1*0Sstevel@tonic-gate %{ 2*0Sstevel@tonic-gate /* 3*0Sstevel@tonic-gate * Copyright (c) 1998 by Sun Microsystems, Inc. 4*0Sstevel@tonic-gate * All rights reserved. 5*0Sstevel@tonic-gate */ 6*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 7*0Sstevel@tonic-gate 8*0Sstevel@tonic-gate /* $OrigRevision: 2.1 $ 9*0Sstevel@tonic-gate ** 10*0Sstevel@tonic-gate ** Originally written by Steven M. Bellovin <smb@research.att.com> while 11*0Sstevel@tonic-gate ** at the University of North Carolina at Chapel Hill. Later tweaked by 12*0Sstevel@tonic-gate ** a couple of people on Usenet. Completely overhauled by Rich $alz 13*0Sstevel@tonic-gate ** <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990; 14*0Sstevel@tonic-gate ** send any email to Rich. 15*0Sstevel@tonic-gate ** 16*0Sstevel@tonic-gate ** This grammar has eight shift/reduce conflicts. 17*0Sstevel@tonic-gate ** 18*0Sstevel@tonic-gate ** This code is in the public domain and has no copyright. 19*0Sstevel@tonic-gate */ 20*0Sstevel@tonic-gate /* SUPPRESS 287 on yaccpar_sccsid *//* Unusd static variable */ 21*0Sstevel@tonic-gate /* SUPPRESS 288 on yyerrlab *//* Label unused */ 22*0Sstevel@tonic-gate #include <stdio.h> 23*0Sstevel@tonic-gate #include <ctype.h> 24*0Sstevel@tonic-gate 25*0Sstevel@tonic-gate #include <sys/types.h> 26*0Sstevel@tonic-gate #define NEED_TZSET 27*0Sstevel@tonic-gate struct timeb { 28*0Sstevel@tonic-gate time_t time; /* Seconds since the epoch */ 29*0Sstevel@tonic-gate unsigned short millitm; /* Field not used */ 30*0Sstevel@tonic-gate short timezone; 31*0Sstevel@tonic-gate short dstflag; /* Field not used */ 32*0Sstevel@tonic-gate }; 33*0Sstevel@tonic-gate #include <time.h> 34*0Sstevel@tonic-gate 35*0Sstevel@tonic-gate #include <locale.h> 36*0Sstevel@tonic-gate #include <string.h> 37*0Sstevel@tonic-gate #include <stdlib.h> 38*0Sstevel@tonic-gate #include <note.h> 39*0Sstevel@tonic-gate #include <libintl.h> 40*0Sstevel@tonic-gate 41*0Sstevel@tonic-gate #if !defined(lint) && !defined(SABER) 42*0Sstevel@tonic-gate static char RCS[] = 43*0Sstevel@tonic-gate "$Header: /home/laramie/berliner/ws/backup/usr/src/cmd/backup/lib/getdate.y,v 1.5 1992/06/09 21:46:21 sam Exp $"; 44*0Sstevel@tonic-gate #endif /* !defined(lint) && !defined(SABER) */ 45*0Sstevel@tonic-gate 46*0Sstevel@tonic-gate 47*0Sstevel@tonic-gate #define EPOCH 1970 48*0Sstevel@tonic-gate #define HOURN(x) (x * 60) 49*0Sstevel@tonic-gate #define SECSPERDAY (24L * 60L * 60L) 50*0Sstevel@tonic-gate 51*0Sstevel@tonic-gate #define CHECK_TM(y) (((y) % 100) < 70 ? (y) + 2000 : (y) + 1900) 52*0Sstevel@tonic-gate 53*0Sstevel@tonic-gate /* 54*0Sstevel@tonic-gate ** An entry in the lexical lookup table. 55*0Sstevel@tonic-gate */ 56*0Sstevel@tonic-gate typedef struct _TABLE { 57*0Sstevel@tonic-gate char *name; 58*0Sstevel@tonic-gate int type; 59*0Sstevel@tonic-gate time_t value; 60*0Sstevel@tonic-gate } TABLE; 61*0Sstevel@tonic-gate 62*0Sstevel@tonic-gate 63*0Sstevel@tonic-gate /* 64*0Sstevel@tonic-gate ** Daylight-savings mode: on, off, or not yet known. 65*0Sstevel@tonic-gate */ 66*0Sstevel@tonic-gate typedef enum _DSTMODE { 67*0Sstevel@tonic-gate DSTon, DSToff, DSTmaybe 68*0Sstevel@tonic-gate } DSTMODE; 69*0Sstevel@tonic-gate 70*0Sstevel@tonic-gate /* 71*0Sstevel@tonic-gate ** Meridian: am, pm, or 24-hour style. 72*0Sstevel@tonic-gate */ 73*0Sstevel@tonic-gate typedef enum _MERIDIAN { 74*0Sstevel@tonic-gate MERam, MERpm, MER24 75*0Sstevel@tonic-gate } MERIDIAN; 76*0Sstevel@tonic-gate 77*0Sstevel@tonic-gate 78*0Sstevel@tonic-gate /* 79*0Sstevel@tonic-gate ** Global variables. We could get rid of most of these by using a good 80*0Sstevel@tonic-gate ** union as the yacc stack. (This routine was originally written before 81*0Sstevel@tonic-gate ** yacc had the %union construct.) Maybe someday; right now we only use 82*0Sstevel@tonic-gate ** the %union very rarely. 83*0Sstevel@tonic-gate */ 84*0Sstevel@tonic-gate static char *yyInput; 85*0Sstevel@tonic-gate static DSTMODE yyDSTmode; 86*0Sstevel@tonic-gate static time_t yyDayOrdinal; 87*0Sstevel@tonic-gate static time_t yyDayNumber; 88*0Sstevel@tonic-gate static int yyHaveDate; 89*0Sstevel@tonic-gate static int yyHaveDay; 90*0Sstevel@tonic-gate static int yyHaveRel; 91*0Sstevel@tonic-gate static int yyHaveTime; 92*0Sstevel@tonic-gate static int yyHaveZone; 93*0Sstevel@tonic-gate static time_t yyTimezone; 94*0Sstevel@tonic-gate static time_t yyDay; 95*0Sstevel@tonic-gate static time_t yyHour; 96*0Sstevel@tonic-gate static time_t yyMinutes; 97*0Sstevel@tonic-gate static time_t yyMonth; 98*0Sstevel@tonic-gate static time_t yySeconds; 99*0Sstevel@tonic-gate static time_t yyYear; 100*0Sstevel@tonic-gate static MERIDIAN yyMeridian; 101*0Sstevel@tonic-gate static time_t yyRelMonth; 102*0Sstevel@tonic-gate static time_t yyRelSeconds; 103*0Sstevel@tonic-gate 104*0Sstevel@tonic-gate static char *domainname = "hsm_libdump"; /* for dgettext() */ 105*0Sstevel@tonic-gate 106*0Sstevel@tonic-gate #define yylex 1 /* suppress yacc's definition */ 107*0Sstevel@tonic-gate %} 108*0Sstevel@tonic-gate 109*0Sstevel@tonic-gate %union { 110*0Sstevel@tonic-gate time_t Number; 111*0Sstevel@tonic-gate enum _MERIDIAN Meridian; 112*0Sstevel@tonic-gate } 113*0Sstevel@tonic-gate 114*0Sstevel@tonic-gate %token tAGO tDAY tDAYZONE tID tMERIDIAN tMINUTE_UNIT tMONTH tMONTH_UNIT 115*0Sstevel@tonic-gate %token tSEC_UNIT tSNUMBER tUNUMBER tZONE 116*0Sstevel@tonic-gate 117*0Sstevel@tonic-gate %type <Number> tDAY tDAYZONE tMINUTE_UNIT tMONTH tMONTH_UNIT 118*0Sstevel@tonic-gate %type <Number> tSEC_UNIT tSNUMBER tUNUMBER tZONE 119*0Sstevel@tonic-gate %type <Meridian> tMERIDIAN o_merid 120*0Sstevel@tonic-gate 121*0Sstevel@tonic-gate %% 122*0Sstevel@tonic-gate 123*0Sstevel@tonic-gate spec : /* NULL */ 124*0Sstevel@tonic-gate | spec item 125*0Sstevel@tonic-gate ; 126*0Sstevel@tonic-gate 127*0Sstevel@tonic-gate item : time { 128*0Sstevel@tonic-gate yyHaveTime++; 129*0Sstevel@tonic-gate } 130*0Sstevel@tonic-gate | zone { 131*0Sstevel@tonic-gate yyHaveZone++; 132*0Sstevel@tonic-gate } 133*0Sstevel@tonic-gate | date { 134*0Sstevel@tonic-gate yyHaveDate++; 135*0Sstevel@tonic-gate } 136*0Sstevel@tonic-gate | day { 137*0Sstevel@tonic-gate yyHaveDay++; 138*0Sstevel@tonic-gate } 139*0Sstevel@tonic-gate | rel { 140*0Sstevel@tonic-gate yyHaveRel++; 141*0Sstevel@tonic-gate } 142*0Sstevel@tonic-gate | number 143*0Sstevel@tonic-gate ; 144*0Sstevel@tonic-gate 145*0Sstevel@tonic-gate time : tUNUMBER tMERIDIAN { 146*0Sstevel@tonic-gate yyHour = $1; 147*0Sstevel@tonic-gate yyMinutes = 0; 148*0Sstevel@tonic-gate yySeconds = 0; 149*0Sstevel@tonic-gate yyMeridian = $2; 150*0Sstevel@tonic-gate } 151*0Sstevel@tonic-gate | tUNUMBER ':' tUNUMBER o_merid { 152*0Sstevel@tonic-gate yyHour = $1; 153*0Sstevel@tonic-gate yyMinutes = $3; 154*0Sstevel@tonic-gate yySeconds = 0; 155*0Sstevel@tonic-gate yyMeridian = $4; 156*0Sstevel@tonic-gate } 157*0Sstevel@tonic-gate | tUNUMBER ':' tUNUMBER tSNUMBER { 158*0Sstevel@tonic-gate yyHour = $1; 159*0Sstevel@tonic-gate yyMinutes = $3; 160*0Sstevel@tonic-gate yyMeridian = MER24; 161*0Sstevel@tonic-gate yyDSTmode = DSToff; 162*0Sstevel@tonic-gate yyTimezone = - ($4 % 100 + ($4 / 100) * 60); 163*0Sstevel@tonic-gate } 164*0Sstevel@tonic-gate | tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid { 165*0Sstevel@tonic-gate yyHour = $1; 166*0Sstevel@tonic-gate yyMinutes = $3; 167*0Sstevel@tonic-gate yySeconds = $5; 168*0Sstevel@tonic-gate yyMeridian = $6; 169*0Sstevel@tonic-gate } 170*0Sstevel@tonic-gate | tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER { 171*0Sstevel@tonic-gate yyHour = $1; 172*0Sstevel@tonic-gate yyMinutes = $3; 173*0Sstevel@tonic-gate yySeconds = $5; 174*0Sstevel@tonic-gate yyMeridian = MER24; 175*0Sstevel@tonic-gate yyDSTmode = DSToff; 176*0Sstevel@tonic-gate yyTimezone = - ($6 % 100 + ($6 / 100) * 60); 177*0Sstevel@tonic-gate } 178*0Sstevel@tonic-gate ; 179*0Sstevel@tonic-gate 180*0Sstevel@tonic-gate zone : tZONE { 181*0Sstevel@tonic-gate yyTimezone = $1; 182*0Sstevel@tonic-gate yyDSTmode = DSToff; 183*0Sstevel@tonic-gate } 184*0Sstevel@tonic-gate | tDAYZONE { 185*0Sstevel@tonic-gate yyTimezone = $1; 186*0Sstevel@tonic-gate yyDSTmode = DSTon; 187*0Sstevel@tonic-gate } 188*0Sstevel@tonic-gate ; 189*0Sstevel@tonic-gate 190*0Sstevel@tonic-gate day : tDAY { 191*0Sstevel@tonic-gate yyDayOrdinal = 1; 192*0Sstevel@tonic-gate yyDayNumber = $1; 193*0Sstevel@tonic-gate } 194*0Sstevel@tonic-gate | tDAY ',' { 195*0Sstevel@tonic-gate yyDayOrdinal = 1; 196*0Sstevel@tonic-gate yyDayNumber = $1; 197*0Sstevel@tonic-gate } 198*0Sstevel@tonic-gate | tUNUMBER tDAY { 199*0Sstevel@tonic-gate yyDayOrdinal = $1; 200*0Sstevel@tonic-gate yyDayNumber = $2; 201*0Sstevel@tonic-gate } 202*0Sstevel@tonic-gate ; 203*0Sstevel@tonic-gate 204*0Sstevel@tonic-gate date : tUNUMBER '/' tUNUMBER { 205*0Sstevel@tonic-gate yyMonth = $1; 206*0Sstevel@tonic-gate yyDay = $3; 207*0Sstevel@tonic-gate } 208*0Sstevel@tonic-gate | tUNUMBER '/' tUNUMBER '/' tUNUMBER { 209*0Sstevel@tonic-gate yyMonth = $1; 210*0Sstevel@tonic-gate yyDay = $3; 211*0Sstevel@tonic-gate yyYear = $5; 212*0Sstevel@tonic-gate } 213*0Sstevel@tonic-gate | tMONTH tUNUMBER { 214*0Sstevel@tonic-gate yyMonth = $1; 215*0Sstevel@tonic-gate yyDay = $2; 216*0Sstevel@tonic-gate } 217*0Sstevel@tonic-gate | tMONTH tUNUMBER ',' tUNUMBER { 218*0Sstevel@tonic-gate yyMonth = $1; 219*0Sstevel@tonic-gate yyDay = $2; 220*0Sstevel@tonic-gate yyYear = $4; 221*0Sstevel@tonic-gate } 222*0Sstevel@tonic-gate | tUNUMBER tMONTH { 223*0Sstevel@tonic-gate yyMonth = $2; 224*0Sstevel@tonic-gate yyDay = $1; 225*0Sstevel@tonic-gate } 226*0Sstevel@tonic-gate | tUNUMBER tMONTH tUNUMBER { 227*0Sstevel@tonic-gate yyMonth = $2; 228*0Sstevel@tonic-gate yyDay = $1; 229*0Sstevel@tonic-gate yyYear = $3; 230*0Sstevel@tonic-gate } 231*0Sstevel@tonic-gate ; 232*0Sstevel@tonic-gate 233*0Sstevel@tonic-gate rel : relunit tAGO { 234*0Sstevel@tonic-gate yyRelSeconds = -yyRelSeconds; 235*0Sstevel@tonic-gate yyRelMonth = -yyRelMonth; 236*0Sstevel@tonic-gate } 237*0Sstevel@tonic-gate | relunit 238*0Sstevel@tonic-gate ; 239*0Sstevel@tonic-gate 240*0Sstevel@tonic-gate relunit : tUNUMBER tMINUTE_UNIT { 241*0Sstevel@tonic-gate yyRelSeconds += $1 * $2 * 60L; 242*0Sstevel@tonic-gate } 243*0Sstevel@tonic-gate | tSNUMBER tMINUTE_UNIT { 244*0Sstevel@tonic-gate yyRelSeconds += $1 * $2 * 60L; 245*0Sstevel@tonic-gate } 246*0Sstevel@tonic-gate | tMINUTE_UNIT { 247*0Sstevel@tonic-gate yyRelSeconds += $1 * 60L; 248*0Sstevel@tonic-gate } 249*0Sstevel@tonic-gate | tSNUMBER tSEC_UNIT { 250*0Sstevel@tonic-gate yyRelSeconds += $1; 251*0Sstevel@tonic-gate } 252*0Sstevel@tonic-gate | tUNUMBER tSEC_UNIT { 253*0Sstevel@tonic-gate yyRelSeconds += $1; 254*0Sstevel@tonic-gate } 255*0Sstevel@tonic-gate | tSEC_UNIT { 256*0Sstevel@tonic-gate yyRelSeconds++; 257*0Sstevel@tonic-gate } 258*0Sstevel@tonic-gate | tSNUMBER tMONTH_UNIT { 259*0Sstevel@tonic-gate yyRelMonth += $1 * $2; 260*0Sstevel@tonic-gate } 261*0Sstevel@tonic-gate | tUNUMBER tMONTH_UNIT { 262*0Sstevel@tonic-gate yyRelMonth += $1 * $2; 263*0Sstevel@tonic-gate } 264*0Sstevel@tonic-gate | tMONTH_UNIT { 265*0Sstevel@tonic-gate yyRelMonth += $1; 266*0Sstevel@tonic-gate } 267*0Sstevel@tonic-gate ; 268*0Sstevel@tonic-gate 269*0Sstevel@tonic-gate number : tUNUMBER { 270*0Sstevel@tonic-gate if (yyHaveTime && yyHaveDate && !yyHaveRel) 271*0Sstevel@tonic-gate yyYear = $1; 272*0Sstevel@tonic-gate else { 273*0Sstevel@tonic-gate yyHaveTime++; 274*0Sstevel@tonic-gate if ($1 < 100) { 275*0Sstevel@tonic-gate yyHour = $1; 276*0Sstevel@tonic-gate yyMinutes = 0; 277*0Sstevel@tonic-gate } 278*0Sstevel@tonic-gate else { 279*0Sstevel@tonic-gate yyHour = $1 / 100; 280*0Sstevel@tonic-gate yyMinutes = $1 % 100; 281*0Sstevel@tonic-gate } 282*0Sstevel@tonic-gate yySeconds = 0; 283*0Sstevel@tonic-gate yyMeridian = MER24; 284*0Sstevel@tonic-gate } 285*0Sstevel@tonic-gate } 286*0Sstevel@tonic-gate ; 287*0Sstevel@tonic-gate 288*0Sstevel@tonic-gate o_merid : /* NULL */ { 289*0Sstevel@tonic-gate $$ = MER24; 290*0Sstevel@tonic-gate } 291*0Sstevel@tonic-gate | tMERIDIAN { 292*0Sstevel@tonic-gate $$ = $1; 293*0Sstevel@tonic-gate } 294*0Sstevel@tonic-gate ; 295*0Sstevel@tonic-gate 296*0Sstevel@tonic-gate %% 297*0Sstevel@tonic-gate 298*0Sstevel@tonic-gate /* Month and day table. */ 299*0Sstevel@tonic-gate static TABLE MonthDayTable[] = { 300*0Sstevel@tonic-gate { "january", tMONTH, 1 }, 301*0Sstevel@tonic-gate { "february", tMONTH, 2 }, 302*0Sstevel@tonic-gate { "march", tMONTH, 3 }, 303*0Sstevel@tonic-gate { "april", tMONTH, 4 }, 304*0Sstevel@tonic-gate { "may", tMONTH, 5 }, 305*0Sstevel@tonic-gate { "june", tMONTH, 6 }, 306*0Sstevel@tonic-gate { "july", tMONTH, 7 }, 307*0Sstevel@tonic-gate { "august", tMONTH, 8 }, 308*0Sstevel@tonic-gate { "september", tMONTH, 9 }, 309*0Sstevel@tonic-gate { "sept", tMONTH, 9 }, 310*0Sstevel@tonic-gate { "october", tMONTH, 10 }, 311*0Sstevel@tonic-gate { "november", tMONTH, 11 }, 312*0Sstevel@tonic-gate { "december", tMONTH, 12 }, 313*0Sstevel@tonic-gate { "sunday", tDAY, 0 }, 314*0Sstevel@tonic-gate { "monday", tDAY, 1 }, 315*0Sstevel@tonic-gate { "tuesday", tDAY, 2 }, 316*0Sstevel@tonic-gate { "tues", tDAY, 2 }, 317*0Sstevel@tonic-gate { "wednesday", tDAY, 3 }, 318*0Sstevel@tonic-gate { "wednes", tDAY, 3 }, 319*0Sstevel@tonic-gate { "thursday", tDAY, 4 }, 320*0Sstevel@tonic-gate { "thur", tDAY, 4 }, 321*0Sstevel@tonic-gate { "thurs", tDAY, 4 }, 322*0Sstevel@tonic-gate { "friday", tDAY, 5 }, 323*0Sstevel@tonic-gate { "saturday", tDAY, 6 }, 324*0Sstevel@tonic-gate { NULL } 325*0Sstevel@tonic-gate }; 326*0Sstevel@tonic-gate 327*0Sstevel@tonic-gate /* Time units table. */ 328*0Sstevel@tonic-gate static TABLE UnitsTable[] = { 329*0Sstevel@tonic-gate { "year", tMONTH_UNIT, 12 }, 330*0Sstevel@tonic-gate { "month", tMONTH_UNIT, 1 }, 331*0Sstevel@tonic-gate { "fortnight", tMINUTE_UNIT, 14 * 24 * 60 }, 332*0Sstevel@tonic-gate { "week", tMINUTE_UNIT, 7 * 24 * 60 }, 333*0Sstevel@tonic-gate { "day", tMINUTE_UNIT, 1 * 24 * 60 }, 334*0Sstevel@tonic-gate { "hour", tMINUTE_UNIT, 60 }, 335*0Sstevel@tonic-gate { "minute", tMINUTE_UNIT, 1 }, 336*0Sstevel@tonic-gate { "min", tMINUTE_UNIT, 1 }, 337*0Sstevel@tonic-gate { "second", tSEC_UNIT, 1 }, 338*0Sstevel@tonic-gate { "sec", tSEC_UNIT, 1 }, 339*0Sstevel@tonic-gate { NULL } 340*0Sstevel@tonic-gate }; 341*0Sstevel@tonic-gate 342*0Sstevel@tonic-gate /* Assorted relative-time words. */ 343*0Sstevel@tonic-gate static TABLE OtherTable[] = { 344*0Sstevel@tonic-gate { "tomorrow", tMINUTE_UNIT, 1 * 24 * 60 }, 345*0Sstevel@tonic-gate { "yesterday", tMINUTE_UNIT, -1 * 24 * 60 }, 346*0Sstevel@tonic-gate { "today", tMINUTE_UNIT, 0 }, 347*0Sstevel@tonic-gate { "now", tMINUTE_UNIT, 0 }, 348*0Sstevel@tonic-gate { "last", tUNUMBER, -1 }, 349*0Sstevel@tonic-gate { "this", tMINUTE_UNIT, 0 }, 350*0Sstevel@tonic-gate { "next", tUNUMBER, 2 }, 351*0Sstevel@tonic-gate { "first", tUNUMBER, 1 }, 352*0Sstevel@tonic-gate /* { "second", tUNUMBER, 2 }, */ 353*0Sstevel@tonic-gate { "third", tUNUMBER, 3 }, 354*0Sstevel@tonic-gate { "fourth", tUNUMBER, 4 }, 355*0Sstevel@tonic-gate { "fifth", tUNUMBER, 5 }, 356*0Sstevel@tonic-gate { "sixth", tUNUMBER, 6 }, 357*0Sstevel@tonic-gate { "seventh", tUNUMBER, 7 }, 358*0Sstevel@tonic-gate { "eighth", tUNUMBER, 8 }, 359*0Sstevel@tonic-gate { "ninth", tUNUMBER, 9 }, 360*0Sstevel@tonic-gate { "tenth", tUNUMBER, 10 }, 361*0Sstevel@tonic-gate { "eleventh", tUNUMBER, 11 }, 362*0Sstevel@tonic-gate { "twelfth", tUNUMBER, 12 }, 363*0Sstevel@tonic-gate { "ago", tAGO, 1 }, 364*0Sstevel@tonic-gate { NULL } 365*0Sstevel@tonic-gate }; 366*0Sstevel@tonic-gate 367*0Sstevel@tonic-gate /* The timezone table. */ 368*0Sstevel@tonic-gate static TABLE TimezoneTable[] = { 369*0Sstevel@tonic-gate { "gmt", tZONE, HOURN( 0) }, /* Greenwich Mean */ 370*0Sstevel@tonic-gate { "ut", tZONE, HOURN( 0) }, /* Universal (Coordinated) */ 371*0Sstevel@tonic-gate { "utc", tZONE, HOURN( 0) }, 372*0Sstevel@tonic-gate { "wet", tZONE, HOURN( 0) }, /* Western European */ 373*0Sstevel@tonic-gate { "bst", tDAYZONE, HOURN( 0) }, /* British Summer */ 374*0Sstevel@tonic-gate { "wat", tZONE, HOURN( 1) }, /* West Africa */ 375*0Sstevel@tonic-gate { "at", tZONE, HOURN( 2) }, /* Azores */ 376*0Sstevel@tonic-gate #if 0 377*0Sstevel@tonic-gate /* For completeness. BST is also British Summer, and GST is 378*0Sstevel@tonic-gate * also Guam Standard. */ 379*0Sstevel@tonic-gate { "bst", tZONE, HOURN( 3) }, /* Brazil Standard */ 380*0Sstevel@tonic-gate { "gst", tZONE, HOURN( 3) }, /* Greenland Standard */ 381*0Sstevel@tonic-gate #endif 382*0Sstevel@tonic-gate { "nft", tZONE, HOURN(3.5) }, /* Newfoundland */ 383*0Sstevel@tonic-gate { "nst", tZONE, HOURN(3.5) }, /* Newfoundland Standard */ 384*0Sstevel@tonic-gate { "ndt", tDAYZONE, HOURN(3.5) }, /* Newfoundland Daylight */ 385*0Sstevel@tonic-gate { "ast", tZONE, HOURN( 4) }, /* Atlantic Standard */ 386*0Sstevel@tonic-gate { "adt", tDAYZONE, HOURN( 4) }, /* Atlantic Daylight */ 387*0Sstevel@tonic-gate { "est", tZONE, HOURN( 5) }, /* Eastern Standard */ 388*0Sstevel@tonic-gate { "edt", tDAYZONE, HOURN( 5) }, /* Eastern Daylight */ 389*0Sstevel@tonic-gate { "cst", tZONE, HOURN( 6) }, /* Central Standard */ 390*0Sstevel@tonic-gate { "cdt", tDAYZONE, HOURN( 6) }, /* Central Daylight */ 391*0Sstevel@tonic-gate { "mst", tZONE, HOURN( 7) }, /* Mountain Standard */ 392*0Sstevel@tonic-gate { "mdt", tDAYZONE, HOURN( 7) }, /* Mountain Daylight */ 393*0Sstevel@tonic-gate { "pst", tZONE, HOURN( 8) }, /* Pacific Standard */ 394*0Sstevel@tonic-gate { "pdt", tDAYZONE, HOURN( 8) }, /* Pacific Daylight */ 395*0Sstevel@tonic-gate { "yst", tZONE, HOURN( 9) }, /* Yukon Standard */ 396*0Sstevel@tonic-gate { "ydt", tDAYZONE, HOURN( 9) }, /* Yukon Daylight */ 397*0Sstevel@tonic-gate { "hst", tZONE, HOURN(10) }, /* Hawaii Standard */ 398*0Sstevel@tonic-gate { "hdt", tDAYZONE, HOURN(10) }, /* Hawaii Daylight */ 399*0Sstevel@tonic-gate { "cat", tZONE, HOURN(10) }, /* Central Alaska */ 400*0Sstevel@tonic-gate { "ahst", tZONE, HOURN(10) }, /* Alaska-Hawaii Standard */ 401*0Sstevel@tonic-gate { "nt", tZONE, HOURN(11) }, /* Nome */ 402*0Sstevel@tonic-gate { "idlw", tZONE, HOURN(12) }, /* International Date Line West */ 403*0Sstevel@tonic-gate { "cet", tZONE, -HOURN(1) }, /* Central European */ 404*0Sstevel@tonic-gate { "met", tZONE, -HOURN(1) }, /* Middle European */ 405*0Sstevel@tonic-gate { "mewt", tZONE, -HOURN(1) }, /* Middle European Winter */ 406*0Sstevel@tonic-gate { "mest", tDAYZONE, -HOURN(1) }, /* Middle European Summer */ 407*0Sstevel@tonic-gate { "swt", tZONE, -HOURN(1) }, /* Swedish Winter */ 408*0Sstevel@tonic-gate { "sst", tDAYZONE, -HOURN(1) }, /* Swedish Summer */ 409*0Sstevel@tonic-gate { "fwt", tZONE, -HOURN(1) }, /* French Winter */ 410*0Sstevel@tonic-gate { "fst", tDAYZONE, -HOURN(1) }, /* French Summer */ 411*0Sstevel@tonic-gate { "eet", tZONE, -HOURN(2) }, /* Eastern Europe, USSR Zone 1 */ 412*0Sstevel@tonic-gate { "bt", tZONE, -HOURN(3) }, /* Baghdad, USSR Zone 2 */ 413*0Sstevel@tonic-gate { "it", tZONE, -HOURN(3.5) },/* Iran */ 414*0Sstevel@tonic-gate { "zp4", tZONE, -HOURN(4) }, /* USSR Zone 3 */ 415*0Sstevel@tonic-gate { "zp5", tZONE, -HOURN(5) }, /* USSR Zone 4 */ 416*0Sstevel@tonic-gate { "ist", tZONE, -HOURN(5.5) },/* Indian Standard */ 417*0Sstevel@tonic-gate { "zp6", tZONE, -HOURN(6) }, /* USSR Zone 5 */ 418*0Sstevel@tonic-gate #if 0 419*0Sstevel@tonic-gate /* For completeness. NST is also Newfoundland Stanard, nad SST is 420*0Sstevel@tonic-gate * also Swedish Summer. */ 421*0Sstevel@tonic-gate { "nst", tZONE, -HOURN(6.5) },/* North Sumatra */ 422*0Sstevel@tonic-gate { "sst", tZONE, -HOURN(7) }, /* South Sumatra, USSR Zone 6 */ 423*0Sstevel@tonic-gate #endif /* 0 */ 424*0Sstevel@tonic-gate { "wast", tZONE, -HOURN(7) }, /* West Australian Standard */ 425*0Sstevel@tonic-gate { "wadt", tDAYZONE, -HOURN(7) }, /* West Australian Daylight */ 426*0Sstevel@tonic-gate { "jt", tZONE, -HOURN(7.5) },/* Java (3pm in Cronusland!) */ 427*0Sstevel@tonic-gate { "cct", tZONE, -HOURN(8) }, /* China Coast, USSR Zone 7 */ 428*0Sstevel@tonic-gate { "jst", tZONE, -HOURN(9) }, /* Japan Standard, USSR Zone 8 */ 429*0Sstevel@tonic-gate { "cast", tZONE, -HOURN(9.5) },/* Central Australian Standard */ 430*0Sstevel@tonic-gate { "cadt", tDAYZONE, -HOURN(9.5) },/* Central Australian Daylight */ 431*0Sstevel@tonic-gate { "east", tZONE, -HOURN(10) }, /* Eastern Australian Standard */ 432*0Sstevel@tonic-gate { "eadt", tDAYZONE, -HOURN(10) }, /* Eastern Australian Daylight */ 433*0Sstevel@tonic-gate { "gst", tZONE, -HOURN(10) }, /* Guam Standard, USSR Zone 9 */ 434*0Sstevel@tonic-gate { "nzt", tZONE, -HOURN(12) }, /* New Zealand */ 435*0Sstevel@tonic-gate { "nzst", tZONE, -HOURN(12) }, /* New Zealand Standard */ 436*0Sstevel@tonic-gate { "nzdt", tDAYZONE, -HOURN(12) }, /* New Zealand Daylight */ 437*0Sstevel@tonic-gate { "idle", tZONE, -HOURN(12) }, /* International Date Line East */ 438*0Sstevel@tonic-gate { NULL } 439*0Sstevel@tonic-gate }; 440*0Sstevel@tonic-gate 441*0Sstevel@tonic-gate /* Military timezone table. */ 442*0Sstevel@tonic-gate static TABLE MilitaryTable[] = { 443*0Sstevel@tonic-gate { "a", tZONE, HOURN( 1) }, 444*0Sstevel@tonic-gate { "b", tZONE, HOURN( 2) }, 445*0Sstevel@tonic-gate { "c", tZONE, HOURN( 3) }, 446*0Sstevel@tonic-gate { "d", tZONE, HOURN( 4) }, 447*0Sstevel@tonic-gate { "e", tZONE, HOURN( 5) }, 448*0Sstevel@tonic-gate { "f", tZONE, HOURN( 6) }, 449*0Sstevel@tonic-gate { "g", tZONE, HOURN( 7) }, 450*0Sstevel@tonic-gate { "h", tZONE, HOURN( 8) }, 451*0Sstevel@tonic-gate { "i", tZONE, HOURN( 9) }, 452*0Sstevel@tonic-gate { "k", tZONE, HOURN( 10) }, 453*0Sstevel@tonic-gate { "l", tZONE, HOURN( 11) }, 454*0Sstevel@tonic-gate { "m", tZONE, HOURN( 12) }, 455*0Sstevel@tonic-gate { "n", tZONE, HOURN(- 1) }, 456*0Sstevel@tonic-gate { "o", tZONE, HOURN(- 2) }, 457*0Sstevel@tonic-gate { "p", tZONE, HOURN(- 3) }, 458*0Sstevel@tonic-gate { "q", tZONE, HOURN(- 4) }, 459*0Sstevel@tonic-gate { "r", tZONE, HOURN(- 5) }, 460*0Sstevel@tonic-gate { "s", tZONE, HOURN(- 6) }, 461*0Sstevel@tonic-gate { "t", tZONE, HOURN(- 7) }, 462*0Sstevel@tonic-gate { "u", tZONE, HOURN(- 8) }, 463*0Sstevel@tonic-gate { "v", tZONE, HOURN(- 9) }, 464*0Sstevel@tonic-gate { "w", tZONE, HOURN(-10) }, 465*0Sstevel@tonic-gate { "x", tZONE, HOURN(-11) }, 466*0Sstevel@tonic-gate { "y", tZONE, HOURN(-12) }, 467*0Sstevel@tonic-gate { "z", tZONE, HOURN( 0) }, 468*0Sstevel@tonic-gate { NULL } 469*0Sstevel@tonic-gate }; 470*0Sstevel@tonic-gate 471*0Sstevel@tonic-gate 472*0Sstevel@tonic-gate 473*0Sstevel@tonic-gate 474*0Sstevel@tonic-gate /* ARGSUSED */ 475*0Sstevel@tonic-gate static void 476*0Sstevel@tonic-gate yyerror(s) 477*0Sstevel@tonic-gate char *s; 478*0Sstevel@tonic-gate { 479*0Sstevel@tonic-gate } 480*0Sstevel@tonic-gate 481*0Sstevel@tonic-gate 482*0Sstevel@tonic-gate static time_t 483*0Sstevel@tonic-gate ToSeconds(Hours, Minutes, Seconds, Meridian) 484*0Sstevel@tonic-gate time_t Hours; 485*0Sstevel@tonic-gate time_t Minutes; 486*0Sstevel@tonic-gate time_t Seconds; 487*0Sstevel@tonic-gate MERIDIAN Meridian; 488*0Sstevel@tonic-gate { 489*0Sstevel@tonic-gate if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59) 490*0Sstevel@tonic-gate return -1; 491*0Sstevel@tonic-gate switch (Meridian) { 492*0Sstevel@tonic-gate case MER24: 493*0Sstevel@tonic-gate if (Hours < 0 || Hours > 23) 494*0Sstevel@tonic-gate return -1; 495*0Sstevel@tonic-gate return (Hours * 60L + Minutes) * 60L + Seconds; 496*0Sstevel@tonic-gate case MERam: 497*0Sstevel@tonic-gate if (Hours < 1 || Hours > 12) 498*0Sstevel@tonic-gate return -1; 499*0Sstevel@tonic-gate if (Hours != 12) 500*0Sstevel@tonic-gate return (Hours * 60L + Minutes) * 60L + Seconds; 501*0Sstevel@tonic-gate else 502*0Sstevel@tonic-gate return Minutes * 60L + Seconds; 503*0Sstevel@tonic-gate case MERpm: 504*0Sstevel@tonic-gate if (Hours < 1 || Hours > 12) 505*0Sstevel@tonic-gate return -1; 506*0Sstevel@tonic-gate if (Hours != 12) 507*0Sstevel@tonic-gate return ((Hours + 12) * 60L + Minutes) * 60L + Seconds; 508*0Sstevel@tonic-gate else 509*0Sstevel@tonic-gate return (720L + Minutes) * 60L + Seconds; 510*0Sstevel@tonic-gate } 511*0Sstevel@tonic-gate /* NOTREACHED */ 512*0Sstevel@tonic-gate } 513*0Sstevel@tonic-gate 514*0Sstevel@tonic-gate 515*0Sstevel@tonic-gate static time_t 516*0Sstevel@tonic-gate Convert(Month, Day, Year, Hours, Minutes, Seconds, Meridian, DSTmode) 517*0Sstevel@tonic-gate time_t Month; 518*0Sstevel@tonic-gate time_t Day; 519*0Sstevel@tonic-gate time_t Year; 520*0Sstevel@tonic-gate time_t Hours; 521*0Sstevel@tonic-gate time_t Minutes; 522*0Sstevel@tonic-gate time_t Seconds; 523*0Sstevel@tonic-gate MERIDIAN Meridian; 524*0Sstevel@tonic-gate DSTMODE DSTmode; 525*0Sstevel@tonic-gate { 526*0Sstevel@tonic-gate static int DaysInMonth[12] = { 527*0Sstevel@tonic-gate 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 528*0Sstevel@tonic-gate }; 529*0Sstevel@tonic-gate time_t tod; 530*0Sstevel@tonic-gate time_t Julian; 531*0Sstevel@tonic-gate time_t i; 532*0Sstevel@tonic-gate 533*0Sstevel@tonic-gate if (Year < 0) 534*0Sstevel@tonic-gate Year = -Year; 535*0Sstevel@tonic-gate if (Year < 138) 536*0Sstevel@tonic-gate Year += 1900; 537*0Sstevel@tonic-gate DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0) 538*0Sstevel@tonic-gate ? 29 : 28; 539*0Sstevel@tonic-gate if (Year < EPOCH || Year > 2037 540*0Sstevel@tonic-gate || Month < 1 || Month > 12 541*0Sstevel@tonic-gate /* LINTED Month is a time_t so intermediate results aren't truncated */ 542*0Sstevel@tonic-gate || Day < 1 || Day > DaysInMonth[(int)--Month]) 543*0Sstevel@tonic-gate return -1; 544*0Sstevel@tonic-gate 545*0Sstevel@tonic-gate for (Julian = Day - 1, i = 0; i < Month; i++) 546*0Sstevel@tonic-gate Julian += DaysInMonth[i]; 547*0Sstevel@tonic-gate for (i = EPOCH; i < Year; i++) 548*0Sstevel@tonic-gate Julian += 365 + (i % 4 == 0); 549*0Sstevel@tonic-gate Julian *= SECSPERDAY; 550*0Sstevel@tonic-gate Julian += yyTimezone * 60L; 551*0Sstevel@tonic-gate if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0) 552*0Sstevel@tonic-gate return -1; 553*0Sstevel@tonic-gate Julian += tod; 554*0Sstevel@tonic-gate if (DSTmode == DSTon 555*0Sstevel@tonic-gate || (DSTmode == DSTmaybe && localtime(&Julian)->tm_isdst)) 556*0Sstevel@tonic-gate Julian -= 60 * 60; 557*0Sstevel@tonic-gate return Julian; 558*0Sstevel@tonic-gate } 559*0Sstevel@tonic-gate 560*0Sstevel@tonic-gate 561*0Sstevel@tonic-gate static time_t 562*0Sstevel@tonic-gate DSTcorrect(Start, Future) 563*0Sstevel@tonic-gate time_t Start; 564*0Sstevel@tonic-gate time_t Future; 565*0Sstevel@tonic-gate { 566*0Sstevel@tonic-gate time_t StartDay; 567*0Sstevel@tonic-gate time_t FutureDay; 568*0Sstevel@tonic-gate 569*0Sstevel@tonic-gate StartDay = (localtime(&Start)->tm_hour + 1) % 24; 570*0Sstevel@tonic-gate FutureDay = (localtime(&Future)->tm_hour + 1) % 24; 571*0Sstevel@tonic-gate return (Future - Start) + (StartDay - FutureDay) * 60L * 60L; 572*0Sstevel@tonic-gate } 573*0Sstevel@tonic-gate 574*0Sstevel@tonic-gate 575*0Sstevel@tonic-gate static time_t 576*0Sstevel@tonic-gate RelativeDate(Start, DayOrdinal, DayNumber) 577*0Sstevel@tonic-gate time_t Start; 578*0Sstevel@tonic-gate time_t DayOrdinal; 579*0Sstevel@tonic-gate time_t DayNumber; 580*0Sstevel@tonic-gate { 581*0Sstevel@tonic-gate struct tm *tm; 582*0Sstevel@tonic-gate time_t now; 583*0Sstevel@tonic-gate 584*0Sstevel@tonic-gate now = Start; 585*0Sstevel@tonic-gate tm = localtime(&now); 586*0Sstevel@tonic-gate now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7); 587*0Sstevel@tonic-gate now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1); 588*0Sstevel@tonic-gate return DSTcorrect(Start, now); 589*0Sstevel@tonic-gate } 590*0Sstevel@tonic-gate 591*0Sstevel@tonic-gate 592*0Sstevel@tonic-gate static time_t 593*0Sstevel@tonic-gate RelativeMonth(Start, RelMonth) 594*0Sstevel@tonic-gate time_t Start; 595*0Sstevel@tonic-gate time_t RelMonth; 596*0Sstevel@tonic-gate { 597*0Sstevel@tonic-gate struct tm *tm; 598*0Sstevel@tonic-gate time_t Month; 599*0Sstevel@tonic-gate time_t Year; 600*0Sstevel@tonic-gate 601*0Sstevel@tonic-gate if (RelMonth == 0) 602*0Sstevel@tonic-gate return 0; 603*0Sstevel@tonic-gate tm = localtime(&Start); 604*0Sstevel@tonic-gate Month = 12 * tm->tm_year + tm->tm_mon + RelMonth; 605*0Sstevel@tonic-gate Year = Month / 12; 606*0Sstevel@tonic-gate Month = Month % 12 + 1; 607*0Sstevel@tonic-gate return DSTcorrect(Start, 608*0Sstevel@tonic-gate Convert(Month, (time_t)tm->tm_mday, Year, 609*0Sstevel@tonic-gate (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec, 610*0Sstevel@tonic-gate MER24, DSTmaybe)); 611*0Sstevel@tonic-gate } 612*0Sstevel@tonic-gate 613*0Sstevel@tonic-gate 614*0Sstevel@tonic-gate static int 615*0Sstevel@tonic-gate LookupWord(buff) 616*0Sstevel@tonic-gate char *buff; 617*0Sstevel@tonic-gate { 618*0Sstevel@tonic-gate char *p; 619*0Sstevel@tonic-gate char *q; 620*0Sstevel@tonic-gate TABLE *tp; 621*0Sstevel@tonic-gate uint_t i; 622*0Sstevel@tonic-gate int abbrev; 623*0Sstevel@tonic-gate 624*0Sstevel@tonic-gate /* Make it lowercase. */ 625*0Sstevel@tonic-gate for (p = buff; *p; p++) 626*0Sstevel@tonic-gate if (isupper((u_char)*p)) 627*0Sstevel@tonic-gate *p = tolower(*p); 628*0Sstevel@tonic-gate 629*0Sstevel@tonic-gate if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) { 630*0Sstevel@tonic-gate yylval.Meridian = MERam; 631*0Sstevel@tonic-gate return tMERIDIAN; 632*0Sstevel@tonic-gate } 633*0Sstevel@tonic-gate if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) { 634*0Sstevel@tonic-gate yylval.Meridian = MERpm; 635*0Sstevel@tonic-gate return tMERIDIAN; 636*0Sstevel@tonic-gate } 637*0Sstevel@tonic-gate 638*0Sstevel@tonic-gate /* See if we have an abbreviation for a month. */ 639*0Sstevel@tonic-gate if (strlen(buff) == 3) 640*0Sstevel@tonic-gate abbrev = 1; 641*0Sstevel@tonic-gate else if (strlen(buff) == 4 && buff[3] == '.') { 642*0Sstevel@tonic-gate abbrev = 1; 643*0Sstevel@tonic-gate buff[3] = '\0'; 644*0Sstevel@tonic-gate } 645*0Sstevel@tonic-gate else 646*0Sstevel@tonic-gate abbrev = 0; 647*0Sstevel@tonic-gate 648*0Sstevel@tonic-gate for (tp = MonthDayTable; tp->name; tp++) { 649*0Sstevel@tonic-gate if (abbrev) { 650*0Sstevel@tonic-gate if (strncmp(buff, tp->name, 3) == 0) { 651*0Sstevel@tonic-gate yylval.Number = tp->value; 652*0Sstevel@tonic-gate return tp->type; 653*0Sstevel@tonic-gate } 654*0Sstevel@tonic-gate } 655*0Sstevel@tonic-gate else if (strcmp(buff, tp->name) == 0) { 656*0Sstevel@tonic-gate yylval.Number = tp->value; 657*0Sstevel@tonic-gate return tp->type; 658*0Sstevel@tonic-gate } 659*0Sstevel@tonic-gate } 660*0Sstevel@tonic-gate 661*0Sstevel@tonic-gate for (tp = TimezoneTable; tp->name; tp++) 662*0Sstevel@tonic-gate if (strcmp(buff, tp->name) == 0) { 663*0Sstevel@tonic-gate yylval.Number = tp->value; 664*0Sstevel@tonic-gate return tp->type; 665*0Sstevel@tonic-gate } 666*0Sstevel@tonic-gate 667*0Sstevel@tonic-gate for (tp = UnitsTable; tp->name; tp++) 668*0Sstevel@tonic-gate if (strcmp(buff, tp->name) == 0) { 669*0Sstevel@tonic-gate yylval.Number = tp->value; 670*0Sstevel@tonic-gate return tp->type; 671*0Sstevel@tonic-gate } 672*0Sstevel@tonic-gate 673*0Sstevel@tonic-gate /* Strip off any plural and try the units table again. */ 674*0Sstevel@tonic-gate i = strlen(buff) - 1; 675*0Sstevel@tonic-gate if (buff[i] == 's') { 676*0Sstevel@tonic-gate buff[i] = '\0'; 677*0Sstevel@tonic-gate for (tp = UnitsTable; tp->name; tp++) 678*0Sstevel@tonic-gate if (strcmp(buff, tp->name) == 0) { 679*0Sstevel@tonic-gate yylval.Number = tp->value; 680*0Sstevel@tonic-gate return tp->type; 681*0Sstevel@tonic-gate } 682*0Sstevel@tonic-gate } 683*0Sstevel@tonic-gate 684*0Sstevel@tonic-gate for (tp = OtherTable; tp->name; tp++) 685*0Sstevel@tonic-gate if (strcmp(buff, tp->name) == 0) { 686*0Sstevel@tonic-gate yylval.Number = tp->value; 687*0Sstevel@tonic-gate return tp->type; 688*0Sstevel@tonic-gate } 689*0Sstevel@tonic-gate 690*0Sstevel@tonic-gate /* Military timezones. */ 691*0Sstevel@tonic-gate if (buff[1] == '\0' && isalpha((u_char)*buff)) { 692*0Sstevel@tonic-gate for (tp = MilitaryTable; tp->name; tp++) 693*0Sstevel@tonic-gate if (strcmp(buff, tp->name) == 0) { 694*0Sstevel@tonic-gate yylval.Number = tp->value; 695*0Sstevel@tonic-gate return tp->type; 696*0Sstevel@tonic-gate } 697*0Sstevel@tonic-gate } 698*0Sstevel@tonic-gate 699*0Sstevel@tonic-gate /* Drop out any periods and try the timezone table again. */ 700*0Sstevel@tonic-gate for (i = 0, p = q = buff; *q; q++) 701*0Sstevel@tonic-gate if (*q != '.') 702*0Sstevel@tonic-gate *p++ = *q; 703*0Sstevel@tonic-gate else 704*0Sstevel@tonic-gate i++; 705*0Sstevel@tonic-gate *p = '\0'; 706*0Sstevel@tonic-gate if (i) 707*0Sstevel@tonic-gate for (tp = TimezoneTable; tp->name; tp++) 708*0Sstevel@tonic-gate if (strcmp(buff, tp->name) == 0) { 709*0Sstevel@tonic-gate yylval.Number = tp->value; 710*0Sstevel@tonic-gate return tp->type; 711*0Sstevel@tonic-gate } 712*0Sstevel@tonic-gate 713*0Sstevel@tonic-gate return tID; 714*0Sstevel@tonic-gate } 715*0Sstevel@tonic-gate 716*0Sstevel@tonic-gate void 717*0Sstevel@tonic-gate pdateerr(p) 718*0Sstevel@tonic-gate char *p; 719*0Sstevel@tonic-gate { 720*0Sstevel@tonic-gate char *name = "DATEMSK"; /* env variable for date format */ 721*0Sstevel@tonic-gate char *value; 722*0Sstevel@tonic-gate char fmt[256], line[256]; 723*0Sstevel@tonic-gate FILE *fp; 724*0Sstevel@tonic-gate time_t now; 725*0Sstevel@tonic-gate struct tm *tm; 726*0Sstevel@tonic-gate 727*0Sstevel@tonic-gate value = getenv(name); 728*0Sstevel@tonic-gate if (value == (char *)0) { 729*0Sstevel@tonic-gate fprintf(stderr, 730*0Sstevel@tonic-gate dgettext(domainname, "%s: Environment variable %s not set\n"), 731*0Sstevel@tonic-gate p, name); 732*0Sstevel@tonic-gate return; 733*0Sstevel@tonic-gate } 734*0Sstevel@tonic-gate switch (getdate_err) { 735*0Sstevel@tonic-gate case 0: 736*0Sstevel@tonic-gate default: 737*0Sstevel@tonic-gate fprintf(stderr, 738*0Sstevel@tonic-gate dgettext(domainname, "%s: Unkown getdate() error\n"), p); 739*0Sstevel@tonic-gate break; 740*0Sstevel@tonic-gate case 1: 741*0Sstevel@tonic-gate fprintf(stderr, 742*0Sstevel@tonic-gate dgettext(domainname, "%s: %s null or undefined\n"), p, name); 743*0Sstevel@tonic-gate break; 744*0Sstevel@tonic-gate case 2: 745*0Sstevel@tonic-gate fprintf(stderr, dgettext(domainname, 746*0Sstevel@tonic-gate "%s: Cannot read template file %s\n"), p, value); 747*0Sstevel@tonic-gate break; 748*0Sstevel@tonic-gate case 3: 749*0Sstevel@tonic-gate fprintf(stderr, dgettext(domainname, 750*0Sstevel@tonic-gate "%s: Failed to get file status information\n"), p); 751*0Sstevel@tonic-gate break; 752*0Sstevel@tonic-gate case 4: 753*0Sstevel@tonic-gate fprintf(stderr, dgettext(domainname, 754*0Sstevel@tonic-gate "%s: Template file %s not a regular file\n"), p, value); 755*0Sstevel@tonic-gate break; 756*0Sstevel@tonic-gate case 5: 757*0Sstevel@tonic-gate fprintf(stderr, dgettext(domainname, 758*0Sstevel@tonic-gate "%s: Error reading template file %s\n"), p, value); 759*0Sstevel@tonic-gate break; 760*0Sstevel@tonic-gate case 6: 761*0Sstevel@tonic-gate fprintf(stderr, dgettext(domainname, 762*0Sstevel@tonic-gate "%s: %s failed\n"), p, "malloc()"); 763*0Sstevel@tonic-gate break; 764*0Sstevel@tonic-gate case 7: 765*0Sstevel@tonic-gate fprintf(stderr, dgettext(domainname, 766*0Sstevel@tonic-gate "%s: Bad date/time format\n"), p); 767*0Sstevel@tonic-gate fp = fopen(value, "r"); 768*0Sstevel@tonic-gate if (fp == (FILE *)0) 769*0Sstevel@tonic-gate break; 770*0Sstevel@tonic-gate now = time((time_t *)0); 771*0Sstevel@tonic-gate tm = localtime(&now); 772*0Sstevel@tonic-gate fprintf(stderr, dgettext(domainname, 773*0Sstevel@tonic-gate "The following are examples of valid formats:\n")); 774*0Sstevel@tonic-gate while (fgets(fmt, sizeof (fmt), fp)) { 775*0Sstevel@tonic-gate if (strchr(fmt, '%') == (char *)0) 776*0Sstevel@tonic-gate continue; 777*0Sstevel@tonic-gate fprintf(stderr, " "); 778*0Sstevel@tonic-gate (void) strftime(line, sizeof (line), fmt, tm); 779*0Sstevel@tonic-gate fprintf(stderr, "%s", line); 780*0Sstevel@tonic-gate } 781*0Sstevel@tonic-gate (void) fclose(fp); 782*0Sstevel@tonic-gate break; 783*0Sstevel@tonic-gate case 8: 784*0Sstevel@tonic-gate (void) fprintf(stderr, dgettext(domainname, 785*0Sstevel@tonic-gate "%s: Invalid date specification\n"), p); 786*0Sstevel@tonic-gate break; 787*0Sstevel@tonic-gate } 788*0Sstevel@tonic-gate } 789*0Sstevel@tonic-gate 790*0Sstevel@tonic-gate #undef yylex 791*0Sstevel@tonic-gate static int 792*0Sstevel@tonic-gate yylex() 793*0Sstevel@tonic-gate { 794*0Sstevel@tonic-gate char c; 795*0Sstevel@tonic-gate char *p; 796*0Sstevel@tonic-gate char buff[20]; 797*0Sstevel@tonic-gate int Count; 798*0Sstevel@tonic-gate int sign; 799*0Sstevel@tonic-gate 800*0Sstevel@tonic-gate for ( ; ; ) { 801*0Sstevel@tonic-gate while (isspace((u_char)*yyInput)) 802*0Sstevel@tonic-gate yyInput++; 803*0Sstevel@tonic-gate 804*0Sstevel@tonic-gate if (isdigit((u_char)(c = *yyInput)) || c == '-' || c == '+') { 805*0Sstevel@tonic-gate if (c == '-' || c == '+') { 806*0Sstevel@tonic-gate sign = c == '-' ? -1 : 1; 807*0Sstevel@tonic-gate if (!isdigit((u_char)*++yyInput)) 808*0Sstevel@tonic-gate /* skip the '-' sign */ 809*0Sstevel@tonic-gate continue; 810*0Sstevel@tonic-gate } 811*0Sstevel@tonic-gate else 812*0Sstevel@tonic-gate sign = 0; 813*0Sstevel@tonic-gate yylval.Number = 0; 814*0Sstevel@tonic-gate while (isdigit((u_char)(c = *yyInput++))) { 815*0Sstevel@tonic-gate int n; 816*0Sstevel@tonic-gate char digit = c; 817*0Sstevel@tonic-gate (void) sscanf(&digit, "%1d", &n); 818*0Sstevel@tonic-gate yylval.Number = 10 * yylval.Number + n; 819*0Sstevel@tonic-gate } 820*0Sstevel@tonic-gate yyInput--; 821*0Sstevel@tonic-gate if (sign < 0) 822*0Sstevel@tonic-gate yylval.Number = -yylval.Number; 823*0Sstevel@tonic-gate return sign ? tSNUMBER : tUNUMBER; 824*0Sstevel@tonic-gate } 825*0Sstevel@tonic-gate if (isalpha((u_char)c)) { 826*0Sstevel@tonic-gate for (p = buff; isalpha((u_char)(c = *yyInput++)) || c == '.'; ) 827*0Sstevel@tonic-gate if (p < &buff[sizeof (buff) - 1]) 828*0Sstevel@tonic-gate *p++ = c; 829*0Sstevel@tonic-gate *p = '\0'; 830*0Sstevel@tonic-gate yyInput--; 831*0Sstevel@tonic-gate return LookupWord(buff); 832*0Sstevel@tonic-gate } 833*0Sstevel@tonic-gate if (c != '(') 834*0Sstevel@tonic-gate return *yyInput++; 835*0Sstevel@tonic-gate Count = 0; 836*0Sstevel@tonic-gate do { 837*0Sstevel@tonic-gate c = *yyInput++; 838*0Sstevel@tonic-gate if (c == '\0') 839*0Sstevel@tonic-gate return c; 840*0Sstevel@tonic-gate if (c == '(') 841*0Sstevel@tonic-gate Count++; 842*0Sstevel@tonic-gate else if (c == ')') 843*0Sstevel@tonic-gate Count--; 844*0Sstevel@tonic-gate } while (Count > 0); 845*0Sstevel@tonic-gate } 846*0Sstevel@tonic-gate } 847*0Sstevel@tonic-gate 848*0Sstevel@tonic-gate 849*0Sstevel@tonic-gate time_t 850*0Sstevel@tonic-gate getreldate(p, now) 851*0Sstevel@tonic-gate char *p; 852*0Sstevel@tonic-gate struct timeb *now; 853*0Sstevel@tonic-gate { 854*0Sstevel@tonic-gate struct tm *tm; 855*0Sstevel@tonic-gate struct timeb ftz; 856*0Sstevel@tonic-gate time_t Start; 857*0Sstevel@tonic-gate time_t tod; 858*0Sstevel@tonic-gate 859*0Sstevel@tonic-gate if (strcmp(setlocale(LC_TIME, NULL), "C")) { 860*0Sstevel@tonic-gate static char localedate[24]; 861*0Sstevel@tonic-gate struct tm ltm; 862*0Sstevel@tonic-gate 863*0Sstevel@tonic-gate tm = getdate(p); 864*0Sstevel@tonic-gate if (getdate_err == 1 /* NODATEMASK */) { 865*0Sstevel@tonic-gate char buffy[BUFSIZ]; 866*0Sstevel@tonic-gate time_t current; 867*0Sstevel@tonic-gate 868*0Sstevel@tonic-gate printf(gettext("environment variable %s not set\n"), "DATEMSK"); 869*0Sstevel@tonic-gate do { 870*0Sstevel@tonic-gate time(¤t); 871*0Sstevel@tonic-gate tm = localtime(¤t); 872*0Sstevel@tonic-gate memcpy(<m, tm, sizeof(ltm)); 873*0Sstevel@tonic-gate tm = <m; 874*0Sstevel@tonic-gate 875*0Sstevel@tonic-gate (void) fputs(gettext("Enter date as mmddhhmm[yy]: "), stdout); 876*0Sstevel@tonic-gate (void) fflush(stdout); 877*0Sstevel@tonic-gate if (fgets(buffy, sizeof (buffy), stdin) == NULL) { 878*0Sstevel@tonic-gate (void) printf(gettext("Encountered EOF on stdin\n")); 879*0Sstevel@tonic-gate return(-1); 880*0Sstevel@tonic-gate } 881*0Sstevel@tonic-gate } while (sscanf(buffy, "%2d%2d%2d%2d%2d", 882*0Sstevel@tonic-gate &(tm->tm_mon), &(tm->tm_mday), &(tm->tm_hour), 883*0Sstevel@tonic-gate &(tm->tm_min), &(tm->tm_year)) < 4); 884*0Sstevel@tonic-gate 885*0Sstevel@tonic-gate (tm->tm_mon)--; 886*0Sstevel@tonic-gate } else if (tm == NULL) 887*0Sstevel@tonic-gate return(-1); 888*0Sstevel@tonic-gate 889*0Sstevel@tonic-gate (void)sprintf(localedate, "%d:%2.2d %d/%d %d", 890*0Sstevel@tonic-gate tm->tm_hour, tm->tm_min, tm->tm_mon + 1, 891*0Sstevel@tonic-gate tm->tm_mday, CHECK_TM(tm->tm_year)); 892*0Sstevel@tonic-gate p = localedate; 893*0Sstevel@tonic-gate } 894*0Sstevel@tonic-gate 895*0Sstevel@tonic-gate yyInput = p; 896*0Sstevel@tonic-gate if (now == NULL) { 897*0Sstevel@tonic-gate now = &ftz; 898*0Sstevel@tonic-gate (void) time(&ftz.time); 899*0Sstevel@tonic-gate /* Set the timezone global. */ 900*0Sstevel@tonic-gate tzset(); 901*0Sstevel@tonic-gate /* LINTED timezone is time_t so intermediate results aren't truncated */ 902*0Sstevel@tonic-gate ftz.timezone = (int) timezone / 60; 903*0Sstevel@tonic-gate } 904*0Sstevel@tonic-gate 905*0Sstevel@tonic-gate tm = localtime(&now->time); 906*0Sstevel@tonic-gate yyYear = tm->tm_year; 907*0Sstevel@tonic-gate yyMonth = tm->tm_mon + 1; 908*0Sstevel@tonic-gate yyDay = tm->tm_mday; 909*0Sstevel@tonic-gate yyTimezone = now->timezone; 910*0Sstevel@tonic-gate yyDSTmode = DSTmaybe; 911*0Sstevel@tonic-gate yyHour = tm->tm_hour; 912*0Sstevel@tonic-gate yyMinutes = tm->tm_min; 913*0Sstevel@tonic-gate yySeconds = tm->tm_sec; 914*0Sstevel@tonic-gate yyMeridian = MER24; 915*0Sstevel@tonic-gate yyRelSeconds = 0; 916*0Sstevel@tonic-gate yyRelMonth = 0; 917*0Sstevel@tonic-gate yyHaveDate = 0; 918*0Sstevel@tonic-gate yyHaveDay = 0; 919*0Sstevel@tonic-gate yyHaveRel = 0; 920*0Sstevel@tonic-gate yyHaveTime = 0; 921*0Sstevel@tonic-gate yyHaveZone = 0; 922*0Sstevel@tonic-gate 923*0Sstevel@tonic-gate if (yyparse() 924*0Sstevel@tonic-gate || yyHaveTime > 1 || yyHaveZone > 1 || yyHaveDate > 1 || yyHaveDay > 1) 925*0Sstevel@tonic-gate return -1; 926*0Sstevel@tonic-gate 927*0Sstevel@tonic-gate if (yyHaveDate || yyHaveTime || yyHaveDay) { 928*0Sstevel@tonic-gate Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds, 929*0Sstevel@tonic-gate yyMeridian, yyDSTmode); 930*0Sstevel@tonic-gate if (Start < 0) 931*0Sstevel@tonic-gate return -1; 932*0Sstevel@tonic-gate } 933*0Sstevel@tonic-gate else { 934*0Sstevel@tonic-gate Start = now->time; 935*0Sstevel@tonic-gate if (!yyHaveRel) 936*0Sstevel@tonic-gate Start -= ((tm->tm_hour * 60L) + tm->tm_min * 60L) + tm->tm_sec; 937*0Sstevel@tonic-gate } 938*0Sstevel@tonic-gate 939*0Sstevel@tonic-gate Start += yyRelSeconds; 940*0Sstevel@tonic-gate Start += RelativeMonth(Start, yyRelMonth); 941*0Sstevel@tonic-gate 942*0Sstevel@tonic-gate if (yyHaveDay && !yyHaveDate) { 943*0Sstevel@tonic-gate tod = RelativeDate(Start, yyDayOrdinal, yyDayNumber); 944*0Sstevel@tonic-gate Start += tod; 945*0Sstevel@tonic-gate } 946*0Sstevel@tonic-gate 947*0Sstevel@tonic-gate /* Have to do *something* with a legitimate -1 so it's distinguishable 948*0Sstevel@tonic-gate * from the error return value. (Alternately could set errno on error.) */ 949*0Sstevel@tonic-gate return Start == -1 ? 0 : Start; 950*0Sstevel@tonic-gate } 951*0Sstevel@tonic-gate 952*0Sstevel@tonic-gate #if defined(TEST) 953*0Sstevel@tonic-gate 954*0Sstevel@tonic-gate /* ARGSUSED */ 955*0Sstevel@tonic-gate main(ac, av) 956*0Sstevel@tonic-gate int ac; 957*0Sstevel@tonic-gate char *av[]; 958*0Sstevel@tonic-gate { 959*0Sstevel@tonic-gate char buff[128]; 960*0Sstevel@tonic-gate time_t d; 961*0Sstevel@tonic-gate 962*0Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 963*0Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 964*0Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 965*0Sstevel@tonic-gate #endif 966*0Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 967*0Sstevel@tonic-gate 968*0Sstevel@tonic-gate (void) printf(gettext("Enter date, or blank line to exit.\n\t> ")); 969*0Sstevel@tonic-gate (void) fflush(stdout); 970*0Sstevel@tonic-gate while (gets(buff) && buff[0]) { 971*0Sstevel@tonic-gate d = getreldate(buff, (struct timeb *)NULL); 972*0Sstevel@tonic-gate if (d == -1) 973*0Sstevel@tonic-gate (void) printf(gettext("Bad format - couldn't convert.\n")); 974*0Sstevel@tonic-gate else { 975*0Sstevel@tonic-gate (void) cftime(buff, "%c\n", &d); 976*0Sstevel@tonic-gate (void) printf("%s", buff); 977*0Sstevel@tonic-gate } 978*0Sstevel@tonic-gate (void) printf("\t> "); 979*0Sstevel@tonic-gate (void) fflush(stdout); 980*0Sstevel@tonic-gate } 981*0Sstevel@tonic-gate exit(0); 982*0Sstevel@tonic-gate /* NOTREACHED */ 983*0Sstevel@tonic-gate } 984*0Sstevel@tonic-gate #endif /* defined(TEST) */ 985