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