add changelog
[platform/upstream/gdbm.git] / src / gdbmimp.c
1 /* gdbmimp.c - Import a GDBM database. */
2
3 /* This file is part of GDBM, the GNU data base manager.
4    Copyright (C) 2007, 2011, 2013 Free Software Foundation, Inc.
5
6    GDBM is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3, or (at your option)
9    any later version.
10
11    GDBM is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with GDBM. If not, see <http://www.gnu.org/licenses/>.   */
18
19 # include "autoconf.h"
20 # include <arpa/inet.h>
21
22 # include "gdbmdefs.h"
23 # include "gdbm.h"
24
25 int
26 gdbm_import_from_file (GDBM_FILE dbf, FILE *fp, int flag)
27 {
28   int seenbang, seennewline, rsize, size, kbufsize, dbufsize, rret;
29   int c;
30   char *kbuffer, *dbuffer;
31   datum key, data;
32   int count = 0;
33
34   seenbang = 0;
35   seennewline = 0;
36   kbuffer = NULL;
37   dbuffer = NULL;
38
39   /* Read (and discard) four lines begining with ! and ending with \n. */
40   while (1)
41     {
42       if ((c = fgetc (fp)) == -1)
43         goto read_fail;
44       
45       if (c == '!')
46         seenbang++;
47       if (c == '\n')
48         {
49           if (seenbang > 3 && seennewline > 2)
50             {
51               /* End of last line. */
52               break;
53             }
54           seennewline++;
55         }
56     }
57
58   /* Allocate buffers. */
59   kbufsize = 512;
60   kbuffer = malloc (kbufsize);
61   if (kbuffer == NULL)
62     {
63       gdbm_errno = GDBM_MALLOC_ERROR;
64       return -1;
65     }
66   dbufsize = 512;
67   dbuffer = malloc (dbufsize);
68   if (dbuffer == NULL)
69     {
70       free (kbuffer);
71       gdbm_errno = GDBM_MALLOC_ERROR;
72       return -1;
73     }
74
75   /* Insert/replace records in the database until we run out of file. */
76   while ((rret = fread (&rsize, sizeof (rsize), 1, fp)) == 1)
77     {
78       /* Read the key. */
79       size = ntohl (rsize);
80       if (size > kbufsize)
81         {
82           kbufsize = (size + 512);
83           kbuffer = realloc (kbuffer, kbufsize);
84           if (kbuffer == NULL)
85             {
86               free (dbuffer);
87               gdbm_errno = GDBM_MALLOC_ERROR;
88               return -1;
89             }
90         }
91       if (fread (kbuffer, size, 1, fp) != 1)
92         goto read_fail;
93
94       key.dptr = kbuffer;
95       key.dsize = size;
96
97       /* Read the data. */
98       if (fread (&rsize, sizeof (rsize), 1, fp) != 1)
99         goto read_fail;
100
101       size = ntohl (rsize);
102       if (size > dbufsize)
103         {
104           dbufsize = (size + 512);
105           dbuffer = realloc (dbuffer, dbufsize);
106           if (dbuffer == NULL)
107             {
108               free (kbuffer);
109               gdbm_errno = GDBM_MALLOC_ERROR;
110               return -1;
111             }
112         }
113       if (fread (dbuffer, size, 1, fp) != 1)
114         goto read_fail;
115
116       data.dptr = dbuffer;
117       data.dsize = size;
118
119       if (gdbm_store (dbf, key, data, flag) != 0)
120         {
121           /* Keep the existing errno. */
122           free (kbuffer);
123           free (dbuffer);
124           return -1;
125         }
126
127       count++;
128     }
129
130   if (rret == 0)
131     return count;
132
133 read_fail:
134
135   free (kbuffer);
136   free (dbuffer);
137   gdbm_errno = GDBM_FILE_READ_ERROR;
138   return -1;
139 }
140
141 int
142 gdbm_import (GDBM_FILE dbf, const char *importfile, int flag)
143 {
144   FILE *fp;
145   int rc;
146   
147   fp = fopen (importfile, "r");
148   if (!fp)
149     {
150       gdbm_errno = GDBM_FILE_OPEN_ERROR;
151       return -1;
152     }
153   rc = gdbm_import_from_file (dbf, fp, flag);
154   fclose (fp);
155   return rc;
156 }
157