Coverage Report

Created: 2025-07-23 07:04

/src/samba/third_party/heimdal/lib/roken/dumpdata.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2005 Kungliga Tekniska Högskolan
3
 * (Royal Institute of Technology, Stockholm, Sweden).
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 *
10
 * 1. Redistributions of source code must retain the above copyright
11
 *    notice, this list of conditions and the following disclaimer.
12
 *
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 *
17
 * 3. Neither the name of the Institute nor the names of its contributors
18
 *    may be used to endorse or promote products derived from this software
19
 *    without specific prior written permission.
20
 *
21
 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31
 * SUCH DAMAGE.
32
 */
33
34
#include <config.h>
35
36
#include "roken.h"
37
38
/*
39
 * Write datablob to a filename, don't care about errors.
40
 */
41
42
ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
43
rk_dumpdata (const char *filename, const void *buf, size_t size)
44
0
{
45
0
    int fd;
46
47
0
    fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, 0640);
48
0
    if (fd < 0)
49
0
  return;
50
0
    net_write(fd, buf, size);
51
0
    close(fd);
52
0
}
53
54
/* For not-regular files */
55
static int
56
undump_not_file(int fd, char **out, size_t *size, int nul_terminate)
57
0
{
58
0
    size_t lim = 10 * 1024 * 1024;
59
0
    size_t bufsz = 0;
60
0
    size_t sz = 0;
61
0
    char *buf = NULL;
62
0
    char *tmp;
63
64
0
    *out = NULL;
65
0
    if (size && *size != 0 && *size < lim)
66
0
        lim = *size;
67
0
    if (size)
68
0
        *size = 0;
69
70
    /*
71
     * We can't use net_read() if we're on WIN32 because that really wants a
72
     * socket FD, which is in a distinct FD namespace from those returned by
73
     * open() on Windows.
74
     */
75
0
    do {
76
0
        ssize_t bytes;
77
78
0
        if (sz == bufsz) {
79
0
            if (bufsz == 0)
80
0
                bufsz = 1024;
81
0
            else
82
0
                bufsz += bufsz >> 1;
83
84
0
            tmp = realloc(buf, bufsz);
85
0
            if (tmp == NULL) {
86
0
                free(buf);
87
0
                return ENOMEM;
88
0
            }
89
0
            buf = tmp;
90
0
        }
91
92
0
        bytes = read(fd, buf + sz, bufsz - sz);
93
0
        if (bytes == 0)
94
0
            break;
95
0
        if (bytes < 0 &&
96
0
            (errno == EAGAIN || errno == EWOULDBLOCK))
97
0
            continue;
98
0
        if (bytes < 0) {
99
0
            free(buf);
100
0
            return errno;
101
0
        }
102
0
        sz += bytes;
103
0
    } while (sz < lim);
104
105
0
    *out = buf;
106
0
    if (size)
107
0
        *size = sz;
108
109
0
    if (!nul_terminate)
110
0
        return 0;
111
112
0
    if (bufsz > sz) {
113
0
        buf[sz] = '\0';
114
0
        return 0;
115
0
    }
116
117
0
    *out = tmp = realloc(buf, bufsz + 1);
118
0
    if (tmp == NULL) {
119
0
        free(buf);
120
0
        return ENOMEM;
121
0
    }
122
0
    buf = tmp;
123
0
    buf[sz] = '\0';
124
0
    return 0;
125
0
}
126
127
/*
128
 * Read all data from a file, care about errors.
129
 *
130
 * If `*size' is not zero and the file is not a regular file, then up to that
131
 * many bytes will be read.
132
 *
133
 * Returns zero on success or a system error code on failure.
134
 */
135
136
ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
137
rk_undumpdata(const char *filename, void **buf, size_t *size)
138
0
{
139
0
    struct stat sb;
140
0
    int fd, ret;
141
0
    ssize_t sret;
142
143
0
    *buf = NULL;
144
145
0
    fd = open(filename, O_RDONLY, 0);
146
0
    if (fd < 0)
147
0
  return errno;
148
0
    if (fstat(fd, &sb) != 0){
149
0
  ret = errno;
150
0
  goto out;
151
0
    }
152
0
    if (!S_ISREG(sb.st_mode)) {
153
0
        char *char_buf;
154
155
0
        ret = undump_not_file(fd, &char_buf, size, 0);
156
0
        (void) close(fd);
157
0
        *buf = char_buf;
158
0
        return ret;
159
0
    }
160
161
0
    if (sb.st_size < 0)
162
0
        sb.st_size = 0;
163
0
    *buf = malloc(sb.st_size);
164
0
    if (*buf == NULL) {
165
0
  ret = ENOMEM;
166
0
  goto out;
167
0
    }
168
0
    *size = sb.st_size;
169
170
0
    sret = read(fd, *buf, *size);
171
0
    if (sret < 0)
172
0
  ret = errno;
173
0
    else if (sret != (ssize_t)*size)
174
0
  ret = EINVAL;
175
0
    else
176
0
  ret = 0;
177
178
0
  out:
179
0
    if (ret) {
180
0
  free(*buf);
181
0
  *buf = NULL;
182
0
    }
183
0
    close(fd);
184
0
    return ret;
185
0
}
186
187
/*
188
 * Read all text from a file.
189
 *
190
 * Outputs a C string.  It is up to the caller to check for embedded NULs.
191
 * The number of bytes read will be stored in `*size' if `size' is not NULL.
192
 *
193
 * If `size' is not NULL and `*size' is not zero and the file is not a regular
194
 * file, then up to that many bytes will be read.
195
 *
196
 * Returns zero on success or a system error code on failure.
197
 */
198
199
ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
200
rk_undumptext(const char *filename, char **out, size_t *size)
201
0
{
202
0
    struct stat sb;
203
0
    int fd, ret;
204
0
    ssize_t sret;
205
0
    char *buf;
206
207
0
    *out = NULL;
208
209
0
    fd = open(filename, O_RDONLY, 0);
210
0
    if (fd < 0)
211
0
        return errno;
212
0
    if (fstat(fd, &sb) != 0) {
213
0
        (void) close(fd);
214
0
  return errno;
215
0
    }
216
0
    if (!S_ISREG(sb.st_mode)) {
217
0
        ret = undump_not_file(fd, out, size, 1);
218
0
        (void) close(fd);
219
0
        return ret;
220
0
    }
221
222
0
    if (sb.st_size < 0)
223
0
        sb.st_size = 0;
224
0
    buf = malloc(sb.st_size + 1);
225
0
    if (buf == NULL) {
226
0
  ret = ENOMEM;
227
0
  goto out;
228
0
    }
229
0
    if (size)
230
0
        *size = sb.st_size;
231
232
0
    sret = read(fd, buf, sb.st_size);
233
0
    if (sret < 0)
234
0
  ret = errno;
235
0
    else if (sret != (ssize_t)sb.st_size)
236
0
  ret = EINVAL;
237
0
    else
238
0
  ret = 0;
239
240
0
out:
241
0
    if (ret) {
242
0
  free(buf);
243
0
    } else {
244
0
        buf[sb.st_size] = '\0';
245
0
        *out = buf;
246
0
    }
247
0
    close(fd);
248
0
    return ret;
249
0
}