Initial version of email gateway under CVS control.
[egate.git] / util / iso2709.c
1 /*
2    gw-res.c: Iso2709 record management
3
4    Europagate, 1994-1995.
5
6    $Log: iso2709.c,v $
7    Revision 1.1.1.1  1995/02/09 17:27:11  adam
8    Initial version of email gateway under CVS control.
9
10  */
11
12 #include <stdlib.h>
13 #include <string.h>
14 #include <stdio.h>
15 #include <assert.h>
16 #include <ctype.h>
17
18 #include <iso2709p.h>
19
20 static int atoin (const char *buf, int n)
21 {
22     int val = 0;
23     while (--n >= 0)
24     {
25         if (isdigit(*buf))
26             val = val*10 + (*buf - '0');
27         buf++;
28     }
29     return val;
30 }
31
32 static void strncpyx (char *d, const char *s, int n)
33 {
34     while (--n >= 0 && *s)
35         if (*s != ISO2709_IDFS)
36             *d++ = *s++;
37         else
38         {
39             *d++ = ' ';
40             s++;
41         }
42     *d = '\0';
43 #if 0
44     strncpy (d, s, n);
45     d[n] = '\0';
46 #endif
47 }
48
49 char *iso2709_read (FILE *inf)
50 {
51     char length_str[5];
52     int size;
53     char *buf;
54
55     if (fread (length_str, 1, 5, inf) != 5)
56         return NULL;
57     size = atoin (length_str, 5);
58     if (size <= 6)
59         return NULL;
60     if (!(buf = malloc (size+1)))
61         return NULL;
62     if (fread (buf+5, 1, size-5, inf) != (size-5))
63     {
64         free (buf);
65         return NULL;
66     }
67     memcpy (buf, length_str, 5);
68     buf[size] = '\0';
69     return buf;
70 }
71
72 Iso2709Rec iso2709_cvt (const char *buf)
73 {
74     struct iso2709_dir **dpp, *dp;
75     int pos = 24;
76     Iso2709Rec p;
77
78     if (!(p = malloc (sizeof(*p))))
79         return NULL;
80
81     p->record_length = atoin (buf, 5);
82     strncpyx (p->record_status, buf+5, 1);
83     strncpyx (p->implementation_codes, buf+6, 4);
84     p->indicator_length = atoin (buf+10, 1);
85     p->identifier_length = atoin (buf+11, 1);
86     p->base_address = atoin (buf+12, 4);
87     strncpyx (p->user_systems, buf+17, 3);
88
89     p->length_data_entry = atoin (buf+20, 1);
90     p->length_starting = atoin (buf+21, 1);
91     p->length_implementation = atoin (buf+22, 1);
92     strncpyx (p->future_use, buf+23, 1);
93
94     dpp = &p->directory;
95
96     *dpp = NULL;
97     while (buf[pos] != ISO2709_FS)
98     {
99         *dpp = malloc (sizeof(**dpp));
100         (*dpp)->next = NULL;
101         strncpyx ((*dpp)->tag, buf+pos, 3);
102         pos += 3;
103         (*dpp)->length = atoin (buf+pos, p->length_data_entry);
104         pos += p->length_data_entry;
105         (*dpp)->offset = atoin (buf+pos, p->length_starting);
106         pos += p->length_starting + p->length_implementation;
107
108         dpp = &(*dpp)->next;
109     }
110     pos++;
111 #if 0
112     fprintf (stderr, "indicator_len=%d, identifier_len=%d\n", 
113              p->indicator_length, p->identifier_length);
114 #endif
115     for (dp = p->directory; dp; dp = dp->next)
116     {
117         int tag00;
118         struct iso2709_field **fpp;
119         int dpos = pos+dp->offset;
120         char *save_indicator = NULL;
121
122         fpp = &dp->fields;
123
124         *fpp = malloc (sizeof(**fpp));
125         (*fpp)->next = NULL;
126         if (p->indicator_length && memcmp (dp->tag, "00", 2))
127         {
128             (*fpp)->indicator = malloc (p->indicator_length+1);
129             strncpyx ((*fpp)->indicator, buf+dpos, p->indicator_length);
130             dpos += p->indicator_length;
131         }
132         else
133             (*fpp)->indicator = NULL;
134
135         if (memcmp (dp->tag, "00", 2))
136             tag00 = 0;
137         else
138             tag00 = 1;
139         fprintf (stderr, "%s", dp->tag);
140         while (1)
141         {
142             int dpos_n;
143             if (p->identifier_length && !tag00)
144             {
145                 (*fpp)->identifier = malloc (p->identifier_length+1);
146                 strncpyx ((*fpp)->identifier, buf+dpos+1,
147                           p->identifier_length-1);
148                 dpos += p->identifier_length;
149             }
150             else
151                 (*fpp)->identifier = NULL;
152
153             dpos_n = dpos;
154             while (buf[dpos_n] != ISO2709_FS && buf[dpos_n] != ISO2709_IDFS)
155                 dpos_n++;
156
157             (*fpp)->data = malloc (dpos_n - dpos + 1);
158             strncpyx ((*fpp)->data, buf+dpos, dpos_n - dpos);
159             dpos = dpos_n;
160             
161             if (!save_indicator && (*fpp)->indicator)
162                 fprintf (stderr, " %s", (*fpp)->indicator);
163             if ((*fpp)->identifier)
164                 fprintf (stderr, " *%s", (*fpp)->identifier);
165             fprintf (stderr, " %s", (*fpp)->data);
166             if (buf[dpos] == ISO2709_FS)
167                 break;
168             
169             save_indicator = (*fpp)->indicator;
170             fpp = &(*fpp)->next;
171             *fpp = malloc (sizeof(**fpp));
172             (*fpp)->next = NULL;
173             (*fpp)->indicator = save_indicator;
174         }
175         fprintf (stderr, "\n");
176     }
177     return p;
178 }