X-Git-Url: https://git.infodrom.org/?p=infodrom%2Fdtaus;a=blobdiff_plain;f=dtaus.c;h=ed82a84c61027cc8422f4df84ad02edb8347cc31;hp=e79f31b6a05297839dd8a83004a256f4cbd027d2;hb=87c267e06569b86963cd892eec40e7a68bdb3a01;hpb=185967934658309fe29d2d5ca5ed5b24716d90ff diff --git a/dtaus.c b/dtaus.c index e79f31b..ed82a84 100644 --- a/dtaus.c +++ b/dtaus.c @@ -1,6 +1,6 @@ /* dtaus.c - Datenträgeraustausch mit einer Bank - Copyright (c) 1996 Martin Schulze + Copyright (c) 1996,8,2001 Martin Schulze 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 @@ -14,7 +14,7 @@ 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. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. $Id$ */ @@ -22,11 +22,14 @@ #include "dtaus.h" #include "bigint.h" #include +#include #include #include #include #include +/* #define DEFAULT_EURO */ + /* * First: Some control structures */ @@ -54,6 +57,7 @@ dtaus_record recA[] = { {"BLZ", 7, 8, REQ}, {"Referenz", 70, 10, OPT}, {"Datum", 50, 6, IGN}, + {"Euro", 127, 1, OPT}, {NULL, 0, 0} }; @@ -63,7 +67,8 @@ dtaus_record recA[] = { #define A_BLZ 3 #define A_REF 4 #define A_DATE 5 -#define A_LEN 6 +#define A_EURO 6 +#define A_LEN 7 dtaus_record recC[] = { {"Name", 93, 27, REQ}, @@ -75,6 +80,7 @@ dtaus_record recC[] = { {"myName", 128, 27, OPT}, {"myKonto", 69, 10, OPT}, {"myBLZ", 61, 8, OPT}, + {"Euro", 182, 1, IGN}, {"Text", 187, 29, OPT}, {"Extension", 216, 29, OPT}, {NULL, 0, 0} @@ -89,9 +95,12 @@ dtaus_record recC[] = { #define C_MYNAM 6 #define C_MYKTO 7 #define C_MYBLZ 8 -#define C_TEXT 9 -#define C_EXT 10 -#define C_LEN 11 +#define C_EURO 9 +#define C_TEXT 10 +#define C_EXT 11 +#define C_LEN 12 + +#define MAX_TEXT 61 dtaus_record recE[] = { {"Anzahl", 10, 7, IGN}, @@ -139,6 +148,10 @@ char *upcase(char *s) case 'ß': *(xp++) = 'S'; *xp='S'; break; } } else + /* + * Filter out all other characters since credit institutes won't + * accept the file otherwise. + */ *xp = ' '; } *xp = '\0'; @@ -151,7 +164,8 @@ char *downcase(char *s) static char x[100]; char *cp; - strcpy (x, s); + memset (x, 0, sizeof (x)); + strncpy (x, s, 99); for (cp=x;*cp;cp++) if (isupper(*cp)) @@ -178,7 +192,20 @@ char *strip_zeros (char *s) return p; } -char dtaus_char(void *buf, unsigned int pos) +char *strip_nondigits (char *s) +{ + char *p; + char *x; + + for (x=s,p=s;*x;x++) + if (isdigit (*x)) + *(p++) = *x; + *(p++) = '\0'; + + return s; +} + +char dtaus_char (void *buf, unsigned int pos) { static char res; char *bufp = buf; @@ -268,7 +295,7 @@ char *string2ext (char *s) res[0] = '\0'; if (!strcmp(s, "01")) - sprintf (res, "Klient"); + sprintf (res, "Kunde"); else if (!strcmp(s, "02")) sprintf (res, "Text"); else if (!strcmp(s, "03")) @@ -281,7 +308,7 @@ char *ext2string (char *s) static char res[3]; res[0] = '\0'; - if (!strcmp(s, "Klient")) + if (!strcmp(s, "Kunde")) sprintf (res, "01"); else if (!strcmp(s, "Text")) sprintf (res, "02"); @@ -339,6 +366,28 @@ char *extract_ident (char *line) return line; } +/* + * Pads a string with zero's on the left side. + */ +char *padzeroclip (char *s, int len) +{ + char *p, *q; + + if (strlen(s) == len) return s; + if (strlen(s) > len) { + q=s+len; + *(q--) = '\0'; + return s; + } + + q=s+len; + *(q--) = '\0'; + for (p=s+strlen(s)-1;p>=s;p--) + *(q--)=*p; + for (;q>=s;) *(q--)='0'; + return s; +} + int rec_index(char *ident, int type) { int i; @@ -404,11 +453,15 @@ char *get_date() timer = time ( NULL ); loctime = localtime(&timer); - sprintf(res, "%02d.%02d.%02d", loctime->tm_mday, loctime->tm_mon+1, loctime->tm_year); + sprintf(res, "%02d.%02d.%02d", loctime->tm_mday, loctime->tm_mon+1, loctime->tm_year % 100); return res; } -void dtaus_prepareA(char *buf) +/* + * Prepare a record A according to the specs. + * See dtaus.txt for explanation + */ +void dtaus_prepareA (char *buf) { int i; time_t timer; @@ -424,36 +477,73 @@ void dtaus_prepareA(char *buf) 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] = ' '; + for (i=15;i<15+8; i++) buf[i] = '0'; /* A5 */ + sprintf(tmp, "%02d%02d%02d", loctime->tm_mday, loctime->tm_mon+1, loctime->tm_year % 100); + for (i=0; i<6; i++) buf[50+i] = tmp[i]; /* A7 (Date) */ + for (i=56;i<56+4; i++) buf[i] = ' '; /* A8 */ + for (i=70;i<70+10; i++) buf[i] = '0'; /* A10 */ + for (i=80;i<80+48; i++) buf[i] = ' '; /* A11 */ +#ifdef DEFAULT_EURO + buf[127] = '1'; /* A12 (Currency) */ +#else + buf[127] = ' '; /* A12 (Currency) */ +#endif } -void dtaus_prepareC(char *buf) +/* + * Prepare a record C according to the specs. + * See dtaus.txt for explanation + */ +void dtaus_prepareC (char *buf, int normaltext, int maxtext) { int i; + int appendix = 0; + div_t res; bzero (buf, 257); buf[0] = '0'; - buf[1] = '2'; - buf[2] = '1'; - buf[3] = '6'; + + if (normaltext) + appendix = 1; + if (maxtext) { + res = div (maxtext-1, 4); + appendix += res.quot; + if (res.rem) appendix++; + } + i = 187 + (appendix * 29); + + /* Bail out if the number is too large, shouldn't be possible though */ + if (i >= 1000) + exit (1); + + buf[1] = (i/100)+48;i-=(i/100)*100; + buf[2] = (i/10)+48;i-=(i/10)*10; + buf[3] = i+48; 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] = ' '; + + for (i=31;i<31+13; i++) buf[i] = '0'; /* C6 */ + buf[49] = ' '; /* C8 */ + for (i=50;i<50+11; i++) buf[i] = '0'; /* C9 (Betrag) */ + for (i=79;i<79+11; i++) buf[i] = '0'; /* C12 (Euro) */ + for (i=90;i<90+3; i++) buf[i] = ' '; /* C13 */ + for (i=93;i<90+27; i++) buf[i] = ' '; /* C14a (Kunde) */ + for (i=120;i<120+8; i++) buf[i] = ' '; /* C14b */ +#ifdef DEFAULT_EURO + buf[182] = '1'; /* C17a (Currency) */ +#else + buf[182] = ' '; /* C17a (Currency) */ +#endif + for (i=183;i<183+2; i++) buf[i] = ' '; /* C17b */ + for (i=185;i<185+2; i++) buf[i] = '0'; /* C18 (#Extension) */ + for (i=187;i<187+(29*2); i++) buf[i] = ' '; /* C19-C22 (misc text) */ + for (i=245;i<245+11; i++) buf[i] = ' '; /* C23 */ } -void dtaus_prepareE(char *buf) +/* + * Prepare a record E according to the specs. + * See dtaus.txt for explanation + */ +void dtaus_prepareE (char *buf) { int i; @@ -463,9 +553,10 @@ void dtaus_prepareE(char *buf) 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] = ' '; + for (i=5;i<5+5; i++) buf[i] = ' '; /* E3 */ + for (i=17;i<17+13; i++) buf[i] = '0'; /* E8 (Check Betrag) */ + for (i=64;i<64+13; i++) buf[i] = '0'; /* E8 (Check Euro) */ + for (i=77;i<77+51; i++) buf[i] = ' '; /* E9 */ } int dtaus_writeA(FILE *f, char **values) @@ -481,35 +572,45 @@ int dtaus_writeA(FILE *f, char **values) } 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"); + fprintf (stderr, "Ungültiger Typ, nur LK, GK, LB oder GB erlaubt.\n"); return 0; } + i=A_NAME;if (values[i] && strlen(values[i]) > recA[i].len) + values[i][recA[i].len] = '\0'; + dtaus_prepareA(buf); buf[5] = values[A_TRANS][0]; buf[6] = values[A_TRANS][1]; - sprintf (tmp, "%08s", values[A_BLZ]); + sprintf (tmp, "%s", padzeroclip (strip_nondigits (values[A_BLZ]),8)); for (i=0; i<8; i++) buf[recA[A_BLZ].pos+i] = tmp[i]; - sprintf (tmp, "%-27s", upcase(values[A_NAME])); + sprintf (tmp, "%-27.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]); + sprintf (tmp, "%s", padzeroclip (strip_nondigits (values[A_KTO]),10)); 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) +int dtaus_writeC(FILE *f, char **valuesA, char **values, char **text) { char buf[257]; + char appendix[129]; char tmp[30]; - int i; + int i, k; + int maxtext = 0; + int fieldnr; + div_t res; - /* + if (text) + for (maxtext=0;text[maxtext];maxtext++); + +#if DEBUG for (i=0; (recC[i].name); i++) if (values[i]) printf ("%s: %s\n", recC[i].name, values[i]); - */ +#endif for (i=0; (recC[i].name); i++) if ((recC[i].type == REQ) && !values[i]) { @@ -522,52 +623,85 @@ int dtaus_writeC(FILE *f, char **valuesA, char **values) return 0; } - dtaus_prepareC(buf); - if (!values[C_TEXT]) { - buf[1] = '1'; - buf[2] = '8'; - buf[3] = '7'; - } + i=C_TEXT;if (values[i] && strlen(values[i]) > recC[i].len) + values[i][recC[i].len] = '\0'; + i=C_ZWECK;if (values[i] && strlen(values[i]) > recC[i].len) + values[i][recC[i].len] = '\0'; + i=C_MYNAM;if (values[i] && strlen(values[i]) > recC[i].len) + values[i][recC[i].len] = '\0'; + i=C_TEXT;if (values[i] && strlen(values[i]) > recC[i].len) + values[i][recC[i].len] = '\0'; + i=C_EXT;if (values[i] && strlen(values[i]) > recC[i].len) + values[i][recC[i].len] = '\0'; + + dtaus_prepareC (buf, values[C_TEXT] != NULL, maxtext); for (i=0; i<5; i++) buf[recC[C_TRANS].pos+i] = tmp[i]; if (values[C_MYBLZ]) - sprintf (tmp, "%08s", values[C_MYBLZ]); + sprintf (tmp, "%s", padzeroclip (strip_nondigits (values[C_MYBLZ]),8)); else - sprintf (tmp, "%08s", valuesA[A_BLZ]); + sprintf (tmp, "%s", padzeroclip (strip_nondigits (valuesA[A_BLZ]),8)); for (i=0; i 1) { + fieldnr=1; + while (fieldnr0?1:0; - /* FIXME: Erweiterungsfelder werden ignoriert */ + /* Number of extension records for this C record */ + extC = dtaus_int(buf, 185, 2); - 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)); + + /* + * Are there extension records that we have to check? + * + * 2nd half of the AND is wrong, but since dtaus < 0.5 wrote 01 + * instead of 00 we should let it in so it can read its own + * old files... *sigh* + */ + while (extC > 0 && dtaus_char(buf,4) != 'C' && dtaus_char(buf,4) != 'E') { + for (index=0; index < 4; index++) { + if ((dtaus_char(buf,index*29) != ' ')) { + bufp = buf + index*29; + memcpy(x, bufp, 2); tmp[2] = '\0'; bufp+=2; + memcpy(tmp, bufp, recC[C_TEXT].len-2); tmp[recC[C_TEXT].len-2] = '\0'; + printctln(fcontrol, string2ext(x), strip_spaces(tmp)); + } + } + if (dtaus_nextrec(buf, fdtaus) != 1) + bzero (buf, sizeof(buf)); + extC--; + } + fprintf(fcontrol, "}\n"); } } @@ -700,15 +876,15 @@ void dtaus2control (char *cdtaus, char *ccontrol) */ if (dtaus_char(buf,4) == 'E') { if (dtaus_char(buf,4) == 'E') { - fprintf(fcontrol, "END {\n"); + fprintf(fcontrol, "\nEND {\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))); + printctln(fcontrol, recE[index].name, strip_zeros(string2real(tmp))); else - fprintf(fcontrol, " %s\t%s\n", recE[index].name, strip_zeros(tmp)); + printctln(fcontrol, recE[index].name, strip_zeros(tmp)); } fprintf(fcontrol, "}\n"); @@ -735,26 +911,38 @@ int control2dtaus (char *ccontrol, char *cdtaus, char *cbeleg, char *ccheck) char *valA[A_LEN], *valC[C_LEN]; int count; bigint sum_val, sum_blz, sum_kto, bi; + char **text = NULL; + char *cp; + int textindex = 0; - if (!cdtaus) + if (!cdtaus) { if (!(fdtaus = fopen("dtaus0.txt", "w"))) return 0; - if (cdtaus) - if (!(fdtaus = fopen(cdtaus, "w"))) - return 0; - if (!ccontrol) + } else { + if (!strcmp (cdtaus, "-")) + fdtaus = stdout; + else + 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) + } else { + if (!strcmp (ccontrol, "-")) + fcontrol = stdin; + else + if (!(fcontrol = fopen(ccontrol, "r"))) + return 0; + } + if (!cbeleg) { if (!(fbeleg = fopen("dtaus0.doc", "w"))) return 0; - if (cbeleg) + } else { if (!(fbeleg = fopen(cbeleg, "w"))) return 0; + } if (!ccheck) fcheck = stdout; else @@ -772,13 +960,6 @@ int control2dtaus (char *ccontrol, char *cdtaus, char *cbeleg, char *ccheck) 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 Sammeleinziehungsauftrag\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); @@ -788,14 +969,34 @@ int control2dtaus (char *ccontrol, char *cdtaus, char *cbeleg, char *ccheck) strcpy(valA[recindex], line); control_nextline ((void *)line, 100, fcontrol); } + if (((recindex = rec_index("art", REC_A)) != -1) && valA[recindex] && strlen(valA[recindex])) { + fprintf(fbeleg, "\n\n"); + fprintf(fbeleg, "\n Begleitzettel\n\n"); + fprintf(fbeleg, "\n Belegloser Datentraegeraustausch\n\n"); + if (valA[recindex][0] == 'L') + fprintf(fbeleg, "\n Sammeleinziehungsauftrag\n\n"); + else if (valA[recindex][0] == 'G') + fprintf(fbeleg, "\n Sammelueberweisungsauftrag\n\n"); + else + fprintf(fbeleg, "\n Sammelauftrag\n\n"); + fprintf(fbeleg, "\n VOL ........................:\n"); + fprintf(fbeleg, "\n Erstellungsdatum ...........: %s\n", get_date()); + fprintf(fbeleg, "\n Waehrung ...................: DM\n"); + } 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()); + if (valA[recindex][0] == 'L') + fprintf (fcheck, " Sammeleinziehungsauftrag\n\n"); + else if (valA[recindex][0] == 'G') + fprintf (fcheck, " Sammelueberweisungsauftrag\n\n"); + else + fprintf (fcheck, " Sammelauftrag\n\n"); + fprintf (fcheck, " Erstellungsdatum : %s\n\n", get_date()); + fprintf (fcheck, " Waehrung : DM\n\n\n"); fprintf (fcheck, " %-10s %-8s %-30s %12s\n", "Kontonr.", "BLZ", "Name", "Betrag"); fprintf (fcheck, " --------------------------------------------------------------------\n"); } else { @@ -815,15 +1016,45 @@ int control2dtaus (char *ccontrol, char *cdtaus, char *cbeleg, char *ccheck) if (line[0] == '{') { while (strlen(line) && line[0] == '{') { control_nextline ((void *)line, 100, fcontrol); + if (text) { + for (textindex=0; textindex < MAX_TEXT && text[textindex]; textindex++) + free (text[textindex]); + free (text); + text = NULL; + } 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); + if (recC[recindex].type != IGN) { + /* + * Special exception to support multiple Text fields + */ + if (recindex == C_TEXT && valC[recindex]) { + if (!text) { + if ((text = (char **)malloc ((MAX_TEXT+1) * sizeof (char *))) == NULL) + return 0; + else { + textindex = 0; + memset (text, 0, (MAX_TEXT+1) * sizeof (char *)); + } + } + if (textindex < MAX_TEXT) { + if ((cp = (char *)malloc (strlen (line) + 1))) { + strcpy (cp, line); + cp[strlen (line)] = '\0'; + text[textindex++] = cp; + } + } + } else { + if ((valC[recindex] = (char *)malloc (strlen(line)+1))) + strcpy(valC[recindex], line); + else + return 0; + } + } control_nextline ((void *)line, 100, fcontrol); } - if (!dtaus_writeC(fdtaus, valA, valC)) { + if (!dtaus_writeC(fdtaus, valA, valC, text)) { fprintf (stderr, "Konnte den regulären Datensatz nicht schreiben.\n"); return 0; }