gwenhywfar  5.10.1
olddb.c
Go to the documentation of this file.
1 /***************************************************************************
2  $RCSfile$
3  -------------------
4  cvs : $Id$
5  begin : Thu Oct 30 2003
6  copyright : (C) 2003 by Martin Preuss
7  email : martin@libchipcard.de
8 
9  ***************************************************************************
10  * *
11  * This library is free software; you can redistribute it and/or *
12  * modify it under the terms of the GNU Lesser General Public *
13  * License as published by the Free Software Foundation; either *
14  * version 2.1 of the License, or (at your option) any later version. *
15  * *
16  * This library is distributed in the hope that it will be useful, *
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
19  * Lesser General Public License for more details. *
20  * *
21  * You should have received a copy of the GNU Lesser General Public *
22  * License along with this library; if not, write to the Free Software *
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
24  * MA 02111-1307 USA *
25  * *
26  ***************************************************************************/
27 
28 
29 #ifdef HAVE_CONFIG_H
30 # include <config.h>
31 #endif
32 
33 #include "olddb_p.h"
34 #include <gwenhywfar/text.h>
35 #include <gwenhywfar/debug.h>
36 #include <gwenhywfar/stringlist.h>
37 #include <gwenhywfar/dbio_be.h>
38 #include <gwenhywfar/syncio_file.h>
39 #include <gwenhywfar/fastbuffer.h>
40 
41 #include <stdlib.h>
42 #include <string.h>
43 #include <assert.h>
44 #include <sys/types.h>
45 #include <sys/stat.h>
46 #include <fcntl.h>
47 #include <string.h>
48 #include <errno.h>
49 
50 /* We need a printf format specifier for "size_t" but <inttypes.h>
51  * does not have one. So in this one single exception we define our
52  * own, inspired from here:
53  * https://stackoverflow.com/questions/44382862/how-to-printf-a-size-t-without-warning-in-mingw-w64-gcc-7-1
54  */
55 #ifdef _WIN32
56 # ifdef _WIN64
57 # define PRI_SIZET PRIu64
58 # else
59 # define PRI_SIZET PRIu32
60 # endif
61 #else
62 # define PRI_SIZET "zd"
63 #endif
64 
65 
67  GWEN_DB_NODE *group,
68  const char *s,
69  uint32_t mode)
70 {
71  char name[256];
72  char *np;
73  char *p;
74  const char *g;
75  int i;
76  int quotes;
77  int esc;
78  int firstval;
79  GWEN_BUFFER *vbuf=NULL;
80 
81  assert(s);
82  name[0]=0;
83 
84  /* check for group definition */
85  g=s;
86  while (*g && (unsigned char)(*g)<33)
87  g++;
88  if (*g=='[') {
89  /* ok, parse group name */
90  GWEN_DB_NODE *grp;
91 
92  s=g;
93  s++;
94  while (*s && (unsigned char)(*s)<33)
95  s++;
96  p=name;
97  i=sizeof(name)-1;
98  while ((unsigned char)(*s)>31 && i && *s!=']' && *s!='#') {
99  *p=*s;
100  p++;
101  s++;
102  } /* while */
103  if (!i) {
104  DBG_ERROR(0, "Groupname is too long (limit is %" PRI_SIZET " chars)",
105  sizeof(name)-1);
106  return 0;
107  }
108  if (*s!=']') {
109  DBG_ERROR(0, "\"]\" expected");
110  return 0;
111  }
112  *p=0;
113  DBG_VERBOUS(0, "Selecting group \"%s\"", name);
114  grp=GWEN_DB_GetGroup(root, mode, name);
115  if (!grp) {
116  DBG_DEBUG(0, "Group \"%s\" is not available", name);
117  return 0;
118  }
119  return grp;
120  }
121 
122  /* get name */
123  while (*s && (unsigned char)(*s)<33)
124  s++;
125  i=sizeof(name)-1;
126  p=name;
127  while ((unsigned char)(*s)>31 && i-- && *s!='=' && *s!='#') {
128  *p=*s;
129  p++;
130  s++;
131  } /* while */
132  if (!i) {
133  DBG_ERROR(0, "Name is too long (limit is %" PRI_SIZET " chars)", sizeof(name)-1);
134  return 0;
135  }
136  *p=0;
137  np=name;
138 
139  /* post process name */
140  i=strlen(name)-1;
141  while (i>=0) {
142  if ((unsigned char)(name[i])<33)
143  name[i]=0;
144  else
145  break;
146  i--;
147  }
148 
149  i=strlen(name);
150  if (i>1) {
151  if (name[i-1]=='"' &&
152  name[0]=='"') {
153  name[i-1]=0;
154  np++;
155  }
156  }
157 
158  if ((unsigned char)(*s)<31 || *s=='#') {
159  DBG_VERBOUS(0, "Empty line");
160  return group;
161  }
162 
163  /* get equation mark */
164  if (*s!='=') {
165  DBG_ERROR(0, "\"=\" expected");
166  return 0;
167  }
168  s++;
169 
170  if (strlen(np)==0) {
171  DBG_ERROR(0, "Variable name must not be empty");
172  return 0;
173  }
174 
175  DBG_VERBOUS(0, "Creating variable \"%s\"", np);
176 
177 
178  firstval=1;
179  /* read komma separated values */
180 
181  vbuf=GWEN_Buffer_new(0, 64, 0, 1);
182  while ((unsigned char)(*s)>31) {
183  char *vp;
184 
185  /* skip komma that may occur */
186  while (*s && (unsigned char)(*s)<33)
187  s++;
188  if (*s==0) {
189  break;
190  }
191  if (*s==',') {
192  if (firstval) {
193  DBG_ERROR(0, "Unexpected comma");
194  GWEN_Buffer_free(vbuf);
195  return 0;
196  }
197  s++;
198  }
199  else {
200  if (!firstval) {
201  DBG_ERROR(0, "Comma expected");
202  GWEN_Buffer_free(vbuf);
203  return 0;
204  }
205  }
206 
207  /* get value */
208  while (*s && (unsigned char)(*s)<33)
209  s++;
210  /* copy value */
211  quotes=0;
212  esc=0;
213  i=GWEN_DBIO_OLDDB_MAXVALUE_LEN-1;
214  while ((unsigned char)(*s)>31 && i) {
215  if (esc) {
216  GWEN_Buffer_AppendByte(vbuf, *s);
217  i--;
218  esc=0;
219  }
220  else {
221  if (*s=='\\')
222  esc=1;
223  else if (*s=='"') {
224  quotes++;
225  if (quotes==2) {
226  s++;
227  break;
228  }
229  }
230  else if (*s=='#' && !(quotes&1))
231  break;
232  else if (*s==',' && !(quotes&1))
233  break;
234  else {
235  GWEN_Buffer_AppendByte(vbuf, *s);
236  i--;
237  }
238  }
239  s++;
240  } /* while */
241  if (!i) {
242  DBG_ERROR(0, "Value is too long (limit is %d chars)",
243  GWEN_DBIO_OLDDB_MAXVALUE_LEN-1);
244  GWEN_Buffer_free(vbuf);
245  return 0;
246  }
247  if (quotes&1) {
248  DBG_ERROR(0, "Unbalanced quotation marks");
249  GWEN_Buffer_free(vbuf);
250  return 0;
251  }
252  if (esc)
253  DBG_WARN(0, "Backslash at the end of the line");
254  *p=0;
255  vp=GWEN_Buffer_GetStart(vbuf);
256  /* post process value */
257  if (quotes==0) {
258  i=GWEN_Buffer_GetUsedBytes(vbuf);
259  if (i) {
260  i--;
261  while (i>=0) {
262  if ((unsigned char)(vp[i])<33)
263  vp[i]=0;
264  else
265  break;
266  i--;
267  }
268  }
269  i=strlen(vp);
270  if (i>1) {
271  if (vp[i-1]=='"' &&
272  vp[0]=='"') {
273  vp[i-1]=0;
274  vp++;
275  }
276  }
277  }
278 
279  /* create value, append it */
280  DBG_VERBOUS(0, " Creating value \"%s\"", vp);
281  GWEN_DB_SetCharValue(group, mode, np, vp);
282  GWEN_Buffer_Reset(vbuf);
283 
284  if (*s=='#')
285  break;
286  firstval=0;
287  } /* while (reading values) */
288 
289  GWEN_Buffer_free(vbuf);
290 
291  return group;
292 }
293 
294 
295 
297  GWEN_SYNCIO *sio,
298  GWEN_DB_NODE *data,
300  uint32_t flags)
301 {
302  GWEN_DB_NODE *curr;
303  int ln;
304  int gerr;
305  GWEN_BUFFER *lbuffer;
306  GWEN_FAST_BUFFER *fb;
307 
308  assert(data);
309 
310  fb=GWEN_FastBuffer_new(512, sio);
311  lbuffer=GWEN_Buffer_new(0, 256, 0, 1);
312  curr=data;
313  ln=1;
314 
315  for (;;) {
316  GWEN_Buffer_Reset(lbuffer);
317  gerr=GWEN_FastBuffer_ReadLineToBuffer(fb, lbuffer);
318  if (gerr) {
319  GWEN_Buffer_free(lbuffer);
320  if (gerr==GWEN_ERROR_EOF && ln) {
322  return 0;
323  }
324  else {
325  DBG_ERROR_ERR(0, gerr);
326  return gerr;
327  }
328  }
329  curr=GWEN_DBIO_OldDb__ParseLine(data, curr, GWEN_Buffer_GetStart(lbuffer), flags);
330  if (!curr) {
331  DBG_ERROR(0, "Error in input stream (line %d)", ln);
332  GWEN_Buffer_free(lbuffer);
334  return GWEN_ERROR_BAD_DATA;
335  }
336  ln++;
337  } /* while */
338 }
339 
340 
341 
346  GWEN_UNUSED uint32_t flags)
347 {
348  DBG_ERROR(GWEN_LOGDOMAIN, "Export function not supported");
349  return GWEN_ERROR_GENERIC;
350 }
351 
352 
353 
355 {
356  int rv;
357  GWEN_SYNCIO *sio;
358  GWEN_DB_NODE *dbTmp;
359  GWEN_DB_NODE *dbCfg;
360 
363  rv=GWEN_SyncIo_Connect(sio);
364  if (rv<0) {
365  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
366  GWEN_SyncIo_free(sio);
368  }
369 
370  dbTmp=GWEN_DB_Group_new("tmp");
371  dbCfg=GWEN_DB_Group_new("cfg");
372  rv=GWEN_DBIO_OldDb_Import(dbio, sio, dbTmp, dbCfg, GWEN_DB_FLAGS_DEFAULT);
373 
374  GWEN_DB_Group_free(dbCfg);
375  GWEN_DB_Group_free(dbTmp);
376 
378  GWEN_SyncIo_free(sio);
379 
380  if (rv) {
382  }
384 }
385 
386 
387 
389 {
390  GWEN_DBIO *dbio;
391 
392  dbio=GWEN_DBIO_new("OldDb", "Imports and exports Old OpenHBCI data");
396  return dbio;
397 }
398 
399 
400 
402  const char *modName,
403  const char *fileName)
404 {
405  GWEN_PLUGIN *pl;
406 
407  pl=GWEN_DBIO_Plugin_new(pm, modName, fileName);
408  assert(pl);
409 
411 
412  return pl;
413 
414 }
415 
416 
417 
int GWEN_DBIO_OldDb_Export(GWEN_UNUSED GWEN_DBIO *dbio, GWEN_UNUSED GWEN_SYNCIO *sio, GWEN_UNUSED GWEN_DB_NODE *data, GWEN_UNUSED GWEN_DB_NODE *cfg, GWEN_UNUSED uint32_t flags)
Definition: olddb.c:342
struct GWEN_PLUGIN_MANAGER GWEN_PLUGIN_MANAGER
Definition: plugin.h:40
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
int GWEN_SyncIo_Connect(GWEN_SYNCIO *sio)
Definition: syncio.c:97
struct GWEN_DB_NODE GWEN_DB_NODE
Definition: db.h:228
struct GWEN_PLUGIN GWEN_PLUGIN
Definition: plugin.h:39
GWEN_DBIO * GWEN_DBIO_new(const char *name, const char *descr)
Definition: dbio.c:207
GWEN_DB_NODE * GWEN_DBIO_OldDb__ParseLine(GWEN_DB_NODE *root, GWEN_DB_NODE *group, const char *s, uint32_t mode)
Definition: olddb.c:66
void GWEN_DB_Group_free(GWEN_DB_NODE *n)
Definition: db.c:421
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
Definition: buffer.c:277
#define GWEN_SYNCIO_FILE_FLAGS_READ
Definition: syncio_file.h:53
GWEN_DBIO_CHECKFILE_RESULT GWEN_DBIO_OldDb_CheckFile(GWEN_DBIO *dbio, const char *fname)
Definition: olddb.c:354
#define NULL
Definition: binreloc.c:300
int GWEN_FastBuffer_ReadLineToBuffer(GWEN_FAST_BUFFER *fb, GWEN_BUFFER *buf)
Definition: fastbuffer.c:95
#define DBG_VERBOUS(dbg_logger, format, args...)
Definition: debug.h:224
void GWEN_DBIO_SetCheckFileFn(GWEN_DBIO *dbio, GWEN_DBIO_CHECKFILEFN f)
Definition: dbio.c:344
void GWEN_FastBuffer_free(GWEN_FAST_BUFFER *fb)
Definition: fastbuffer.c:46
#define DBG_WARN(dbg_logger, format, args...)
Definition: debug.h:125
#define DBG_ERROR_ERR(dbg_logger, dbg_err)
Definition: debug.h:113
#define GWEN_LOGDOMAIN
Definition: logger.h:35
void GWEN_DBIO_SetImportFn(GWEN_DBIO *dbio, GWEN_DBIO_IMPORTFN f)
Definition: dbio.c:329
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:42
void GWEN_Buffer_Reset(GWEN_BUFFER *bf)
Definition: buffer.c:650
#define GWEN_ERROR_BAD_DATA
Definition: error.h:121
int GWEN_DBIO_OldDb_Import(GWEN_UNUSED GWEN_DBIO *dbio, GWEN_SYNCIO *sio, GWEN_DB_NODE *data, GWEN_UNUSED GWEN_DB_NODE *cfg, uint32_t flags)
Definition: olddb.c:296
#define PRI_SIZET
Definition: olddb.c:62
struct GWEN_SYNCIO GWEN_SYNCIO
Definition: syncio.h:40
GWEN_DBIO * GWEN_DBIO_OldDb_Factory(GWEN_UNUSED GWEN_PLUGIN *pl)
Definition: olddb.c:388
#define DBG_DEBUG(dbg_logger, format, args...)
Definition: debug.h:214
#define GWEN_ERROR_GENERIC
Definition: error.h:62
int GWEN_Buffer_AppendByte(GWEN_BUFFER *bf, char c)
Definition: buffer.c:394
GWEN_DB_NODE * GWEN_DB_GetGroup(GWEN_DB_NODE *n, uint32_t flags, const char *path)
Definition: db.c:1381
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:89
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:38
void GWEN_SyncIo_free(GWEN_SYNCIO *sio)
Definition: syncio.c:78
void GWEN_SyncIo_AddFlags(GWEN_SYNCIO *sio, uint32_t fl)
Definition: syncio.c:179
void GWEN_DBIO_Plugin_SetFactoryFn(GWEN_PLUGIN *pl, GWEN_DBIO_PLUGIN_FACTORYFN f)
Definition: dbio.c:188
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
#define GWEN_ERROR_EOF
Definition: error.h:96
struct GWEN_DBIO GWEN_DBIO
Definition: dbio.h:43
int GWEN_SyncIo_Disconnect(GWEN_SYNCIO *sio)
Definition: syncio.c:109
void GWEN_DBIO_SetExportFn(GWEN_DBIO *dbio, GWEN_DBIO_EXPORTFN f)
Definition: dbio.c:337
GWEN_PLUGIN * dbio_olddb_factory(GWEN_PLUGIN_MANAGER *pm, const char *modName, const char *fileName)
Definition: olddb.c:401
int GWEN_DB_SetCharValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const char *val)
Definition: db.c:997
GWEN_DBIO_CHECKFILE_RESULT
Definition: dbio.h:79
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:181
GWEN_DB_NODE * GWEN_DB_Group_new(const char *name)
Definition: db.c:173
GWENHYWFAR_API GWEN_SYNCIO * GWEN_SyncIo_File_new(const char *path, GWEN_SYNCIO_FILE_CREATIONMODE cm)
GWEN_FAST_BUFFER * GWEN_FastBuffer_new(uint32_t bsize, GWEN_SYNCIO *io)
Definition: fastbuffer.c:27
#define GWEN_UNUSED
#define GWEN_DB_FLAGS_DEFAULT
Definition: db.h:168
GWEN_PLUGIN * GWEN_DBIO_Plugin_new(GWEN_PLUGIN_MANAGER *pm, const char *name, const char *fileName)
Definition: dbio.c:147