PostgreSQL Source Code: src/port/path.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16#ifndef FRONTEND

18#else

20#endif

21

22#include <ctype.h>

23#include <sys/stat.h>

24#ifdef WIN32

25#ifdef _WIN32_IE

26#undef _WIN32_IE

27#endif

28#define _WIN32_IE 0x0500

29#ifdef near

30#undef near

31#endif

32#define near

33#include <shlobj.h>

34#else

37#endif

38

40#include "pg_config_paths.h"

41

42

43#ifndef WIN32

44#define IS_PATH_VAR_SEP(ch) ((ch) == ':')

45#else

46#define IS_PATH_VAR_SEP(ch) ((ch) == ';')

47#endif

48

49#ifdef WIN32

50static void debackslash_path(char *path, int encoding);

52#endif

53static void make_relative_path(char *ret_path, const char *target_path,

58

59

60

61

62

63

64

65

66#ifdef WIN32

67

68static char *

70{

72 {

73 path += 2;

75 path++;

76 }

77 else if (isalpha((unsigned char) path[0]) && path[1] == ':')

78 {

79 path += 2;

80 }

81 return (char *) path;

82}

83#else

84

85#define skip_drive(path) (path)

86#endif

87

88

89

90

91

92

93bool

95{

96#ifdef WIN32

98#else

99 return false;

100#endif

101}

102

103

104

105

106

107

108

109char *

111{

112 const char *p;

113

117 return NULL;

118}

119

120

121

122

123

124

125

126char *

128{

129 const char *p;

130

131

132 for (p = pathlist; *p; p++)

135 return NULL;

136}

137

138

139

140

141

142

143

144char *

146{

147 const char *p,

148 *ret = NULL;

149

152 ret = p;

154}

155

156

157#ifdef WIN32

158

159

160

161

162

163static void

164debackslash_path(char *path, int encoding)

165{

166 char *p;

167

168

169

170

171

172

173

174

176 {

177 for (p = path; *p; p += pg_sjis_mblen((const unsigned char *) p))

178 {

179 if (*p == '\\')

180 *p = '/';

181 }

182 }

183 else

184 {

185 for (p = path; *p; p++)

186 {

187 if (*p == '\\')

188 *p = '/';

189 }

190 }

191}

192

193

194

195

196

197

198

199

200

201static int

203{

205

206 if (*s >= 0xa1 && *s <= 0xdf)

207 len = 1;

209 len = 2;

210 else

211 len = 1;

212 return len;

213}

214

215#endif

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235void

237{

238#ifdef WIN32

239 char *p;

240

242 if (*p == '/')

243 *p = '\\';

244#endif

245}

246

247

248

249

250

251

252

253

254

255

256

257void

259{

260#ifdef WIN32

261

262

263

264

265

266

267 GetShortPathName(path, path, MAXPGPATH - 1);

268

269

270

272#endif

273}

274

275

276

277

278

279

280

281

282

283

284

285void

287 const char *head, const char *tail)

288{

289 if (ret_path != head)

291

292

293

294

295

296

297 if (*tail)

298 {

299

300 snprintf(ret_path + strlen(ret_path), MAXPGPATH - strlen(ret_path),

301 "%s%s",

302 (*(skip_drive(head)) != '\0') ? "/" : "",

303 tail);

304 }

305}

306

307

308

309typedef enum

