PostgreSQL Source Code: src/timezone/pgtz.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

14

15#include <ctype.h>

16#include <fcntl.h>

18

25

26

27

29

30

32

33

35 const char *fname, int fnamelen,

36 char *canonname, int canonnamelen);

37

38

39

40

41

42static const char *

44{

45#ifndef SYSTEMTZDIR

46

47 static bool done_tzdir = false;

49

50 if (done_tzdir)

51 return tzdir;

52

54 strlcpy(tzdir + strlen(tzdir), "/timezone", MAXPGPATH - strlen(tzdir));

55

56 done_tzdir = true;

57 return tzdir;

58#else

59

60 return SYSTEMTZDIR;

61#endif

62}

63

64

65

66

67

68

69

70

71

72

73

74

75int

77{

78 const char *fname;

80 int fullnamelen;

81 int orignamelen;

82

83

85 orignamelen = fullnamelen = strlen(fullname);

86

88 return -1;

89

90

91

92

93

94

95

96

97 if (canonname == NULL)

98 {

99 int result;

100

101 fullname[fullnamelen] = '/';

102

103 strcpy(fullname + fullnamelen + 1, name);

104 result = open(fullname, O_RDONLY | PG_BINARY, 0);

105 if (result >= 0)

106 return result;

107

108 fullname[fullnamelen] = '\0';

109 }

110

111

112

113

114

115 fname = name;

116 for (;;)

117 {

118 const char *slashptr;

119 int fnamelen;

120

121 slashptr = strchr(fname, '/');

122 if (slashptr)

123 fnamelen = slashptr - fname;

124 else

125 fnamelen = strlen(fname);

127 fullname + fullnamelen + 1,

129 return -1;

130 fullname[fullnamelen++] = '/';

131 fullnamelen += strlen(fullname + fullnamelen);

132 if (slashptr)

133 fname = slashptr + 1;

134 else

135 break;

136 }

137

138 if (canonname)

140

141 return open(fullname, O_RDONLY | PG_BINARY, 0);

142}

143

144

145

146

147

148

149

150static bool

152 char *canonname, int canonnamelen)

153{

154 bool found = false;

155 DIR *dirdesc;

156 struct dirent *direntry;

157

159

161 {

162

163

164

165

166 if (direntry->d_name[0] == '.')

167 continue;

168

169 if (strlen(direntry->d_name) == fnamelen &&

171 {

172

173 strlcpy(canonname, direntry->d_name, canonnamelen);

174 found = true;

175 break;

176 }

177 }

178

180

181 return found;

182}

183

184

185

186

187

188

189

190

191typedef struct

192{

193

197

199

200

201static bool

203{

205

208

210 4,

211 &hash_ctl,

214 return false;

215

216 return true;

217}

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

235{

237 struct state tzstate;

240 char *p;

241

243 return NULL;

244

247 return NULL;

248

249

250

251

252

253

254

255 p = uppername;

256 while (*tzname)

257 *p++ = pg_toupper((unsigned char) *tzname++);

258 *p = '\0';

259

261 uppername,

263 NULL);

264 if (tzp)

265 {

266

267 return &tzp->tz;

268 }

269

270

271

272

273 if (strcmp(uppername, "GMT") == 0)

274 {

275 if (tzparse(uppername, &tzstate, true))

276 {

277

278 elog(ERROR, "could not initialize GMT time zone");

279 }

280

281 strcpy(canonname, uppername);

282 }

283 else if (tzload(uppername, canonname, &tzstate, true) != 0)

284 {

285 if (uppername[0] == ':' || tzparse(uppername, &tzstate, false))

286 {

287

288 return NULL;

289 }

290

291 strcpy(canonname, uppername);

292 }

293

294

296 uppername,

298 NULL);

299

300

301 strcpy(tzp->tz.TZname, canonname);

302 memcpy(&tzp->tz.state, &tzstate, sizeof(tzstate));

303

304 return &tzp->tz;

305}

306

307

308

309

310

