2 * rdlib.c - routines for manipulating RDOFF libraries (.rdl)
17 /* See Texinfo documentation about new RDOFF libraries format */
21 char *rdl_errors
[5] = {
22 "no error", "could not open file", "invalid file structure",
23 "file contains modules of an unsupported RDOFF version",
27 int rdl_verify(const char *filename
)
29 FILE *fp
= fopen(filename
, "rb");
33 static char lastverified
[256];
34 static int lastresult
= -1;
36 if (lastresult
!= -1 && !strcmp(filename
, lastverified
))
39 strcpy(lastverified
, filename
);
42 return (rdl_error
= lastresult
= 1);
47 while (fread(buf
+ i
, 1, 1, fp
) == 1 && buf
[i
] && i
< 257)
54 * A special module, eg a signature block or a directory.
55 * Format of such a module is defined to be:
56 * six char type identifier
57 * int32_t count bytes content
59 * so we can handle it uniformaly with RDOFF2 modules.
63 /* Currently, nothing useful to do with signature block.. */
67 if (strncmp(buf
, "RDOFF", 5)) {
68 return rdl_error
= lastresult
= 2;
69 } else if (buf
[5] != '2') {
70 return rdl_error
= lastresult
= 3;
73 fread(&length
, 4, 1, fp
);
74 fseek(fp
, length
, SEEK_CUR
); /* skip over the module */
77 return lastresult
= 0; /* library in correct format */
80 int rdl_open(struct librarynode
*lib
, const char *name
)
82 int i
= rdl_verify(name
);
87 lib
->name
= strdup(name
);
93 void rdl_close(struct librarynode
*lib
)
100 int rdl_searchlib(struct librarynode
*lib
, const char *label
, rdffile
* f
)
112 lib
->fp
= fopen(lib
->name
, "rb");
121 while (!feof(lib
->fp
)) {
123 * read the module name from the file, and prepend
124 * the library name and '.' to it.
126 strcpy(buf
, lib
->name
);
128 i
= strlen(lib
->name
);
131 while (fread(buf
+ i
, 1, 1, lib
->fp
) == 1 && buf
[i
] && i
< 512)
138 if (!strcmp(buf
+ t
, ".dir")) { /* skip over directory */
139 fread(&l
, 4, 1, lib
->fp
);
140 fseek(lib
->fp
, l
, SEEK_CUR
);
144 * open the RDOFF module
146 if (rdfopenhere(f
, lib
->fp
, &lib
->referenced
, buf
)) {
147 rdl_error
= 16 * rdf_errno
;
151 * read in the header, and scan for exported symbols
153 hdr
= malloc(f
->header_len
);
154 rdfloadseg(f
, RDOFF_HEADER
, hdr
);
156 while ((r
= rdfgetheaderrec(f
))) {
157 if (r
->type
!= 3) /* not an export */
160 if (!strcmp(r
->e
.label
, label
)) { /* match! */
161 free(hdr
); /* reset to 'just open' */
162 f
->header_loc
= NULL
; /* state... */
168 /* find start of next module... */
171 fseek(lib
->fp
, i
, SEEK_SET
);
175 * close the file if nobody else is using it
178 if (!lib
->referenced
) {
185 int rdl_openmodule(struct librarynode
*lib
, int moduleno
, rdffile
* f
)
194 lib
->fp
= fopen(lib
->name
, "rb");
197 return (rdl_error
= 1);
203 while (!feof(lib
->fp
)) {
204 strcpy(buf
, lib
->name
);
208 while (fread(buf
+ i
, 1, 1, lib
->fp
) == 1 && buf
[i
] && i
< 512)
214 if (buf
[t
] != '.') /* special module - not counted in the numbering */
215 cmod
++; /* of RDOFF modules - must be referred to by name */
217 if (cmod
== moduleno
) {
219 rdfopenhere(f
, lib
->fp
, &lib
->referenced
, buf
);
221 if (!lib
->referenced
) {
228 fread(buf
, 6, 1, lib
->fp
);
232 } else if (strncmp(buf
, "RDOFF", 5)) {
233 if (!--lib
->referenced
) {
237 return rdl_error
= 2;
238 } else if (buf
[5] != '2') {
239 if (!--lib
->referenced
) {
243 return rdl_error
= 3;
246 fread(&length
, 4, 1, lib
->fp
);
247 fseek(lib
->fp
, length
, SEEK_CUR
); /* skip over the module */
249 if (!--lib
->referenced
) {
253 return rdl_error
= 4; /* module not found */
256 void rdl_perror(const char *apname
, const char *filename
)
259 rdfperror(apname
, filename
);
261 fprintf(stderr
, "%s:%s:%s\n", apname
, filename
,
262 rdl_errors
[rdl_error
]);