Coverage Report

Created: 2026-05-16 06:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/dcmtk/oficonv/libsrc/citrus_mmap.c
Line
Count
Source
1
/*-
2
 * Copyright (c)2003 Citrus Project,
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 *
14
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
 * SUCH DAMAGE.
25
 */
26
27
#include "dcmtk/config/osconfig.h"
28
#include "citrus_mmap.h"
29
#include "oficonv_logger.h"
30
31
#ifdef HAVE_SYS_MMAN_H
32
#include <sys/mman.h>
33
#endif
34
#include <sys/types.h>
35
#include <sys/stat.h>
36
37
#include <errno.h>
38
#include <fcntl.h>  /* for O_RDONLY, O_CLOEXEC */
39
#include <limits.h>
40
#include <stdio.h>
41
#include <stdlib.h>
42
#include <string.h>
43
#ifdef HAVE_UNISTD_H
44
#include <unistd.h>
45
#endif
46
47
#include "citrus_bcs.h"
48
#include "citrus_region.h"
49
#include "windows_mmap.h"
50
#include "data_esdb.h"
51
#include "data_csmapper.h"
52
53
#ifndef S_ISREG
54
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
55
#endif
56
57
58
void *lookup_builtin_data_file(const char *path, size_t *len)
59
0
{
60
0
  if (len == NULL || path == NULL) return NULL;
61
62
#ifdef DCMTK_ENABLE_BUILTIN_OFICONV_DATA
63
    const char *default_path;
64
    const char *current_path;
65
    size_t default_path_len;
66
#ifdef HAVE_WINDOWS_H
67
    char buf[OFICONV_PATH_MAX+1];
68
#endif
69
70
    /* check if we are trying to load from the default location */
71
    default_path = DEFAULT_SUPPORT_DATA_DIR;
72
    current_path = path;
73
#ifdef HAVE_WINDOWS_H
74
    memset(buf, 0, sizeof(buf));
75
    (void) ExpandEnvironmentStringsA(default_path, buf, sizeof(buf));
76
    default_path = buf;
77
#endif
78
    default_path_len = strlen(default_path);
79
80
    if (0 == strncmp(current_path, default_path, default_path_len))
81
    {
82
      /* advance to the relative path after the default location */
83
      current_path += default_path_len;
84
85
      /* skip a path separator following the default location, if any */
86
      if ((current_path[0] == PATH_SEPARATOR) || (current_path[0] == '/')) current_path++;
87
88
      /* check if the filename starts with csmapper */
89
#ifdef HAVE_WINDOWS_H
90
      if (0 == strncmp(current_path, "csmapper\\", 9) || 0 == strncmp(current_path, "csmapper/", 9))
91
#else
92
      if (0 == strncmp(current_path, "csmapper/", 9))
93
#endif
94
      {
95
        current_path += 9;
96
97
        if (0 == strcmp(current_path, "charset.pivot.pvdb")) { *len = csmapper_charset_pivot_pvdb_len; return csmapper_charset_pivot_pvdb; }
98
        if (0 == strcmp(current_path, "mapper.dir")) { *len = csmapper_mapper_dir_len; return csmapper_mapper_dir; }
99
        if (0 == strcmp(current_path, "mapper.dir.db")) { *len = csmapper_mapper_dir_db_len; return csmapper_mapper_dir_db; }
100
        if (0 == strcmp(current_path, "ISO-8859/ISO-8859-11%UCS.mps")) { *len = csmapper_ISO_8859_ISO_8859_11_UCS_mps_len; return csmapper_ISO_8859_ISO_8859_11_UCS_mps; }
101
        if (0 == strcmp(current_path, "ISO-8859/ISO-8859-15%UCS.mps")) { *len = csmapper_ISO_8859_ISO_8859_15_UCS_mps_len; return csmapper_ISO_8859_ISO_8859_15_UCS_mps; }
102
        if (0 == strcmp(current_path, "ISO-8859/ISO-8859-2%UCS.mps")) { *len = csmapper_ISO_8859_ISO_8859_2_UCS_mps_len; return csmapper_ISO_8859_ISO_8859_2_UCS_mps; }
103
        if (0 == strcmp(current_path, "ISO-8859/ISO-8859-3%UCS.mps")) { *len = csmapper_ISO_8859_ISO_8859_3_UCS_mps_len; return csmapper_ISO_8859_ISO_8859_3_UCS_mps; }
104
        if (0 == strcmp(current_path, "ISO-8859/ISO-8859-4%UCS.mps")) { *len = csmapper_ISO_8859_ISO_8859_4_UCS_mps_len; return csmapper_ISO_8859_ISO_8859_4_UCS_mps; }
105
        if (0 == strcmp(current_path, "ISO-8859/ISO-8859-5%UCS.mps")) { *len = csmapper_ISO_8859_ISO_8859_5_UCS_mps_len; return csmapper_ISO_8859_ISO_8859_5_UCS_mps; }
106
        if (0 == strcmp(current_path, "ISO-8859/ISO-8859-6%UCS.mps")) { *len = csmapper_ISO_8859_ISO_8859_6_UCS_mps_len; return csmapper_ISO_8859_ISO_8859_6_UCS_mps; }
107
        if (0 == strcmp(current_path, "ISO-8859/ISO-8859-7%UCS.mps")) { *len = csmapper_ISO_8859_ISO_8859_7_UCS_mps_len; return csmapper_ISO_8859_ISO_8859_7_UCS_mps; }
108
        if (0 == strcmp(current_path, "ISO-8859/ISO-8859-8%UCS.mps")) { *len = csmapper_ISO_8859_ISO_8859_8_UCS_mps_len; return csmapper_ISO_8859_ISO_8859_8_UCS_mps; }
109
        if (0 == strcmp(current_path, "ISO-8859/ISO-8859-9%UCS.mps")) { *len = csmapper_ISO_8859_ISO_8859_9_UCS_mps_len; return csmapper_ISO_8859_ISO_8859_9_UCS_mps; }
110
        if (0 == strcmp(current_path, "ISO-8859/UCS%ISO-8859-11.mps")) { *len = csmapper_ISO_8859_UCS_ISO_8859_11_mps_len; return csmapper_ISO_8859_UCS_ISO_8859_11_mps; }
111
        if (0 == strcmp(current_path, "ISO-8859/UCS%ISO-8859-15.mps")) { *len = csmapper_ISO_8859_UCS_ISO_8859_15_mps_len; return csmapper_ISO_8859_UCS_ISO_8859_15_mps; }
112
        if (0 == strcmp(current_path, "ISO-8859/UCS%ISO-8859-2.mps")) { *len = csmapper_ISO_8859_UCS_ISO_8859_2_mps_len; return csmapper_ISO_8859_UCS_ISO_8859_2_mps; }
113
        if (0 == strcmp(current_path, "ISO-8859/UCS%ISO-8859-3.mps")) { *len = csmapper_ISO_8859_UCS_ISO_8859_3_mps_len; return csmapper_ISO_8859_UCS_ISO_8859_3_mps; }
114
        if (0 == strcmp(current_path, "ISO-8859/UCS%ISO-8859-4.mps")) { *len = csmapper_ISO_8859_UCS_ISO_8859_4_mps_len; return csmapper_ISO_8859_UCS_ISO_8859_4_mps; }
115
        if (0 == strcmp(current_path, "ISO-8859/UCS%ISO-8859-5.mps")) { *len = csmapper_ISO_8859_UCS_ISO_8859_5_mps_len; return csmapper_ISO_8859_UCS_ISO_8859_5_mps; }
116
        if (0 == strcmp(current_path, "ISO-8859/UCS%ISO-8859-6.mps")) { *len = csmapper_ISO_8859_UCS_ISO_8859_6_mps_len; return csmapper_ISO_8859_UCS_ISO_8859_6_mps; }
117
        if (0 == strcmp(current_path, "ISO-8859/UCS%ISO-8859-7.mps")) { *len = csmapper_ISO_8859_UCS_ISO_8859_7_mps_len; return csmapper_ISO_8859_UCS_ISO_8859_7_mps; }
118
        if (0 == strcmp(current_path, "ISO-8859/UCS%ISO-8859-8.mps")) { *len = csmapper_ISO_8859_UCS_ISO_8859_8_mps_len; return csmapper_ISO_8859_UCS_ISO_8859_8_mps; }
119
        if (0 == strcmp(current_path, "ISO-8859/UCS%ISO-8859-9.mps")) { *len = csmapper_ISO_8859_UCS_ISO_8859_9_mps_len; return csmapper_ISO_8859_UCS_ISO_8859_9_mps; }
120
        if (0 == strcmp(current_path, "CP/CP936EXT%UCS.mps")) { *len = csmapper_CP_CP936EXT_UCS_mps_len; return csmapper_CP_CP936EXT_UCS_mps; }
121
        if (0 == strcmp(current_path, "CP/UCS%CP936EXT.mps")) { *len = csmapper_CP_UCS_CP936EXT_mps_len; return csmapper_CP_UCS_CP936EXT_mps; }
122
        if (0 == strcmp(current_path, "GB/GB18030%UCS@BMP.mps")) { *len = csmapper_GB_GB18030_UCS_BMP_mps_len; return csmapper_GB_GB18030_UCS_BMP_mps; }
123
        if (0 == strcmp(current_path, "GB/GB2312EXT%UCS.mps")) { *len = csmapper_GB_GB2312EXT_UCS_mps_len; return csmapper_GB_GB2312EXT_UCS_mps; }
124
        if (0 == strcmp(current_path, "GB/GB2312GBK%UCS.mps")) { *len = csmapper_GB_GB2312GBK_UCS_mps_len; return csmapper_GB_GB2312GBK_UCS_mps; }
125
        if (0 == strcmp(current_path, "GB/GB2312UDA1%UCS.mps")) { *len = csmapper_GB_GB2312UDA1_UCS_mps_len; return csmapper_GB_GB2312UDA1_UCS_mps; }
126
        if (0 == strcmp(current_path, "GB/GB2312UDA2%UCS.mps")) { *len = csmapper_GB_GB2312UDA2_UCS_mps_len; return csmapper_GB_GB2312UDA2_UCS_mps; }
127
        if (0 == strcmp(current_path, "GB/GB2312%UCS.mps")) { *len = csmapper_GB_GB2312_UCS_mps_len; return csmapper_GB_GB2312_UCS_mps; }
128
        if (0 == strcmp(current_path, "GB/GBKEXT%UCS.mps")) { *len = csmapper_GB_GBKEXT_UCS_mps_len; return csmapper_GB_GBKEXT_UCS_mps; }
129
        if (0 == strcmp(current_path, "GB/GBKUDA%UCS.mps")) { *len = csmapper_GB_GBKUDA_UCS_mps_len; return csmapper_GB_GBKUDA_UCS_mps; }
130
        if (0 == strcmp(current_path, "GB/UCS@BMP%GB18030.mps")) { *len = csmapper_GB_UCS_BMP_GB18030_mps_len; return csmapper_GB_UCS_BMP_GB18030_mps; }
131
        if (0 == strcmp(current_path, "GB/UCS%GB2312EXT.mps")) { *len = csmapper_GB_UCS_GB2312EXT_mps_len; return csmapper_GB_UCS_GB2312EXT_mps; }
132
        if (0 == strcmp(current_path, "GB/UCS%GB2312UDA1.mps")) { *len = csmapper_GB_UCS_GB2312UDA1_mps_len; return csmapper_GB_UCS_GB2312UDA1_mps; }
133
        if (0 == strcmp(current_path, "GB/UCS%GB2312UDA2.mps")) { *len = csmapper_GB_UCS_GB2312UDA2_mps_len; return csmapper_GB_UCS_GB2312UDA2_mps; }
134
        if (0 == strcmp(current_path, "GB/UCS%GB2312.mps")) { *len = csmapper_GB_UCS_GB2312_mps_len; return csmapper_GB_UCS_GB2312_mps; }
135
        if (0 == strcmp(current_path, "GB/UCS%GBKEXT.mps")) { *len = csmapper_GB_UCS_GBKEXT_mps_len; return csmapper_GB_UCS_GBKEXT_mps; }
136
        if (0 == strcmp(current_path, "GB/UCS%GBKUDA.mps")) { *len = csmapper_GB_UCS_GBKUDA_mps_len; return csmapper_GB_UCS_GBKUDA_mps; }
137
        if (0 == strcmp(current_path, "ISO646/ISO646-JP%UCS.646")) { *len = csmapper_ISO646_ISO646_JP_UCS_646_len; return csmapper_ISO646_ISO646_JP_UCS_646; }
138
        if (0 == strcmp(current_path, "ISO646/ISO646-US%UCS.646")) { *len = csmapper_ISO646_ISO646_US_UCS_646_len; return csmapper_ISO646_ISO646_US_UCS_646; }
139
        if (0 == strcmp(current_path, "JIS/JISX0201-KANA%UCS.mps")) { *len = csmapper_JIS_JISX0201_KANA_UCS_mps_len; return csmapper_JIS_JISX0201_KANA_UCS_mps; }
140
        if (0 == strcmp(current_path, "JIS/JISX0208@1990%UCS.mps")) { *len = csmapper_JIS_JISX0208_1990_UCS_mps_len; return csmapper_JIS_JISX0208_1990_UCS_mps; }
141
        if (0 == strcmp(current_path, "JIS/JISX0212%UCS.mps")) { *len = csmapper_JIS_JISX0212_UCS_mps_len; return csmapper_JIS_JISX0212_UCS_mps; }
142
        if (0 == strcmp(current_path, "JIS/UCS%JISX0201-KANA.mps")) { *len = csmapper_JIS_UCS_JISX0201_KANA_mps_len; return csmapper_JIS_UCS_JISX0201_KANA_mps; }
143
        if (0 == strcmp(current_path, "JIS/UCS%JISX0208@1990.mps")) { *len = csmapper_JIS_UCS_JISX0208_1990_mps_len; return csmapper_JIS_UCS_JISX0208_1990_mps; }
144
        if (0 == strcmp(current_path, "JIS/UCS%JISX0212.mps")) { *len = csmapper_JIS_UCS_JISX0212_mps_len; return csmapper_JIS_UCS_JISX0212_mps; }
145
        if (0 == strcmp(current_path, "KS/KSC5601HANGUL%UCS.mps")) { *len = csmapper_KS_KSC5601HANGUL_UCS_mps_len; return csmapper_KS_KSC5601HANGUL_UCS_mps; }
146
        if (0 == strcmp(current_path, "KS/KSC5601HANJA%UCS.mps")) { *len = csmapper_KS_KSC5601HANJA_UCS_mps_len; return csmapper_KS_KSC5601HANJA_UCS_mps; }
147
        if (0 == strcmp(current_path, "KS/UCS%KSC5601HANGUL.mps")) { *len = csmapper_KS_UCS_KSC5601HANGUL_mps_len; return csmapper_KS_UCS_KSC5601HANGUL_mps; }
148
        if (0 == strcmp(current_path, "KS/UCS%KSC5601HANJA.mps")) { *len = csmapper_KS_UCS_KSC5601HANJA_mps_len; return csmapper_KS_UCS_KSC5601HANJA_mps; }
149
150
        oficonv_log(1 /* debug */, "oficonv data file '", path, "' not present in built-in library.");
151
      }
152
      /* check if the filename starts with esdb */
153
#ifdef HAVE_WINDOWS_H
154
      else if (0 == strncmp(current_path, "esdb/", 5) || 0 == strncmp(current_path, "esdb\\", 5))
155
#else
156
      else if (0 == strncmp(current_path, "esdb/", 5))
157
#endif
158
      {
159
        current_path += 5;
160
161
        if (0 == strcmp(current_path, "esdb.alias.db")) { *len = esdb_esdb_alias_db_len; return esdb_esdb_alias_db; }
162
        if (0 == strcmp(current_path, "esdb.dir.db")) { *len = esdb_esdb_dir_db_len; return esdb_esdb_dir_db; }
163
        if (0 == strcmp(current_path, "UTF/UTF-8.esdb")) { *len = esdb_UTF_UTF_8_esdb_len; return esdb_UTF_UTF_8_esdb; }
164
        if (0 == strcmp(current_path, "ISO-8859/ISO-8859-1.esdb")) { *len = esdb_ISO_8859_ISO_8859_1_esdb_len; return esdb_ISO_8859_ISO_8859_1_esdb; }
165
        if (0 == strcmp(current_path, "ISO-8859/ISO-8859-11.esdb")) { *len = esdb_ISO_8859_ISO_8859_11_esdb_len; return esdb_ISO_8859_ISO_8859_11_esdb; }
166
        if (0 == strcmp(current_path, "ISO-8859/ISO-8859-15.esdb")) { *len = esdb_ISO_8859_ISO_8859_15_esdb_len; return esdb_ISO_8859_ISO_8859_15_esdb; }
167
        if (0 == strcmp(current_path, "ISO-8859/ISO-8859-2.esdb")) { *len = esdb_ISO_8859_ISO_8859_2_esdb_len; return esdb_ISO_8859_ISO_8859_2_esdb; }
168
        if (0 == strcmp(current_path, "ISO-8859/ISO-8859-3.esdb")) { *len = esdb_ISO_8859_ISO_8859_3_esdb_len; return esdb_ISO_8859_ISO_8859_3_esdb; }
169
        if (0 == strcmp(current_path, "ISO-8859/ISO-8859-4.esdb")) { *len = esdb_ISO_8859_ISO_8859_4_esdb_len; return esdb_ISO_8859_ISO_8859_4_esdb; }
170
        if (0 == strcmp(current_path, "ISO-8859/ISO-8859-5.esdb")) { *len = esdb_ISO_8859_ISO_8859_5_esdb_len; return esdb_ISO_8859_ISO_8859_5_esdb; }
171
        if (0 == strcmp(current_path, "ISO-8859/ISO-8859-6.esdb")) { *len = esdb_ISO_8859_ISO_8859_6_esdb_len; return esdb_ISO_8859_ISO_8859_6_esdb; }
172
        if (0 == strcmp(current_path, "ISO-8859/ISO-8859-7.esdb")) { *len = esdb_ISO_8859_ISO_8859_7_esdb_len; return esdb_ISO_8859_ISO_8859_7_esdb; }
173
        if (0 == strcmp(current_path, "ISO-8859/ISO-8859-8.esdb")) { *len = esdb_ISO_8859_ISO_8859_8_esdb_len; return esdb_ISO_8859_ISO_8859_8_esdb; }
174
        if (0 == strcmp(current_path, "ISO-8859/ISO-8859-9.esdb")) { *len = esdb_ISO_8859_ISO_8859_9_esdb_len; return esdb_ISO_8859_ISO_8859_9_esdb; }
175
        if (0 == strcmp(current_path, "EUC/EUC-CN.esdb")) { *len = esdb_EUC_EUC_CN_esdb_len; return esdb_EUC_EUC_CN_esdb; }
176
        if (0 == strcmp(current_path, "EUC/EUC-KR.esdb")) { *len = esdb_EUC_EUC_KR_esdb_len; return esdb_EUC_EUC_KR_esdb; }
177
        if (0 == strcmp(current_path, "GB/GB18030.esdb")) { *len = esdb_GB_GB18030_esdb_len; return esdb_GB_GB18030_esdb; }
178
        if (0 == strcmp(current_path, "GB/GBK.esdb")) { *len = esdb_GB_GBK_esdb_len; return esdb_GB_GBK_esdb; }
179
        if (0 == strcmp(current_path, "ISO646/ISO646-US.esdb")) { *len = esdb_ISO646_ISO646_US_esdb_len; return esdb_ISO646_ISO646_US_esdb; }
180
        if (0 == strcmp(current_path, "MISC/JISX0201-KANA.esdb")) { *len = esdb_MISC_JISX0201_KANA_esdb_len; return esdb_MISC_JISX0201_KANA_esdb; }
181
        if (0 == strcmp(current_path, "MISC/JISX0208@1990.esdb")) { *len = esdb_MISC_JISX0208_1990_esdb_len; return esdb_MISC_JISX0208_1990_esdb; }
182
        if (0 == strcmp(current_path, "MISC/JISX0212.esdb")) { *len = esdb_MISC_JISX0212_esdb_len; return esdb_MISC_JISX0212_esdb; }
183
        if (0 == strcmp(current_path, "MISC/Shift_JIS.esdb")) { *len = esdb_MISC_Shift_JIS_esdb_len; return esdb_MISC_Shift_JIS_esdb; }
184
        if (0 == strcmp(current_path, "UTF/UTF-16-INTERNAL.esdb")) { *len = esdb_UTF_UTF_16_INTERNAL_esdb_len; return esdb_UTF_UTF_16_INTERNAL_esdb; }
185
        if (0 == strcmp(current_path, "UTF/UTF-16-SWAPPED.esdb")) { *len = esdb_UTF_UTF_16_SWAPPED_esdb_len; return esdb_UTF_UTF_16_SWAPPED_esdb; }
186
        if (0 == strcmp(current_path, "UTF/UTF-16.esdb")) { *len = esdb_UTF_UTF_16_esdb_len; return esdb_UTF_UTF_16_esdb; }
187
        if (0 == strcmp(current_path, "UTF/UTF-16BE.esdb")) { *len = esdb_UTF_UTF_16BE_esdb_len; return esdb_UTF_UTF_16BE_esdb; }
188
        if (0 == strcmp(current_path, "UTF/UTF-16LE.esdb")) { *len = esdb_UTF_UTF_16LE_esdb_len; return esdb_UTF_UTF_16LE_esdb; }
189
        if (0 == strcmp(current_path, "UTF/UTF-32-INTERNAL.esdb")) { *len = esdb_UTF_UTF_32_INTERNAL_esdb_len; return esdb_UTF_UTF_32_INTERNAL_esdb; }
190
        if (0 == strcmp(current_path, "UTF/UTF-32-SWAPPED.esdb")) { *len = esdb_UTF_UTF_32_SWAPPED_esdb_len; return esdb_UTF_UTF_32_SWAPPED_esdb; }
191
        if (0 == strcmp(current_path, "UTF/UTF-32.esdb")) { *len = esdb_UTF_UTF_32_esdb_len; return esdb_UTF_UTF_32_esdb; }
192
        if (0 == strcmp(current_path, "UTF/UTF-32BE.esdb")) { *len = esdb_UTF_UTF_32BE_esdb_len; return esdb_UTF_UTF_32BE_esdb; }
193
        if (0 == strcmp(current_path, "UTF/UTF-32LE.esdb")) { *len = esdb_UTF_UTF_32LE_esdb_len; return esdb_UTF_UTF_32LE_esdb; }
194
195
        oficonv_log(1 /* debug */, "oficonv data file '", path, "' not present in built-in library.");
196
      }
197
    }
198
199
#endif /* DCMTK_ENABLE_BUILTIN_OFICONV_DATA */
200
0
    return NULL;
201
0
}
202
203
int
204
_citrus_map_file(struct _citrus_region * r,
205
    const char * path)