311

312

313

314

315

316

317

318

321{

322 long absoffset = (gmtoffset < 0) ? -gmtoffset : gmtoffset;

323 char offsetstr[64];

324 char tzname[128];

325

326 snprintf(offsetstr, sizeof(offsetstr),

329 if (absoffset != 0)

330 {

331 snprintf(offsetstr + strlen(offsetstr),

332 sizeof(offsetstr) - strlen(offsetstr),

335 if (absoffset != 0)

336 snprintf(offsetstr + strlen(offsetstr),

337 sizeof(offsetstr) - strlen(offsetstr),

338 ":%02ld", absoffset);

339 }

340 if (gmtoffset > 0)

341 snprintf(tzname, sizeof(tzname), "<-%s>+%s",

342 offsetstr, offsetstr);

343 else

344 snprintf(tzname, sizeof(tzname), "<+%s>-%s",

345 offsetstr, offsetstr);

346

348}

349

350

351

352

353

354

355

356

357

358

359

360void

362{

363

364

365

366

367

368

369

372}

373

374

375

376

377

378

379

380

381

382

383#define MAX_TZDIR_DEPTH 10

384

386{

392};

393

394

395

398{

401

402 ret->baselen = strlen(startdir) + 1;

404 ret->dirname[0] = startdir;

409 errmsg("could not open directory \"%s\": %m", startdir)));

410 return ret;

411}

412

413void

415{

416 while (dir->depth >= 0)

417 {

421 }

423}

424

427{

428 while (dir->depth >= 0)

429 {

430 struct dirent *direntry;

432

434

435 if (!direntry)

436 {

437

441 continue;

442 }

443

444 if (direntry->d_name[0] == '.')

445 continue;

446

447 snprintf(fullname, sizeof(fullname), "%s/%s",

449

451 {

452

462 errmsg("could not open directory \"%s\": %m",

463 fullname)));

464

465

466 continue;

467 }

468

469

470

471

472

473

474

476 {

477

478 continue;

479 }

480

482 {

483

484 continue;

485 }

486

487

490

491

492 return &dir->tz;

493 }

494

495

496 return NULL;

497}

void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)

HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)

int errmsg_internal(const char *fmt,...)

int errcode_for_file_access(void)

int errmsg(const char *fmt,...)

#define ereport(elevel,...)

struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)

DIR * AllocateDir(const char *dirname)

struct dirent * ReadDir(DIR *dir, const char *dirname)

PGFileType get_dirent_type(const char *path, const struct dirent *de, bool look_through_symlinks, int elevel)

char my_exec_path[MAXPGPATH]

int tzload(const char *name, char *canonname, struct state *sp, bool doextend)

bool tzparse(const char *name, struct state *sp, bool lastditch)

char * pstrdup(const char *in)

void pfree(void *pointer)

void * palloc0(Size size)

bool pg_tz_acceptable(pg_tz *tz)

pg_tz * pg_tzset_offset(long gmtoffset)

static HTAB * timezone_cache

pg_tz * pg_tzenumerate_next(pg_tzenum *dir)

void pg_timezone_initialize(void)

pg_tz * pg_tzset(const char *tzname)

static const char * pg_TZDIR(void)

int pg_open_tzfile(const char *name, char *canonname)

static bool scan_directory_ci(const char *dirname, const char *fname, int fnamelen, char *canonname, int canonnamelen)

static bool init_timezone_hashtable(void)

void pg_tzenumerate_end(pg_tzenum *dir)

pg_tzenum * pg_tzenumerate_start(void)

void get_share_path(const char *my_exec_path, char *ret_path)

unsigned char pg_toupper(unsigned char ch)

size_t strlcpy(char *dst, const char *src, size_t siz)

int pg_strncasecmp(const char *s1, const char *s2, size_t n)

char TZname[TZ_STRLEN_MAX+1]

char * dirname[MAX_TZDIR_DEPTH]

DIR * dirdesc[MAX_TZDIR_DEPTH]