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