First import
authorJoey Schulze <joey@infodrom.org>
Tue, 3 Jun 1997 20:54:54 +0000 (20:54 +0000)
committerJoey Schulze <joey@infodrom.org>
Tue, 3 Jun 1997 20:54:54 +0000 (20:54 +0000)
ChangeLog [new file with mode: 0644]
Makefile [new file with mode: 0644]
dtaus.1 [new file with mode: 0644]
dtaus.c [new file with mode: 0644]
dtaus.h [new file with mode: 0644]
dtaus.txt [new file with mode: 0644]
main.c [new file with mode: 0644]

diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..63c8198
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,11 @@
+Tue Jun  3 19:35:02 1997  Martin Schulze  <joey@finlandia.infodrom.north.de>
+
+       * Switched to CVS
+
+Mon Jun  2 21:12:56 1997  Martin Schulze  <joey@finlandia.infodrom.north.de>
+
+       * First official use of this module in 'Artis Studinetz Manager',
+       artisman for the students home at Artillerieweg 55a in Oldenburg,
+       Germany.
+       
+
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..f7225e1
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,31 @@
+#   Makefile - Datentraegeraustausch mit einer Bank
+#   Copyright (c) 1996  Martin Schulze <joey@artis.uni-oldenburg.de>
+#
+#   This program is free software; you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation; either version 2 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program; if not, write to the Free Software
+#   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#   $Id$
+#
+#   Needs the bigint module
+#
+
+CC = gcc
+CFLAGS = -Wall
+
+
+dtaus: dtaus.o main.o bigint.o
+       $(CC) -o dtaus dtaus.o main.o bigint.o
+
+clean:
+       rm -f *.o dtaus
diff --git a/dtaus.1 b/dtaus.1
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/dtaus.c b/dtaus.c
new file mode 100644 (file)
index 0000000..8e1bcf8
--- /dev/null
+++ b/dtaus.c
@@ -0,0 +1,878 @@
+/*
+    dtaus.c - Datenträgeraustausch mit einer Bank
+    Copyright (c) 1996  Martin Schulze <joey@artis.uni-oldenburg.de>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    $Id$
+ */
+
+#include "dtaus.h"
+#include "bigint.h"
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <time.h>
+#include <malloc.h>
+
+/*
+ *  First: Some control structures
+ */
+
+typedef struct
+{
+  char *name;
+  unsigned short int pos;
+  unsigned short int len;
+  int type;
+} dtaus_record;
+
+#define REC_A  1
+#define REC_C  2
+#define REC_E  3
+
+#define REQ    1
+#define OPT    2
+#define IGN    3
+
+dtaus_record recA[] = {
+  {"Art", 5, 2, REQ},
+  {"Name", 23, 27, REQ},
+  {"Konto", 60, 10, REQ},
+  {"BLZ", 7, 8, REQ},
+  {"Referenz", 70, 10, OPT},
+  {"Datum", 50, 6, IGN},
+  {NULL, 0, 0}
+};
+
+#define A_TRANS        0
+#define A_NAME 1
+#define A_KTO  2
+#define A_BLZ  3
+#define A_REF  4
+#define A_DATE 5
+#define A_LEN  6
+
+dtaus_record recC[] = {
+  {"Name", 93, 27, REQ},
+  {"Konto", 21, 10, REQ},
+  {"BLZ", 13, 8, REQ},
+  {"Transaktion", 44, 5, REQ},
+  {"Betrag", 50, 11, REQ},
+  {"Zweck", 155, 27, REQ},
+  {"myName", 128, 27, OPT},
+  {"myKonto", 69, 10, OPT},
+  {"myBLZ", 61, 8, OPT},
+  {"Text", 187, 29, OPT},
+  {"Extension", 216, 29, OPT},
+  {NULL, 0, 0}
+};
+
+#define C_NAME 0
+#define C_KTO  1
+#define C_BLZ  2
+#define C_TRANS        3
+#define C_VAL  4
+#define C_ZWECK        5
+#define C_MYNAM        6
+#define C_MYKTO        7
+#define C_MYBLZ        8
+#define C_TEXT 9
+#define C_EXT  10
+#define C_LEN  11
+
+dtaus_record recE[] = {
+  {"Anzahl", 10, 7, IGN},
+  {"Summe", 17, 13, IGN},
+  {"Kontos", 30, 17, IGN},
+  {"BLZs", 47, 17, IGN},
+  {NULL, 0, 0}
+};
+
+#define E_COUNT        0
+#define E_VAL  1
+#define E_KTO  2
+#define E_BLZ  3
+#define E_LEN  0
+
+/*
+ *  Second: Some low level routines
+ */
+
+size_t dtaus_nextrec (void **buf, FILE *f)
+{
+  bzero (buf, 128);
+  return fread(buf, 128, 1, f);
+}
+
+char *upcase(char *s)
+{
+  static char x[100];
+  static char *xp;
+  char *cp;
+
+  for (cp=s,xp=x; *cp; cp++,xp++) {
+    if (strchr(" 0123456789.,&-/+*$%ABCDEFGHIJKLMNOPQRSTUVWXYZ",*cp)) {
+       *xp = *cp;
+    } else if (strchr("abcdefghijklmnopqrstuvwxyz",*cp)) {
+      *xp = toupper(*cp);
+    } else if (strchr ("üÜäÄöÖß", *cp)) {
+      switch (*cp) {
+      case 'ü': *(xp++) = 'U'; *xp='E'; break;
+      case 'Ü': *(xp++) = 'U'; *xp='E'; break;
+      case 'ä': *(xp++) = 'A'; *xp='E'; break;
+      case 'Ä': *(xp++) = 'A'; *xp='E'; break;
+      case 'ö': *(xp++) = 'O'; *xp='E'; break;
+      case 'Ö': *(xp++) = 'O'; *xp='E'; break;
+      case 'ß': *(xp++) = 'S'; *xp='S'; break;
+      }
+    } else
+      *xp = ' ';
+  }
+  *xp = '\0';
+
+  return x;
+}
+
+char *downcase(char *s)
+{
+  static char x[100];
+  char *cp;
+
+  strcpy (x, s);
+  
+  for (cp=x;*cp;cp++)
+    if (isupper(*cp))
+      *cp = tolower(*cp);
+  return x;
+}
+
+char *strip_spaces (char *s)
+{
+  int i;
+  char *p;
+
+  for (i=strlen(s);(s[i-1] == ' '||s[i-1] == '\t')&&i>0; i--)
+    s[i-1] = '\0';
+  for (p=s; *p==' '; p++);
+  return p;
+}
+
+char *strip_zeros (char *s)
+{
+  char *p;
+
+  for (p=s; *p=='0'; p++);
+  return p;
+}
+
+char dtaus_char(void *buf, unsigned int pos)
+{
+  static char res;
+  char *bufp = buf;
+
+  bufp+=pos;
+  memcpy(&res, bufp, 1);
+  return res;
+}
+
+char *string2real(char *s)
+{
+  static char res[20];
+  char *cp = s;
+
+  cp+=strlen(s)-2;
+  strncpy(res, s, strlen(s)-2);
+  res[strlen(s)-2] = '.';
+  res[strlen(s)-1] = s[strlen(s)-2];
+  res[strlen(s)] = s[strlen(s)-1];
+  return res;
+}
+
+char *real2string(char *s)
+{
+  static char res[20];
+  char *cp;
+
+  strcpy(res, s);
+  for (cp=res; *cp&&!(*cp == ',')&&!(*cp == '.');cp++);
+  *(cp++) = *(cp+1);
+  *(cp++) = *(cp+1);
+  *cp = '\0';
+  return res;
+}
+
+char *string2trans (char *s)
+{
+  static char res[30];
+
+  res[0] = '\0';
+  if (!strcmp(s, "04000"))
+    sprintf (res, "Abbuchung");
+  else if (!strcmp(s, "05000"))
+    sprintf (res, "Einzug");
+  else if (!strcmp(s, "05005"))
+    sprintf (res, "E-Cash");
+  else if (!strcmp(s, "05006"))
+    sprintf (res, "E-Cash-A");
+  else if (!strcmp(s, "51000"))
+    sprintf (res, "Gutschrift");
+  else if (!strcmp(s, "53000"))
+    sprintf (res, "Lohn");
+  else if (!strncmp(s, "5400", 4))
+    sprintf (res, "Vermögen");
+  /*  else if (!strcmp(s, "56000"))
+    sprintf (res, ""); / * Überweisung öffentlicher Kassen */
+  return res;
+}
+
+char *trans2string (char *s)
+{
+  static char res[30];
+
+  res[0] = '\0';
+  if (!strcmp(s, "Abbuchung"))
+    sprintf (res, "04000");
+  else if (!strcmp(s, "Einzug"))
+    sprintf (res, "05000");
+  else if (!strcmp(s, "E-Cash"))
+    sprintf (res, "05005");
+  else if (!strcmp(s, "E-Cash-A"))
+    sprintf (res, "05006");
+  else if (!strcmp(s, "Gutschrift"))
+    sprintf (res, "51000");
+  else if (!strcmp(s, "Lohn"))
+    sprintf (res, "53000");
+  else if (!strncmp(s, "Vermögen", 4))
+    sprintf (res, "5400");
+  /*  else if (!strcmp(s, ""))
+    sprintf (res, "56000"); / * Überweisung öffentlicher Kassen */
+  return res;
+}
+
+char *string2ext (char *s)
+{
+  static char res[30];
+
+  res[0] = '\0';
+  if (!strcmp(s, "01"))
+    sprintf (res, "Klient");
+  else if (!strcmp(s, "02"))
+    sprintf (res, "Text");
+  else if (!strcmp(s, "03"))
+    sprintf (res, "Auftraggeber");
+  return res;
+}
+
+char *ext2string (char *s)
+{
+  static char res[3];
+
+  res[0] = '\0';
+  if (!strcmp(s, "Klient"))
+    sprintf (res, "01");
+  else if (!strcmp(s, "Text"))
+    sprintf (res, "02");
+  else if (!strcmp(s, "Auftraggeber"))
+    sprintf (res, "03");
+  return res;
+}
+    
+unsigned long int dtaus_int(void *buf, unsigned int pos, unsigned int len)
+{
+  char tmp[30];
+  char *bufp = buf;
+  static unsigned long int res;
+
+  bufp+=pos;
+  memcpy(tmp, bufp, len);
+  tmp[len] = '\0';
+  sscanf(tmp, "%lu", &res);
+  return res;
+}
+
+/*
+ * returns the first word in this line, returns it and shortens the
+ * line.
+ */
+char *extract_ident (char *line)
+{
+  char *c, *x, *y;
+  static char word[30];
+
+  if (strlen(line) > 0) {
+    x = index (line, ' ');
+    y = index (line, '\t');
+
+    if (!x && !y) {
+        strncpy(word, line, 29);
+        line[0] = '\0';
+        return word;
+    }
+
+    /* Check which index returns the lower value, and check if the
+       value is non-NULL */
+    if ((c = (x && x<y)?x:(y?y:x))) { 
+      strncpy(word, line, c - line);
+      word[c-line] = '\0';
+      for (;*c == '\t' || *c == ' '; c++);
+      for (x=line; *c; c++,x++)
+       *x = *c;
+      *x = '\0';
+      strcpy(word, downcase(word));
+      return word;
+    }
+    return NULL;
+  }
+  return line;
+}
+
+int rec_index(char *ident, int type)
+{
+  int i;
+  dtaus_record *rec = NULL;
+
+  switch (type) {
+  case REC_A:  rec = recA; break;
+  case REC_C:  rec = recC; break;
+  case REC_E:  rec = recE; break;
+  }
+
+  for (i=0; (rec[i].name); i++) {
+    if (!strcmp(ident, downcase(rec[i].name)))
+      return i;
+  }
+
+  return -1;
+}
+
+size_t control_nextline (void **buf, int len, FILE *f)
+{
+  char line[100];
+  char tmp[100];
+  char *cp;
+  int i;
+
+  bzero (line, sizeof(line));
+  bzero (buf, len);
+  cp = line;
+
+  while (!strlen(line) && (cp = fgets(line, 100, f))) {
+    if (strlen(line)) {
+      if (line[0] != '#') {
+       if (line[strlen(line)-1] != '\n') { 
+         strcpy(tmp, line);
+         while (tmp[strlen(tmp)-1] != '\n' && (cp = fgets(tmp, 100, f)));
+       } else
+         line[strlen(line)-1] = '\0';
+       if (line[strlen(line)-1] == '\r')
+         line[strlen(line)-1] = '\0';
+       for (i=strlen(line);(line[i-1] == ' '||line[i-1] == '\t')&&i>0; i--)
+         line[i-1] = '\0';
+       if (line[0] == '#')
+         line[0] = '\0';
+      } else
+       line[0] = '\0';
+    }
+  }
+  for (cp=line; *cp==' '; cp++);
+
+  if (strlen(cp)) {
+    memcpy(buf, cp, strlen(cp));
+    return 1;
+  } else
+    return 0;
+}
+
+char *get_date()
+{
+  static char res[10];
+  time_t timer;
+  struct tm *loctime;
+
+  timer = time ( NULL );
+  loctime = localtime(&timer);
+  sprintf(res, "%02d.%02d.%02d", loctime->tm_mday, loctime->tm_mon+1, loctime->tm_year);
+  return res;
+}
+
+void dtaus_prepareA(char *buf)
+{
+  int i;
+  time_t timer;
+  struct tm *loctime;
+  char tmp[10];
+
+  bzero (buf, 129);
+  timer = time ( NULL );
+  loctime = localtime(&timer);
+
+  buf[0] = '0';
+  buf[1] = '1';
+  buf[2] = '2';
+  buf[3] = '8';
+  buf[4] = 'A';
+  for (i=15;i<15+8; i++) buf[i] = '0';
+  sprintf(tmp, "%02d%02d%2d", loctime->tm_mday, loctime->tm_mon+1, loctime->tm_year);
+  for (i=0; i<6; i++) buf[50+i] = tmp[i];
+  for (i=56;i<56+4; i++) buf[i] = ' ';
+  for (i=70;i<70+10; i++) buf[i] = '0';
+  for (i=80;i<80+48; i++) buf[i] = ' ';
+}
+
+void dtaus_prepareC(char *buf)
+{
+  int i;
+
+  bzero (buf, 257);
+  buf[0] = '0';
+  buf[1] = '2';
+  buf[2] = '1';
+  buf[3] = '6';
+  buf[4] = 'C';
+  for (i=31;i<31+13; i++) buf[i] = '0';
+  buf[49] = ' ';
+  for (i=79;i<79+11; i++) buf[i] = '0';
+  for (i=90;i<90+3; i++) buf[i] = ' ';
+  for (i=120;i<120+8; i++) buf[i] = ' ';
+  for (i=182;i<182+3; i++) buf[i] = ' ';
+  for (i=185;i<185+2; i++) buf[i] = '0';
+  for (i=187;i<187+(29*2); i++) buf[i] = ' ';
+  for (i=245;i<245+11; i++) buf[i] = ' ';
+}
+
+void dtaus_prepareE(char *buf)
+{
+  int i;
+
+  bzero (buf, 129);
+  buf[0] = '0';
+  buf[1] = '1';
+  buf[2] = '2';
+  buf[3] = '8';
+  buf[4] = 'E';
+  for (i=5;i<5+5; i++) buf[i] = ' ';
+  for (i=64;i<64+13; i++) buf[i] = '0';
+  for (i=77;i<77+51; i++) buf[i] = ' ';
+}
+
+int dtaus_writeA(FILE *f, char **values)
+{
+  char buf[129];
+  char tmp[30];
+  int i;
+  
+  for (i=0; (recA[i].name); i++)
+    if ((recA[i].type == REQ) && !values[i]) {
+      fprintf (stderr, "Anfangsdatensatz ist nicht vollständig, kein %s.\n", recA[i].name);
+      return 0;
+    }
+  if (!(((values[A_TRANS][0] == 'L')||(values[A_TRANS][0] == 'G'))
+       &&((values[A_TRANS][1] == 'B')||(values[A_TRANS][1] == 'K')))) {
+    fprintf (stderr, "Ungueltiger Typ, nur LK, GK, LB oder GB erlaubt.\n");
+    return 0;
+  }
+
+  dtaus_prepareA(buf);
+  buf[5] = values[A_TRANS][0];
+  buf[6] = values[A_TRANS][1];
+  sprintf (tmp, "%08s", values[A_BLZ]);
+  for (i=0; i<8; i++) buf[recA[A_BLZ].pos+i] = tmp[i];
+  sprintf (tmp, "%-27s", upcase(values[A_NAME]));
+  for (i=0; i<27; i++) buf[recA[A_NAME].pos+i] = tmp[i];
+  sprintf (tmp, "%010s", values[A_KTO]);
+  for (i=0; i<10; i++) buf[recA[A_KTO].pos+i] = tmp[i];
+
+  fputs(buf, f);
+  return 1;
+}
+
+int dtaus_writeC(FILE *f, char **valuesA, char **values)
+{
+  char buf[257];
+  char tmp[30];
+  int i;
+
+  /*
+  for (i=0; (recC[i].name); i++)
+    if (values[i])
+      printf ("%s: %s\n", recC[i].name, values[i]);
+      */
+
+  for (i=0; (recC[i].name); i++)
+    if ((recC[i].type == REQ) && !values[i]) {
+      fprintf (stderr, "Datensatz ist nicht vollständig, kein %s.\n", recC[i].name);
+      return 0;
+    }
+  sprintf (tmp, "%s", trans2string(values[C_TRANS]));
+  if (!strlen(tmp)) {
+    fprintf (stderr, "Ungültiger Typ, nur Abbuchung, Einzug, E-Cash, E-Cash-A, Gutschrift und Lohn erlaubt.\n");
+    return 0;
+  }
+
+  dtaus_prepareC(buf);
+  if (!values[C_TEXT]) {
+    buf[1] = '1';
+    buf[2] = '8';
+    buf[3] = '7';
+  }
+  for (i=0; i<5; i++) buf[recC[C_TRANS].pos+i] = tmp[i];
+  if (values[C_MYBLZ])
+    sprintf (tmp, "%08s", values[C_MYBLZ]);
+  else
+    sprintf (tmp, "%08s", valuesA[A_BLZ]);
+  for (i=0; i<recC[C_MYBLZ].len; i++) buf[5+i] = tmp[i];
+  for (i=0; i<recC[C_MYBLZ].len; i++) buf[recC[C_MYBLZ].pos+i] = tmp[i];
+  sprintf (tmp, "%08s", values[C_BLZ]);
+  for (i=0; i<recC[C_BLZ].len; i++) buf[recC[C_BLZ].pos+i] = tmp[i];
+  sprintf (tmp, "%010s", values[C_KTO]);
+  for (i=0; i<recC[C_KTO].len; i++) buf[recC[C_KTO].pos+i] = tmp[i];
+  sprintf (tmp, "%011s", real2string(values[C_VAL]));
+  for (i=0; i<recC[C_VAL].len; i++) buf[recC[C_VAL].pos+i] = tmp[i];
+  if (values[C_MYKTO])
+    sprintf (tmp, "%010s", values[C_MYKTO]);
+  else
+    sprintf (tmp, "%010s", valuesA[A_KTO]);
+  for (i=0; i<recC[C_MYKTO].len; i++) buf[recC[C_MYKTO].pos+i] = tmp[i];
+  sprintf (tmp, "%-27s", upcase(values[C_NAME]));
+  for (i=0; i<recC[C_NAME].len; i++) buf[recC[C_NAME].pos+i] = tmp[i];
+  if (values[C_MYNAM])
+    sprintf (tmp, "%-27s", upcase(values[C_MYNAM]));
+  else
+    sprintf (tmp, "%-27s", upcase(valuesA[A_NAME]));
+  for (i=0; i<recC[C_MYNAM].len; i++) buf[recC[C_MYNAM].pos+i] = tmp[i];
+  sprintf (tmp, "%-27s", upcase(values[C_ZWECK]));
+  for (i=0; i<recC[C_ZWECK].len; i++) buf[recC[C_ZWECK].pos+i] = tmp[i];
+
+  if (!values[C_TEXT]) {
+    buf[recC[C_TEXT].pos+0] = ' ';
+    buf[recC[C_TEXT].pos+1] = ' ';
+  } else {
+    buf[185+0] = '0';
+    buf[185+1] = '1';
+    buf[recC[C_TEXT].pos+0] = '0';
+    buf[recC[C_TEXT].pos+1] = '2';
+    sprintf (tmp, "%-27s", upcase(values[C_TEXT]));
+    for (i=0; i<recC[C_TEXT].len-2; i++) buf[recC[C_TEXT].pos+2+i] = tmp[i];
+  }
+  fputs(buf, f);
+  return 1;
+}
+
+int dtaus_writeE(FILE *f, int count, bigint sum, bigint blz, bigint kto)
+{
+  char buf[129];
+  char tmp[30];
+  int i;
+  
+  dtaus_prepareE(buf);
+
+  sprintf (tmp, "%07d", count);
+  for (i=0; i<recE[E_COUNT].len; i++) buf[recE[E_COUNT].pos+i] = tmp[i];
+  bigint_sprintf (tmp, "%013s", sum);
+  for (i=0; i<recE[E_VAL].len; i++) buf[recE[E_VAL].pos+i] = tmp[i];
+  bigint_sprintf (tmp, "%013s", sum);
+  for (i=0; i<recE[E_VAL].len; i++) buf[recE[E_VAL].pos+i] = tmp[i];
+  bigint_sprintf (tmp, "%017s", kto);
+  for (i=0; i<recE[E_KTO].len; i++) buf[recE[E_KTO].pos+i] = tmp[i];
+  bigint_sprintf (tmp, "%017s", blz);
+  for (i=0; i<recE[E_BLZ].len; i++) buf[recE[E_BLZ].pos+i] = tmp[i];
+
+  fputs(buf, f);
+  return 1;
+}
+
+/*
+ *  Third: Some high level routines
+ */
+
+void dtaus2control (char *cdtaus, char *ccontrol)
+{
+  FILE *fdtaus, *fcontrol;
+  void *buf;
+  void *bufp;
+  char tmp[30];
+  char x[30];
+  int index, countC;
+
+  if (!cdtaus)
+    if (!(fdtaus = fopen("DTAUS0.TXT", "r")))
+      if (!(fdtaus = fopen("dtaus0.txt", "r")))
+       return;
+  if (cdtaus)
+    if (!(fdtaus = fopen(cdtaus, "r")))
+      return;
+  if (!ccontrol)
+    fcontrol = stdout;
+  else
+    if (!(fcontrol = fopen(ccontrol, "w")))
+      return;
+  if (!(buf = (char *)malloc (512)))
+    return;
+
+  /* 
+   * Record A lesen
+   */
+  if (dtaus_nextrec(buf, fdtaus) == 1) {
+    if (dtaus_char(buf,4) == 'A') {
+      fprintf(fcontrol, "BEGIN {\n");
+      bufp = buf;
+
+      for (index=A_TRANS; index < A_DATE; index++) {
+       bufp = buf + recA[index].pos;
+       memcpy(tmp, bufp, recA[index].len); tmp[recA[index].len] = '\0';
+       fprintf(fcontrol, "  %s\t%s\n", recA[index].name, strip_zeros(strip_spaces(tmp)));
+      }
+
+      index = A_DATE; bufp = buf + recA[index].pos;
+      memcpy(tmp, bufp, recA[index].len); tmp[recA[index].len] = '\0';
+      fprintf(fcontrol, "  %s\t%s\n", recA[index].name, strip_spaces(tmp));
+
+      fprintf(fcontrol, "}\n\n");
+    } else {
+      fprintf (stderr, "Datei fängt nicht mit dem Anfangsdatensatz an.\n");
+      return;
+    }
+  } else {
+    fprintf (stderr, "Der Anfangsdatensatz ist kaputt.\n");
+    return;
+  }
+
+  /*
+   * Record C lesen
+   */
+  if (dtaus_nextrec(buf, fdtaus) == 1) {
+    while (dtaus_char(buf,4) == 'C') {
+      bufp = buf + 128;
+      if (dtaus_nextrec(bufp, fdtaus) == 1) {
+       fprintf(fcontrol, "{\n");
+
+       for (index=C_NAME; index <= C_MYBLZ; index++) {
+         bufp = buf + recC[index].pos;
+         memcpy(tmp, bufp, recC[index].len); tmp[recC[index].len] = '\0';
+         if (index == C_VAL)
+           fprintf(fcontrol, "  %s\t%s\n", recC[index].name, strip_zeros(string2real(tmp)));
+         else if (index == C_TRANS)
+           fprintf(fcontrol, "  %s\t%s\n", recC[index].name, string2trans(tmp));
+         else
+           fprintf(fcontrol, "  %s\t%s\n", recC[index].name, strip_zeros(strip_spaces(tmp)));
+       }
+
+       for (index=C_TEXT; index <= C_EXT; index++) {
+         if (!(dtaus_char(buf,recC[index].pos) == ' ')) {
+           bufp = buf + recC[index].pos;
+           memcpy(x, bufp, 2); tmp[2] = '\0'; bufp+=2;
+           memcpy(tmp, bufp, recC[index].len-2); tmp[recC[index].len-2] = '\0';
+           fprintf(fcontrol, "  %s\t%s\n", string2ext(x), strip_spaces(tmp));
+         }
+       }
+
+       countC = dtaus_int(buf, 185, 2);
+       countC = countC<3?0:countC-2/4;
+       countC += countC%4>0?1:0;
+       /* FIXME: Erweiterungsfelder werden ignoriert */
+
+       fprintf(fcontrol, "}\n");
+      } else {
+       fprintf (stderr, "Der zweite Teil der Transaktion ist kaputt.\n");
+       return;
+      }
+      if (dtaus_nextrec(buf, fdtaus) != 1)
+       bzero (buf, sizeof(buf));
+    }
+  }
+
+  /*
+   * Record E lesen
+   *   (gelesen ist er eigentlich schon...)
+   */
+  if (dtaus_char(buf,4) == 'E') {
+    if (dtaus_char(buf,4) == 'E') {
+      fprintf(fcontrol, "END {\n");
+
+      for (index=E_COUNT; index <= E_BLZ; index++) {
+       bufp = buf + recE[index].pos;
+       memcpy(tmp, bufp, recE[index].len); tmp[recE[index].len] = '\0';
+       if (index == E_VAL)
+         fprintf(fcontrol, "  %s\t%s\n", recE[index].name, strip_zeros(string2real(tmp)));
+       else
+         fprintf(fcontrol, "  %s\t%s\n", recE[index].name, strip_zeros(tmp));
+      }
+
+      fprintf(fcontrol, "}\n");
+    } else {
+      fprintf (stderr, "Das ist kein Abschlußdatensatz.\n");
+      return;
+    }
+  } else {
+    fprintf (stderr, "Der Abschlußdatensatz ist leer oder kaputt.\n");
+    return;
+  }
+  fclose(fcontrol);
+  fclose(fdtaus);
+}
+
+int control2dtaus (char *ccontrol, char *cdtaus, char *cbeleg, char *ccheck)
+{
+  FILE *fdtaus, *fcontrol, *fbeleg, *fcheck;
+  void *buf;
+  char *ident;
+  int  recindex;
+  char tmp[30];
+  char line[100];
+  char *valA[A_LEN], *valC[C_LEN];
+  int count;
+  bigint sum_val, sum_blz, sum_kto, bi;
+
+  if (!cdtaus)
+    if (!(fdtaus = fopen("dtaus0.txt", "w")))
+      return 0;
+  if (cdtaus)
+    if (!(fdtaus = fopen(cdtaus, "w")))
+      return 0;
+  if (!ccontrol)
+    if (!(fcontrol = fopen("dtaus0.ctl", "r")))
+      if (!(fcontrol = fopen("DTAUS0.CTL", "r")))
+       return 0;
+  if (ccontrol)
+    if (!(fcontrol = fopen(ccontrol, "r")))
+      return 0;
+  if (!cbeleg)
+    if (!(fbeleg = fopen("dtaus0.doc", "w")))
+      return 0;
+  if (cbeleg)
+    if (!(fbeleg = fopen(cbeleg, "w")))
+      return 0;
+  if (!ccheck)
+    fcheck = stdout;
+  else
+    if (!(fcheck = fopen(ccheck, "w")))
+      return 0;
+
+
+  if (!(buf = (char *)malloc (512)))
+    return 0;
+
+  /* 
+   * Record A lesen
+   */
+  bzero(valA, sizeof(valA));
+  control_nextline ((void *)line, 100, fcontrol);
+  ident = extract_ident(line);
+  if (!strcmp(ident, "begin") && (line[0] == '{')) {
+    fprintf(fbeleg, "\n\n");
+    fprintf(fbeleg, "\n    Begleitzettel\n\n");
+    fprintf(fbeleg, "\n    Belegloser Datentraegeraustausch\n\n");
+    fprintf(fbeleg, "\n    Sammeleinzeiehungsauftrag\n\n");
+    fprintf(fbeleg, "\n    VOL ........................:\n");
+    fprintf(fbeleg, "\n    Erstellungsdatum ...........: %s\n", get_date());
+
+    control_nextline ((void *)line, 100, fcontrol);
+    while (strlen(line) && line[0] != '}') {
+      ident = extract_ident(line);
+      if ((recindex = rec_index(ident, REC_A)) != -1)
+       if (recA[recindex].type != IGN)
+         if ((valA[recindex] = (char *)malloc (strlen(line)+1)))
+           strcpy(valA[recindex], line);
+      control_nextline ((void *)line, 100, fcontrol);
+    }
+    if (!dtaus_writeA(fdtaus, valA)) {
+      fprintf (stderr, "Konnte den Anfangsdatensatz nicht schreiben.\n");
+      return 0;
+    }
+
+    fprintf (fcheck, "\n\n\n");
+    fprintf (fcheck, "    Sammeleinzeiehungsauftrag\n\n");
+    fprintf (fcheck, "    Erstellungsdatum : %s\n\n\n", get_date());
+    fprintf (fcheck, "     %-10s  %-8s  %-30s   %12s\n", "Kontonr.", "BLZ", "Name", "Betrag");
+    fprintf (fcheck, "    --------------------------------------------------------------------\n");
+  } else {
+    fprintf (stderr, "Datei fängt nicht mit dem Anfangsdatensatz (BEGIN) an.\n");
+    return 0;
+  }
+
+  /* 
+   * Record C lesen
+   */
+  count = 0;
+  sum_val = bigint_int(0);
+  sum_blz = bigint_int(0);
+  sum_kto = bigint_int(0);
+  bzero(valC, sizeof(valC));
+  control_nextline ((void *)line, 100, fcontrol);
+  if (line[0] == '{') {
+    while (strlen(line) && line[0] == '{') {
+      control_nextline ((void *)line, 100, fcontrol);
+      while (strlen(line) && line[0] != '}') {
+       ident = extract_ident(line);
+       if ((recindex = rec_index(ident, REC_C)) != -1)
+         if (recC[recindex].type != IGN)
+           if ((valC[recindex] = (char *)malloc (strlen(line)+1)))
+             strcpy(valC[recindex], line);
+       control_nextline ((void *)line, 100, fcontrol);
+      }
+      if (!dtaus_writeC(fdtaus, valA, valC)) {
+       fprintf (stderr, "Konnte den regulären Datensatz nicht schreiben.\n");
+       return 0;
+      }
+      count++;
+      bi = bigint_string(real2string(valC[C_VAL])); sum_val = bigint_add(sum_val, bi);
+      bi = bigint_string(valC[C_BLZ]); sum_blz = bigint_add(sum_blz, bi);
+      bi = bigint_string(valC[C_KTO]); sum_kto = bigint_add(sum_kto, bi);
+
+      fprintf (fcheck, "     %10s  %8s  %-30s   %12s\n", valC[C_KTO], valC[C_BLZ], valC[C_NAME], valC[C_VAL]);
+      for (recindex=0; recindex<C_LEN; recindex++)
+       if (valC[recindex])
+         free(valC[recindex]);
+      bzero(valC, sizeof(valC));
+      control_nextline ((void *)line, 100, fcontrol);
+    }
+  } else {
+    fprintf (stderr, "Kein regulärer Datensatz?\n");
+    return 0;
+  }
+
+  /* 
+   * Record E lesen
+   */
+  dtaus_writeE(fdtaus, count, sum_val, sum_blz, sum_kto);
+  fprintf (fcheck, "    --------------------------------------------------------------------\n");
+  bigint_sprintf (tmp, "%s", sum_val);
+  fprintf (fbeleg, "\n    Anzahl .....................: %d\n", count);
+  recindex=strlen(tmp);
+  tmp[recindex+1] = '\0';
+  tmp[recindex] = tmp[recindex-1];
+  tmp[recindex-1] = tmp[recindex-2];
+  tmp[recindex-2] = '.';
+  fprintf (fcheck, "     %-52s %14s\n", "Summe", tmp);
+  fprintf (fbeleg, "\n    Summe ......................: %s\n", tmp);
+  bigint_sprintf (tmp, "%s", sum_kto);
+  fprintf (fbeleg, "\n    Kontrollsumme Kontonummern .: %s\n", tmp);
+  bigint_sprintf (tmp, "%s", sum_blz);
+  fprintf (fbeleg, "\n    Kontrollsumme Bankleitzahlen: %s\n", tmp);
+  fprintf (fbeleg, "\n    Unsere Kontonummer .........: %s\n", valA[A_KTO]);
+  fprintf (fbeleg, "\n    Unsere Bankleitzahl ........: %s\n", valA[A_BLZ]);
+  fprintf (fbeleg, "\n\n\n\n\n    __________________________________________________\n");
+  fprintf (fbeleg, "    Ort, Datum                     Unterschrift\n");
+  for (recindex=0; recindex<A_LEN; recindex++)
+    if (valA[recindex])
+      free(valA[recindex]);
+  fclose(fdtaus);
+  fclose(fcontrol);
+  fclose(fbeleg);
+  if (ccheck)
+    fclose(fcheck);
+  return count;
+}
diff --git a/dtaus.h b/dtaus.h
new file mode 100644 (file)
index 0000000..4f96675
--- /dev/null
+++ b/dtaus.h
@@ -0,0 +1,29 @@
+/*
+    dtaus.h - Datentraegeraustausch mit einer Bank
+    Copyright (c) 1996  Martin Schulze <joey@artis.uni-oldenburg.de>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    $Id$
+ */
+
+#ifndef _DTAUS_H_
+#define _DTAUS_H_
+
+void dtaus2control (char *cdtaus, char *ccontrol);
+
+int control2dtaus (char *ccontrol, char *cdtaus, char *cbeleg, char *ccheck);
+
+#endif /* _DTAUS_H_ */
diff --git a/dtaus.txt b/dtaus.txt
new file mode 100644 (file)
index 0000000..e79fa3a
--- /dev/null
+++ b/dtaus.txt
@@ -0,0 +1,183 @@
+  $Id$
+
+  Datenträgeraustausch
+  ====================
+
+  Beim Datenträgeraustausch (DTA) werden Zahlungsverkehrsdaten - also
+  Überweisungen und Lastschriften - nicht mehr auf Papier, sondern
+  beleglos auf Disketten an das jeweilige Geldinstitut gegeben.  
+
+  Die Diskette, die zur Datenträgeraustauschdiskette benutzt wird, muß
+  formatiert und leer sein. Beschriften Sie die Diskette exakt!  Die
+  *einzige* Datei auf der Diskette muß DTAUS0.TXT heißen.  Zusätzlich
+  muß ein Begleitzettel begelegt werden.
+
+  Auf einer Diskette mit 360 KByte werden etwa max. 300 Datensätze
+  gespeichert.  Pro Zahlung werden zwischen 512 Bytes für die Datei
+  gespeichert.  Hinzukommen min. 256 Bytes pro Datensatz C.  Dies
+  bedeutet, daß ungefähr 1000 Zahlungen auf eine 360 KByte Diskette
+  übergeben werden können. 
+
+  Die Datei besteht aus drei Teilen:
+
+  Datensatz A - Header
+  Datensatz C - Body
+  Datensatz E - Footer
+
+  Der Body kann dabei mehrfach auftreten - einmal pro Zahlungsverkehr.
+
+  Alle Informationen liegen im ASCII-Format vor, keine wilden
+  Binärformate.
+
+  Aufbau Datensatz A
+  ------------------
+
+    0   4 Zeichen      Länge des Datensatzes, immer 128 Bytes, also immer "0128"
+    4   1 Zeichen      Datensatz-Typ, immer 'A'
+    5   2 Zeichen      Art der Transaktionen
+                       "LB" für Lastschriften Bankseitig
+                       "LK" für Lastschriften Kundenseitig
+                       "GB" für Gutschriften Bankseitig
+                       "GK" für Gutschriften Kundenseitig
+    7   8 Zeichen      Bankleitzahl des Auftraggebers
+   15   8 Zeichen      CST, "00000000"                [was auch immer das sein mag]
+   23  27 Zeichen      Name des Auftraggebers
+   50   6 Zeichen      aktuelles Datum im Format DDMMJJ
+   56   4 Zeichen      CST, "   " (Blanks)
+   60  10 Zeichen      Kontonummer des Auftraggebers
+   70  10 Zeichen      Optionale Referenznummer
+   80  48 Zeichen      Reserviert, 48 Blanks
+       -- 128 Zeichen
+
+  Aufbau Datensatz C
+  ------------------
+
+    0   4 Zeichen      Länge des Datensatzes, 187 + x * 29 (x..Anzahl Erweiterungsteile)
+    4   1 Zeichen      Datensatz-Typ, immer 'C'
+    5   8 Zeichen      Bankleitzahl des Auftraggebers (optional)
+   13   8 Zeichen      Bankleitzahl des Kunden
+   21  10 Zeichen      Kontonummer des Kunden
+   31  13 Zeichen      Reserviert, "0000000000000"
+   44   5 Zeichen      Art der Transaktion
+                       "04000" Lastschrift des Abbuchungsauftragsverfahren
+                       "05000" Lastschrift des Einzugsermächtigungsverfahren
+                       "05005" Lastschrift aus Verfügung im elec. Cash-System
+                       "05006" Wie 05005 mit ausländischen Karten
+                       "51000" Überweisungs-Gutschrift
+                       "53000" Überweisung Lohn/Gehalt/Rente
+                       "5400J" Vermögenswirksame Leistung (VL) ohne Sparzulage
+                       "5400J" Vermögenswirksame Leistung (VL) mit Sparzulage
+                       "56000" Überweisung öffentlicher Kassen
+                               Die im Textschlüssel mit J bezeichnete Stelle,
+                               wird bei Übernahme in eine Zahlung automatisch
+                               mit der jeweils aktuellen Jahresendziffer (7,
+                               wenn 97) ersetzt.
+   49   1 Zeichen      Reserviert, " " (Blank)
+   50  11 Zeichen      Betrag
+   61   8 Zeichen      Bankleitzahl des Auftraggebers
+   69  10 Zeichen      Kontonummer des Auftraggebers
+   79  11 Zeichen      Filler, "00000000000"
+   90   3 Zeichen      Reserviert, "   " (Blanks)
+   93  27 Zeichen      Name des Kunden
+  120   8 Zeichen      Reserviert, "        " (Blanks)
+       -- 128 Zeichen
+  128   27 Zeichen     Name des Auftraggebers
+  155   27 Zeichen     Verwendungszweck
+  182    3 Zeichen     Reserviert, "   " (Blanks)
+  185    2 Zeichen     Anzahl der Erweiterungsdatensätze, "00" bis "15"
+  187    2 Zeichen     Typ
+                       "01" Name des Kunden
+                       "02" Verwendungszweck
+                       "03" Name des Auftraggebers
+  189   27 Zeichen     Beschreibung gemäß Typ
+  216   29 Zeichen     wie die letzten 29 Zeichen oder 29 Blanks
+  245   11 Zeichen     11 Blanks
+       -- Ende des ersten Erweiterungsdatensatzes
+       -- 256 Zeichen
+
+  So können weitere Datensaetze angehängt werden.  Sie müssen im
+  Gesamten jedoch 128 Zeichen lang sein.  Also vier 29-Zeichen Blöcke
+  und anschließend mit 12 Blanks auffüllen.
+
+  Aufbau Datensatz E
+  ------------------
+
+    0   4 Zeichen      Länge des Datensatzes, immer 128 Bytes, also immer "0128"
+    4   1 Zeichen      Datensatz-Typ, immer 'E'
+    5   5 Zeichen      "     " (Blanks)
+   10   7 Zeichen      Anzahl der Datensätze (wahrscheinlich vom Typ C)
+   17  13 Zeichen      Kontrollsumme Beträge
+   30  17 Zeichen      Kontrollsumme Kontonummern
+   47  17 Zeichen      Kontrollsumme Bankleitzahlen
+   64  13 Zeichen      Reserviert, "0000000000000"
+   77  51 Zeichen      51 Blanks
+
+  Begleitzettel
+  -------------
+
+  Jede dem Geldinstitut gelieferte Diskette muß einen Begleitzettel
+  mit folgenden Mindestangaben enthalten.  Bei mehreren Disketten ist
+  für jede Diskette ein Begleitzettel auszuschreiben.
+
+    Begleitzettel
+
+    Belegloser Datenträgeraustausch
+
+    Sammel-Überweisung-/-einziehungsauftrag
+
+    Vol-Nummer der Diskette
+
+    Erstellungsdatum
+
+    Anzahl der Datensätze C(Stückzahl)
+
+    Summe DM der Datensätze C
+
+    Kontrollsumme der Kontonummern der
+
+    Überweisungsempfänger/Zahlungspflichtigen
+
+    Kontrollsumme der Bankleitzahlen der endbegünstigten
+
+    Kreditinstitute/Zahlungsstellen
+
+    Bankleitzahl/Kontonummer des Absenders
+
+    Name, Bankleitzahl/Kontonummer des Empfängers
+
+    Ort, Datum
+
+    Firma,Unterschrift
+
+  Sie haben die Pflicht, die Disketten zusätzlich durch Klebezettel
+  mit folgenden Angaben zu kennzeichnen.
+
+  Name und Bankleitzahll/Kontonummer des Diskettenabsenders.
+
+    Diskettennummer (VOL-Nummer).
+
+    Dateiname: DTAUS0.TXT 5.25 -und 3.5 Diskette.
+
+  API from dtaus.[ch]
+  -------------------
+
+  void
+  dtaus2control (char *cdtaus, char *ccontrol)
+
+    Diese Routine liest eine Datentraegerdatei aus und wandelt sie in
+    das eigene Kontrollformat zur weiteren Bearbeitung oder Kontrolle.
+
+    Wird als dtaus NULL angegeben, so wird DTAUS0.TXT und dtaus0.txt
+    probiert.  Ist das zweite Argument NULL, so wird auf stdout
+    geschrieben.
+
+  int
+  control2dtaus (char *ccontrol, char *cdtaus, char *cbeleg, char *ccheck)
+
+    Wandelt eine Datei im eigenen Kontrollformat in das genormte
+    Bankformat um.  Die Vorgaben für die Kontrolldatei sind dtaus0.ctl
+    und DTAUS0.CTL, fuer die Ausgabe dtaus0.txt.  Es werden zusätzlich
+    zwei Dateien erstellt.  Die Belegdatei muß unterschrieben mit der
+    Diskette zur Bank gebracht werden.  In der letzten Datei bzw. auf
+    stdout wird der Inhalt des Datentraegers für die Akten in einer
+    Tabelle ausgedruckt.
diff --git a/main.c b/main.c
new file mode 100644 (file)
index 0000000..b3ab351
--- /dev/null
+++ b/main.c
@@ -0,0 +1,24 @@
+/*
+    main.c - Datentraegeraustausch mit einer Bank
+    Copyright (c) 1996  Martin Schulze <joey@orgatech.de>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    $Id$
+ */
+
+main()
+{
+}