1*9508192eSchristos /* Id: dba_write.c,v 1.3 2016/08/05 23:15:08 schwarze Exp */
2*9508192eSchristos /*
3*9508192eSchristos * Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org>
4*9508192eSchristos *
5*9508192eSchristos * Permission to use, copy, modify, and distribute this software for any
6*9508192eSchristos * purpose with or without fee is hereby granted, provided that the above
7*9508192eSchristos * copyright notice and this permission notice appear in all copies.
8*9508192eSchristos *
9*9508192eSchristos * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10*9508192eSchristos * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11*9508192eSchristos * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12*9508192eSchristos * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13*9508192eSchristos * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14*9508192eSchristos * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15*9508192eSchristos * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16*9508192eSchristos *
17*9508192eSchristos * Low-level functions for serializing allocation-based data to disk.
18*9508192eSchristos * The interface is defined in "dba_write.h".
19*9508192eSchristos */
20*9508192eSchristos #include "config.h"
21*9508192eSchristos
22*9508192eSchristos #include <assert.h>
23*9508192eSchristos #if HAVE_ENDIAN
24*9508192eSchristos #include <endian.h>
25*9508192eSchristos #elif HAVE_SYS_ENDIAN
26*9508192eSchristos #include <sys/endian.h>
27*9508192eSchristos #elif HAVE_NTOHL
28*9508192eSchristos #include <arpa/inet.h>
29*9508192eSchristos #endif
30*9508192eSchristos #if HAVE_ERR
31*9508192eSchristos #include <err.h>
32*9508192eSchristos #endif
33*9508192eSchristos #include <errno.h>
34*9508192eSchristos #include <fcntl.h>
35*9508192eSchristos #include <stdint.h>
36*9508192eSchristos #include <stdio.h>
37*9508192eSchristos
38*9508192eSchristos #include "dba_write.h"
39*9508192eSchristos
40*9508192eSchristos static FILE *ofp;
41*9508192eSchristos
42*9508192eSchristos
43*9508192eSchristos int
dba_open(const char * fname)44*9508192eSchristos dba_open(const char *fname)
45*9508192eSchristos {
46*9508192eSchristos ofp = fopen(fname, "w");
47*9508192eSchristos return ofp == NULL ? -1 : 0;
48*9508192eSchristos }
49*9508192eSchristos
50*9508192eSchristos int
dba_close(void)51*9508192eSchristos dba_close(void)
52*9508192eSchristos {
53*9508192eSchristos return fclose(ofp) == EOF ? -1 : 0;
54*9508192eSchristos }
55*9508192eSchristos
56*9508192eSchristos int32_t
dba_tell(void)57*9508192eSchristos dba_tell(void)
58*9508192eSchristos {
59*9508192eSchristos long pos;
60*9508192eSchristos
61*9508192eSchristos if ((pos = ftell(ofp)) == -1)
62*9508192eSchristos err(1, "ftell");
63*9508192eSchristos if (pos >= INT32_MAX) {
64*9508192eSchristos errno = EOVERFLOW;
65*9508192eSchristos err(1, "ftell = %ld", pos);
66*9508192eSchristos }
67*9508192eSchristos return pos;
68*9508192eSchristos }
69*9508192eSchristos
70*9508192eSchristos void
dba_seek(int32_t pos)71*9508192eSchristos dba_seek(int32_t pos)
72*9508192eSchristos {
73*9508192eSchristos if (fseek(ofp, pos, SEEK_SET) == -1)
74*9508192eSchristos err(1, "fseek(%d)", pos);
75*9508192eSchristos }
76*9508192eSchristos
77*9508192eSchristos int32_t
dba_align(void)78*9508192eSchristos dba_align(void)
79*9508192eSchristos {
80*9508192eSchristos int32_t pos;
81*9508192eSchristos
82*9508192eSchristos pos = dba_tell();
83*9508192eSchristos while (pos & 3) {
84*9508192eSchristos dba_char_write('\0');
85*9508192eSchristos pos++;
86*9508192eSchristos }
87*9508192eSchristos return pos;
88*9508192eSchristos }
89*9508192eSchristos
90*9508192eSchristos int32_t
dba_skip(int32_t nmemb,int32_t sz)91*9508192eSchristos dba_skip(int32_t nmemb, int32_t sz)
92*9508192eSchristos {
93*9508192eSchristos const int32_t out[5] = {0, 0, 0, 0, 0};
94*9508192eSchristos int32_t i, pos;
95*9508192eSchristos
96*9508192eSchristos assert(sz >= 0);
97*9508192eSchristos assert(nmemb > 0);
98*9508192eSchristos assert(nmemb <= 5);
99*9508192eSchristos pos = dba_tell();
100*9508192eSchristos for (i = 0; i < sz; i++)
101*9508192eSchristos if (nmemb - fwrite(&out, sizeof(out[0]), nmemb, ofp))
102*9508192eSchristos err(1, "fwrite");
103*9508192eSchristos return pos;
104*9508192eSchristos }
105*9508192eSchristos
106*9508192eSchristos void
dba_char_write(int c)107*9508192eSchristos dba_char_write(int c)
108*9508192eSchristos {
109*9508192eSchristos if (putc(c, ofp) == EOF)
110*9508192eSchristos err(1, "fputc");
111*9508192eSchristos }
112*9508192eSchristos
113*9508192eSchristos void
dba_str_write(const char * str)114*9508192eSchristos dba_str_write(const char *str)
115*9508192eSchristos {
116*9508192eSchristos if (fputs(str, ofp) == EOF)
117*9508192eSchristos err(1, "fputs");
118*9508192eSchristos dba_char_write('\0');
119*9508192eSchristos }
120*9508192eSchristos
121*9508192eSchristos void
dba_int_write(int32_t i)122*9508192eSchristos dba_int_write(int32_t i)
123*9508192eSchristos {
124*9508192eSchristos i = htobe32(i);
125*9508192eSchristos if (fwrite(&i, sizeof(i), 1, ofp) != 1)
126*9508192eSchristos err(1, "fwrite");
127*9508192eSchristos }
128