206
0
{
207
0
    struct stat st;
208
0
    size_t len;
209
0
    void *head;
210
0
    int fd, ret;
211
212
0
    ret = 0;
213
214
0
    _citrus_region_init(r, NULL, 0);
215
216
    /* check if we have a built-in array that we can use instead of loading from file */
217
0
    head = lookup_builtin_data_file(path, &len);
218
0
    if (head)
219
0
    {
220
0
        _citrus_region_init(r, head, len);
221
0
        return 0;
222
0
    }
223
224
    /* otherwise continue with the file system */
225
0
#ifdef O_CLOEXEC
226
0
    if ((fd = open(path, O_RDONLY | O_CLOEXEC)) == -1)
227
#else
228
    if ((fd = open(path, O_RDONLY)) == -1)
229
#endif
230
0
    {
231
0
        oficonv_log(3 /* warning */, "Failed to open oficonv data file '", path, "', check environment variable DCMICONVPATH");
232
0
        return (errno);
233
0
    }
234
0
    if (fstat(fd, &st)  == -1) {
235
0
        ret = errno;
236
0
        oficonv_log(3 /* warning */, "Failed to open oficonv data file '", path, "', check environment variable DCMICONVPATH");
237
0
        goto error;
238
0
    }
239
0
    if (!S_ISREG(st.st_mode)) {
240
0
        ret = EOPNOTSUPP;
241
0
        oficonv_log(3 /* warning */, "Failed to open oficonv data file '", path, "', check environment variable DCMICONVPATH");
242
0
        goto error;
243
0
    }
244
245
0
#ifdef MAP_FILE
246
0
    head = mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_FILE|MAP_PRIVATE, fd, (off_t)0);
247
#else
248
    head = mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_PRIVATE, fd, (off_t)0);
249
#endif
250
0
    if (head == MAP_FAILED) {
251
0
        ret = errno;
252
0
        goto error;
253
0
    }
254
0
    _citrus_region_init(r, head, (size_t)st.st_size);
255
0
    _citrus_set_is_file(r);
256
0
    oficonv_log(1 /* debug */, "Opened oficonv data file '", path, "'");
257
0
error:
258
0
    (void)close(fd);
259
0
    return (ret);
260
0
}
261
262
void
263
_citrus_unmap_file(struct _citrus_region *r)
264
0
{
265
0
    if (_citrus_region_head(r) != NULL) {
266
0
        if ( _citrus_is_file(r)) {
267
0
            (void)munmap(_citrus_region_head(r), _citrus_region_size(r));
268
0
        }
269
        _citrus_region_init(r, NULL, 0);
270
0
    }
271
0
}