Introduction
Introduction Statistics Contact Development Disclaimer Help
zoneinfo.c - 9base - revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log
Files
Refs
README
LICENSE
---
zoneinfo.c (3092B)
---
1 #include <u.h>
2 #include <libc.h>
3
4 /*
5 * Access local time entries of zoneinfo files.
6 * Formats 0 and 2 are supported, and 4-byte timestamps
7 *
8 * Copyright © 2008 M. Teichgräber
9 * Contributed under the terms of the Lucent Public License 1.02.
10 */
11 #include "zoneinfo.h"
12
13 static
14 struct Zoneinfo
15 {
16 int timecnt; /* # of transition times */
17 int typecnt; /* # of local time types */
18 int charcnt; /* # of characters of time zo…
19
20 uchar *ptime;
21 uchar *ptype;
22 uchar *ptt;
23 uchar *pzone;
24 } z;
25
26 static uchar *tzdata;
27
28 static
29 uchar*
30 readtzfile(char *file)
31 {
32 uchar *p;
33 int fd;
34 Dir *d;
35
36 fd = open(file, OREAD);
37 if (fd<0)
38 return nil;
39 d = dirfstat(fd);
40 if (d==nil)
41 return nil;
42 p = malloc(d->length);
43 if (p!=nil)
44 readn(fd, p, d->length);
45 free(d);
46 close(fd);
47 return p;
48 }
49 static char *zonefile;
50 void
51 tzfile(char *f)
52 {
53 if (tzdata!=nil) {
54 free(tzdata);
55 tzdata = nil;
56 }
57 z.timecnt = 0;
58 zonefile = f;
59 }
60
61 static
62 long
63 get4(uchar *p)
64 {
65 return (p[0]<<24)+(p[1]<<16)+(p[2]<<8)+p[3];
66 }
67
68 enum {
69 TTinfosz = 4+1+1,
70 };
71
72 static
73 int
74 parsehead(void)
75 {
76 uchar *p;
77 int ver;
78
79 ver = tzdata[4];
80 if (ver!=0)
81 if (ver!='2')
82 return -1;
83
84 p = tzdata + 4 + 1 + 15;
85
86 z.timecnt = get4(p+3*4);
87 z.typecnt = get4(p+4*4);
88 if (z.typecnt==0)
89 return -1;
90 z.charcnt = get4(p+5*4);
91 z.ptime = p+6*4;
92 z.ptype = z.ptime + z.timecnt*4;
93 z.ptt = z.ptype + z.timecnt;
94 z.pzone = z.ptt + z.typecnt*TTinfosz;
95 return 0;
96 }
97
98 static
99 void
100 ttinfo(Tinfo *ti, int tti)
101 {
102 uchar *p;
103 int i;
104
105 i = z.ptype[tti];
106 assert(i<z.typecnt);
107 p = z.ptt + i*TTinfosz;
108 ti->tzoff = get4(p);
109 ti->dlflag = p[4];
110 assert(p[5]<z.charcnt);
111 ti->zone = (char*)z.pzone + p[5];
112 }
113
114 static
115 void
116 readtimezone(void)
117 {
118 char *tmp;
119
120 z.timecnt = 0;
121 switch (zonefile==nil) {
122 default:
123 if ((tmp=getenv("timezone"))!=nil) {
124 tzdata = readtzfile(tmp);
125 free(tmp);
126 break;
127 }
128 zonefile = "/etc/localtime";
129 /* fall through */
130 case 0:
131 tzdata = readtzfile(zonefile);
132 }
133 if (tzdata==nil)
134 return;
135
136 if (strncmp("TZif", (char*)tzdata, 4)!=0)
137 goto errfree;
138
139 if (parsehead()==-1) {
140 errfree:
141 free(tzdata);
142 tzdata = nil;
143 z.timecnt = 0;
144 return;
145 }
146 }
147
148 static
149 tlong
150 gett4(uchar *p)
151 {
152 long l;
153
154 l = get4(p);
155 if (l<0)
156 return 0;
157 return l;
158 }
159 int
160 zonetinfo(Tinfo *ti, int i)
161 {
162 if (tzdata==nil)
163 readtimezone();
164 if (i<0 || i>=z.timecnt)
165 return -1;
166 ti->t = gett4(z.ptime + 4*i);
167 ttinfo(ti, i);
168 return i;
169 }
170
171 int
172 zonelookuptinfo(Tinfo *ti, tlong t)
173 {
174 uchar *p;
175 int i;
176 tlong oldtt, tt;
177
178 if (tzdata==nil)
179 readtimezone();
180 oldtt = 0;
181 p = z.ptime;
182 for (i=0; i<z.timecnt; i++) {
183 tt = gett4(p);
184 if (t<tt)
185 break;
186 oldtt = tt;
187 p += 4;
188 }
189 if (i>0) {
190 ttinfo(ti, i-1);
191 ti->t = oldtt;
192 // fprint(2, "t:%ld off:%d dflag:%d %s\n", (long)ti->t, t…
193 return i-1;
194 }
195 return -1;
196 }
197
198 void
199 zonedump(int fd)
200 {
201 int i;
202 uchar *p;
203 tlong t;
204 Tinfo ti;
205
206 if (tzdata==nil)
207 readtimezone();
208 p = z.ptime;
209 for (i=0; i<z.timecnt; i++) {
210 t = gett4(p);
211 ttinfo(&ti, i);
212 fprint(fd, "%ld\t%d\t%d\t%s\n", (long)t, ti.tzoff, ti.dl…
213 p += 4;
214 }
215 }
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.