9 * format of RDOFF library files:
10 * optional signature ('.sig')
12 * null terminated module name (max 255 chars)
15 * optional directory ('.dir')
21 * No support exists yet for special modules. But we aren't using
22 * any special modules yet. They are only defined now so that their
23 * existance doesn't break older versions of the linker... presently
24 * anything whose name begins with '.' is ignored.
29 char *rdl_errors
[5] = {
30 "no error","could not open file", "invalid file structure",
31 "file contains modules of an unsupported RDOFF version",
34 int rdl_verify(const char * filename
)
36 FILE * fp
= fopen(filename
, "rb");
40 static char lastverified
[256];
41 static int lastresult
= -1;
43 if (lastresult
!= -1 && !strcmp(filename
, lastverified
))
46 strcpy(lastverified
, filename
);
49 return (rdl_error
= lastresult
= 1);
55 while (fread(buf
+ i
,1,1,fp
) == 1 && buf
[i
] && i
< 257)
61 * A special module, eg a signature block or a directory.
62 * Format of such a module is defined to be:
63 * six char type identifier
64 * long count bytes content
66 * so we can handle it uniformaly with RDOFF2 modules.
70 /* Currently, nothing useful to do with signature block.. */
74 if (strncmp(buf
, "RDOFF", 5)) {
75 return rdl_error
= lastresult
= 2;
76 } else if (buf
[5] != '2') {
77 return rdl_error
= lastresult
= 3;
80 fread(&length
, 4, 1, fp
);
81 fseek(fp
, length
, SEEK_CUR
); /* skip over the module */
84 return lastresult
= 0; /* library in correct format */
87 int rdl_open (struct librarynode
* lib
, const char * name
)
89 int i
= rdl_verify(name
);
93 lib
->name
= strdup(name
);
99 void rdl_close (struct librarynode
* lib
)
106 int rdl_searchlib (struct librarynode
* lib
,
107 const char * label
, rdffile
* f
)
120 lib
->fp
= fopen(lib
->name
,"rb");
130 while (! feof(lib
->fp
) )
133 * read the module name from the file, and prepend
134 * the library name and '.' to it.
136 strcpy(buf
, lib
->name
);
138 i
= strlen(lib
->name
);
139 buf
[i
++] = '.'; t
= i
;
140 while (fread(buf
+ i
,1,1,lib
->fp
) == 1 && buf
[i
] && i
< 512)
145 if (feof(lib
->fp
)) break;
146 if (!strcmp(buf
+ t
, ".dir")) /* skip over directory */
148 fread (&l
, 4, 1, lib
->fp
);
149 fseek (lib
->fp
, l
, SEEK_CUR
);
153 * open the RDOFF module
155 if ( rdfopenhere(f
,lib
->fp
,&lib
->referenced
,buf
) ) {
156 rdl_error
= 16 * rdf_errno
;
160 * read in the header, and scan for exported symbols
162 hdr
= malloc(f
->header_len
);
163 rdfloadseg(f
,RDOFF_HEADER
,hdr
);
165 while ((r
= rdfgetheaderrec(f
)))
167 if (r
->type
!= 3) /* not an export */
170 if (! strcmp(r
->e
.label
, label
) ) /* match! */
172 free(hdr
); /* reset to 'just open' */
173 f
->header_loc
= NULL
; /* state... */
179 /* find start of next module... */
182 fseek(lib
->fp
,i
,SEEK_SET
);
186 * close the file if nobody else is using it
189 if (! lib
->referenced
)
197 int rdl_openmodule (struct librarynode
* lib
, int moduleno
, rdffile
* f
)
207 lib
->fp
= fopen(lib
->name
, "rb");
210 return (rdl_error
= 1);
217 while (!feof(lib
->fp
))
219 strcpy(buf
, lib
->name
);
221 buf
[i
++] = '.'; t
= i
;
222 while (fread(buf
+ i
,1,1,lib
->fp
) == 1 && buf
[i
] && i
< 512)
225 if (feof(lib
->fp
)) break;
227 if (buf
[t
] != '.') /* special module - not counted in the numbering */
228 cmod
++; /* of RDOFF modules - must be referred to by name */
230 if (cmod
== moduleno
) {
232 rdfopenhere(f
, lib
->fp
, &lib
->referenced
, buf
);
234 if (!lib
->referenced
) {
241 fread(buf
, 6, 1, lib
->fp
);
246 else if (strncmp(buf
, "RDOFF", 5)) {
247 if (! --lib
->referenced
) {
251 return rdl_error
= 2;
253 else if (buf
[5] != '2') {
254 if (! --lib
->referenced
) {
258 return rdl_error
= 3;
261 fread(&length
, 4, 1, lib
->fp
);
262 fseek(lib
->fp
, length
, SEEK_CUR
); /* skip over the module */
264 if (! --lib
->referenced
) {
268 return rdl_error
= 4; /* module not found */
271 void rdl_perror(const char *apname
, const char *filename
)
274 rdfperror(apname
, filename
);
276 fprintf(stderr
,"%s:%s:%s\n",apname
,filename
,rdl_errors
[rdl_error
]);