310{

312

314

317

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336void

338{

339

341}

342

343void

345{

346 char *p,

347 *to_p;

348 char *spath;

349 char *parsed;

350 char *unparse;

351 bool was_sep = false;

353 int pathdepth = 0;

354

355#ifdef WIN32

356

357

358

359

360

361

362 debackslash_path(path, encoding);

363

364

365

366

367

368 p = path + strlen(path);

369 if (p > path && *(p - 1) == '"')

370 *(p - 1) = '/';

371#endif

372

373

374

375

376

377

379

380

381

382

383 p = path;

384#ifdef WIN32

385

386 if (*p)

387 p++;

388#endif

389 to_p = p;

390 for (; *p; p++, to_p++)

391 {

392

393 while (*p == '/' && was_sep)

394 p++;

395 if (to_p != p)

396 *to_p = *p;

397 was_sep = (*p == '/');

398 }

399 *to_p = '\0';

400

401

402

403

404

405

406

407

408

409

410

411

412

414 if (*spath == '\0')

415 return;

416

417 if (*spath == '/')

418 {

420

421 parsed = unparse = (spath + 1);

422 }

423 else

424 {

426 parsed = unparse = spath;

427 }

428

429 while (*unparse != '\0')

430 {

431 char *unparse_next;

432 bool is_double_dot;

433

434

435 unparse_next = unparse;

436 while (*unparse_next && *unparse_next != '/')

437 unparse_next++;

438 if (*unparse_next != '\0')

439 *unparse_next++ = '\0';

440

441

442 if (strcmp(unparse, ".") == 0)

443 {

444

445 unparse = unparse_next;

446 continue;

447 }

448

449 if (strcmp(unparse, "..") == 0)

450 is_double_dot = true;

451 else

452 {

453

454 Assert(*unparse != '\0');

455 is_double_dot = false;

456 }

457

459 {

461

462 if (!is_double_dot)

463 {

464

467 pathdepth++;

468 }

469 break;

471 if (is_double_dot)

472 {

473

474

475 *parsed = '\0';

477 if (--pathdepth == 0)

479 }

480 else

481 {

482

483 *parsed++ = '/';

485 pathdepth++;

486 }

487 break;

489 if (is_double_dot)

490 {

491

494 }

495 else

496 {

497

500 pathdepth++;

501 }

502 break;

504 if (is_double_dot)

505 {

506

507 *parsed = '\0';

509 if (--pathdepth == 0)

510 {

511

512

513

514

515

516

517 if (parsed == spath)

519 else

521 }

522 }

523 else

524 {

525

526 *parsed++ = '/';

528 pathdepth++;

529 }

530 break;

532 if (is_double_dot)

533 {

534

535 *parsed++ = '/';

537 }

538 else

539 {

540

541 *parsed++ = '/';

543

544

545

546

547

548

550 pathdepth = 1;

551 }

552 break;

553 }

554

555 unparse = unparse_next;

556 }

557

558

559

560

561

562

563

564 if (parsed == spath)

565 *parsed++ = '.';

566

567

568 *parsed = '\0';

569}

570

571

572

573

574

575

576bool

578{

579

580

581

582

583

584

585 path = skip_drive(path);

586

587 if (path[0] == '.' &&

588 path[1] == '.' &&

589 (path[2] == '\0' || path[2] == '/'))

590 return true;

591

592 return false;

593}

594

595

596

597

598

599

600

601

602

603bool

605{

607 return false;

608

610 return false;

611#ifdef WIN32

612

613

614

615

616

617

618

619

620

621

622 else if (isalpha((unsigned char) path[0]) && path[1] == ':' &&

624 return false;

625#endif

626 else

627 return true;

628}

629

630

631

632

633

634

635

636bool

638{

639 int path1_len = strlen(path1);

640

641 if (strncmp(path1, path2, path1_len) == 0 &&

642 (IS_DIR_SEP(path2[path1_len]) || path2[path1_len] == '\0'))

643 return true;

644 return false;

645}

646

647

648

649

650

651const char *

653{

654 const char *nodir_name;

656

658 if (nodir_name)

659 nodir_name++;

660 else

662

663

664

665

666

667 progname = strdup(nodir_name);

669 {

670 fprintf(stderr, "%s: out of memory\n", nodir_name);

671 abort();

672 }

673

674#if defined(__CYGWIN__) || defined(WIN32)

675

676 if (strlen(progname) > sizeof(EXE) - 1 &&

679#endif

680

682}

683

684

685

686

687

688

689static int

691{

692 while (*s1 && *s2)

693 {

694 if (

695#ifndef WIN32

697#else

698

700#endif

702 return (int) *s1 - (int) *s2;

704 }

705 if (*s1)

706 return 1;

707 if (*s2)

708 return -1;

709 return 0;

710}

711

712

713

714

715

716

717

718

719

720

721

722

723

724

725

726

727

728

729

730

731

732

733

734

735

736

737static void

740{

741 int prefix_len;

742 int tail_start;

743 int tail_len;

744 int i;

745

746

747

748

749

750 prefix_len = 0;

751 for (i = 0; target_path[i] && bin_path[i]; i++)

752 {

754 prefix_len = i + 1;

755 else if (target_path[i] != bin_path[i])

756 break;

757 }

758 if (prefix_len == 0)

759 goto no_match;

760 tail_len = strlen(bin_path) - prefix_len;

761

762

763

764

765

767 trim_directory(ret_path);

769

770

771

772

773 tail_start = (int) strlen(ret_path) - tail_len;

774 if (tail_start > 0 &&

775 IS_DIR_SEP(ret_path[tail_start - 1]) &&

777 {

778 ret_path[tail_start] = '\0';

782 return;

783 }

784

785no_match:

788}

789

790

791

792

793

794

795

796

797

798

799

800

801

802

803

804

805

806char *

808{

809 char *new;

810

811

812 if (path == NULL)

813 return NULL;

814

816 {

817 char *buf;

818 size_t buflen;

819

821 for (;;)

822 {

824 if (buf)

825 {

826#ifndef FRONTEND

828 (errcode(ERRCODE_OUT_OF_MEMORY),

829 errmsg("out of memory")));

830#else

831 fprintf(stderr, _("out of memory\n"));

832 return NULL;

833#endif

834 }

835

836 if (getcwd(buf, buflen))

837 break;

838 else if (errno == ERANGE)

839 {

841 buflen *= 2;

842 continue;

843 }

844 else

845 {

846 int save_errno = errno;

847

849 errno = save_errno;

850#ifndef FRONTEND

851 elog(ERROR, "could not get current working directory: %m");

852#else

853 fprintf(stderr, _("could not get current working directory: %m\n"));

854 return NULL;

855#endif

856 }

857 }

858

859 new = malloc(strlen(buf) + strlen(path) + 2);

860 if (!new)

861 {

863#ifndef FRONTEND

865 (errcode(ERRCODE_OUT_OF_MEMORY),

866 errmsg("out of memory")));

867#else

868 fprintf(stderr, _("out of memory\n"));

869 return NULL;

870#endif

871 }

874 }

875 else

876 {

877 new = strdup(path);

878 if (!new)

879 {

880#ifndef FRONTEND

882 (errcode(ERRCODE_OUT_OF_MEMORY),

883 errmsg("out of memory")));

884#else

885 fprintf(stderr, _("out of memory\n"));

886 return NULL;

887#endif

888 }

889 }

890

891

893

894 return new;

895}

896

897

898

899

900

901void

903{

905}

906

907

908

909

910void

912{

914}

915

916

917

918

919void

921{

923}

924

925

926

927

928void

930{

932}

933

934

935

936

937void

939{

941}

942

943

944

945

946void

948{

950}

951

952

953

954

955void

957{

959}

960

961

962

963

964void

966{

968}

969

970

971

972

973void

975{

977}

978

979

980

981

982void

984{

986}

987

988

989

990

991void

993{

995}

996

997

998

999

1000

1001

1002

1003

1004bool

1006{

1007#ifndef WIN32

1008

1009

1010

1011

1012 const char *home;

1013

1014 home = getenv("HOME");

1015 if (home && home[0])

1016 {

1018 return true;

1019 }

1020 else

1021 {

1022 struct passwd pwbuf;

1023 struct passwd *pw;

1024 char buf[1024];

1025 int rc;

1026

1027 rc = getpwuid_r(geteuid(), &pwbuf, buf, sizeof buf, &pw);

1028 if (rc != 0 || !pw)

1029 return false;

1031 return true;

1032 }

1033#else

1034 char *tmppath;

1035

1036

1037

1038

1039

1040

1041

1042

1043 tmppath = getenv("APPDATA");

1044 if (!tmppath)

1045 return false;

1047 return true;

1048#endif

1049}

1050

1051

1052

1053

1054

1055

1056

1057

1058

1059

1060

1061

1062

1063

1064

1065

1066

1067void

1069{

1071}

1072

1073

1074

1075

1076

1077

1078

1079

1080

1081

1082

1083

1084static char *

1086{

1087 char *p;

1088

1090

1091 if (path[0] == '\0')

1092 return path;

1093

1094

1095 for (p = path + strlen(path) - 1; IS_DIR_SEP(*p) && p > path; p--)

1096 ;

1097

1098 for (; IS\_DIR\_SEP(*p) && p > path; p--)

1099 ;

1100

1101 for (; p > path && IS_DIR_SEP(*(p - 1)); p--)

1102 ;

1103

1105 p++;

1106 *p = '\0';

1107 return p;

1108}

1109

1110

1111

1112

1113

1114

1115

1116static void

1118{

1119 char *p;

1120

1122 p = path + strlen(path);

1123 if (p > path)

1124 for (p--; p > path && IS_DIR_SEP(*p); p--)

1125 *p = '\0';

1126}

1127

1128

1129

1130

1131

1132

1133

1134

1135

1136

1137

1138static char *

1140{

1141 size_t len = strlen(subdir);

1142

1143

1144 if (path != subdir)

1145 memmove(path, subdir, len);

1146

1147 return path + len;

1148}

#define unconstify(underlying_type, expr)

#define IS_HIGHBIT_SET(ch)

#define fprintf(file, fmt, msg)

int errcode(int sqlerrcode)

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

#define ereport(elevel,...)

char my_exec_path[MAXPGPATH]

Assert(PointerIsAligned(start, uint64))

static char bin_path[MAXPGPATH]

void cleanup_path(char *path)

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

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

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

void join_path_components(char *ret_path, const char *head, const char *tail)

#define IS_PATH_VAR_SEP(ch)

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

bool get_home_path(char *ret_path)

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

static char * append_subdir_to_path(char *path, char *subdir)

bool path_is_prefix_of_path(const char *path1, const char *path2)

char * last_dir_separator(const char *filename)

bool path_is_relative_and_below_cwd(const char *path)

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

char * first_path_var_separator(const char *pathlist)

void canonicalize_path(char *path)

void get_parent_directory(char *path)

static void trim_trailing_separator(char *path)

static char * trim_directory(char *path)

static void make_relative_path(char *ret_path, const char *target_path, const char *bin_path, const char *my_exec_path)

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

void canonicalize_path_enc(char *path, int encoding)

static int dir_strcmp(const char *s1, const char *s2)

bool path_contains_parent_reference(const char *path)

void make_native_path(char *filename)

char * make_absolute_path(const char *path)

const char * get_progname(const char *argv0)

char * first_dir_separator(const char *filename)

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

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

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

bool has_drive_prefix(const char *path)

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

@ RELATIVE_WITH_PARENT_REF

#define is_absolute_path(filename)

int pg_strcasecmp(const char *s1, const char *s2)

unsigned char pg_tolower(unsigned char ch)

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

static int pg_sjis_mblen(const unsigned char *s)