xref: /openbsd-src/usr.sbin/mopd/common/file.c (revision 8500990981f885cbe5e6a4958549cacc238b5ae6)
1 /*	$OpenBSD: file.c,v 1.7 2003/12/01 00:56:51 avsm Exp $ */
2 
3 /*
4  * Copyright (c) 1995-96 Mats O Jansson.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #ifndef LINT
28 static const char rcsid[] = "$OpenBSD: file.c,v 1.7 2003/12/01 00:56:51 avsm Exp $";
29 #endif
30 
31 #include "os.h"
32 #include "common/common.h"
33 #include "common/mopdef.h"
34 
35 #ifndef NOAOUT
36 #if defined(__NetBSD__) || defined(__OpenBSD__)
37 #include <sys/exec_aout.h>
38 #endif
39 #if defined(__bsdi__)
40 #define NOAOUT
41 #endif
42 #if defined(__FreeBSD__)
43 #include <sys/imgact_aout.h>
44 #endif
45 #if !defined(MID_I386)
46 #define MID_I386 134
47 #endif
48 #if !defined(MID_SPARC)
49 #define MID_SPARC 138
50 #endif
51 #if !defined(MID_VAX)
52 #define MID_VAX 140
53 #endif
54 #endif
55 
56 void
57 mopFilePutLX(buf, index, value, cnt)
58 	u_char	*buf;
59 	int	index, cnt;
60 	u_long	value;
61 {
62 	int i;
63 	for (i = 0; i < cnt; i++) {
64 		buf[index+i] = value % 256;
65 		value = value / 256;
66 	}
67 }
68 
69 void
70 mopFilePutBX(buf, index, value, cnt)
71 	u_char	*buf;
72 	int	index, cnt;
73 	u_long	value;
74 {
75 	int i;
76 	for (i = 0; i < cnt; i++) {
77 		buf[index+cnt-1-i] = value % 256;
78 		value = value / 256;
79 	}
80 }
81 
82 u_long
83 mopFileGetLX(buf, index, cnt)
84 	u_char	*buf;
85 	int	index, cnt;
86 {
87 	u_long ret = 0;
88 	int i;
89 
90 	for (i = 0; i < cnt; i++) {
91 		ret = ret*256 + buf[index+cnt-1-i];
92 	}
93 
94 	return(ret);
95 }
96 
97 u_long
98 mopFileGetBX(buf, index, cnt)
99 	u_char	*buf;
100 	int	index, cnt;
101 {
102 	u_long ret = 0;
103 	int i;
104 
105 	for (i = 0; i < cnt; i++) {
106 		ret = ret*256 + buf[index+i];
107 	}
108 
109 	return(ret);
110 }
111 
112 void
113 mopFileSwapX(buf, index, cnt)
114 	u_char	*buf;
115 	int	index, cnt;
116 {
117 	int i;
118 	u_char c;
119 
120 	for (i = 0; i < (cnt / 2); i++) {
121 		c = buf[index+i];
122 		buf[index+i] = buf[index+cnt-1-i];
123 		buf[index+cnt-1-i] = c;
124 	}
125 
126 }
127 
128 int
129 CheckMopFile(fd)
130 	int	fd;
131 {
132 	u_char	header[512];
133 	short	image_type;
134 
135 	if (read(fd, header, 512) != 512)
136 		return(-1);
137 
138 	(void)lseek(fd, (off_t) 0, SEEK_SET);
139 
140 	image_type = (u_short)(header[IHD_W_ALIAS+1]*256 +
141 			       header[IHD_W_ALIAS]);
142 
143 	switch(image_type) {
144 		case IHD_C_NATIVE:		/* Native mode image (VAX)   */
145 		case IHD_C_RSX:			/* RSX image produced by TKB */
146 		case IHD_C_BPA:			/* BASIC plus analog         */
147 		case IHD_C_ALIAS:		/* Alias		     */
148 		case IHD_C_CLI:			/* Image is CLI		     */
149 		case IHD_C_PMAX:		/* PMAX system image	     */
150 		case IHD_C_ALPHA:		/* ALPHA system image	     */
151 			break;
152 		default:
153 			return(-1);
154 	}
155 
156 	return(0);
157 }
158 
159 int
160 GetMopFileInfo(fd, load, xfr)
161 	int	fd;
162 	u_long	*load, *xfr;
163 {
164 	u_char	header[512];
165 	short	image_type;
166 	u_long	load_addr, xfr_addr, isd, iha, hbcnt, isize;
167 
168 	if (read(fd, header, 512) != 512)
169 		return(-1);
170 
171 	image_type = (u_short)(header[IHD_W_ALIAS+1]*256 +
172 			       header[IHD_W_ALIAS]);
173 
174 	switch(image_type) {
175 		case IHD_C_NATIVE:		/* Native mode image (VAX)   */
176 			isd = (header[IHD_W_SIZE+1]*256 +
177 			       header[IHD_W_SIZE]);
178 			iha = (header[IHD_W_ACTIVOFF+1]*256 +
179 			       header[IHD_W_ACTIVOFF]);
180 			hbcnt = (header[IHD_B_HDRBLKCNT]);
181 			isize = (header[isd+ISD_W_PAGCNT+1]*256 +
182 				 header[isd+ISD_W_PAGCNT]) * 512;
183 			load_addr = ((header[isd+ISD_V_VPN+1]*256 +
184 				      header[isd+ISD_V_VPN]) & ISD_M_VPN)
185 					* 512;
186 			xfr_addr = (header[iha+IHA_L_TFRADR1+3]*0x1000000 +
187 				    header[iha+IHA_L_TFRADR1+2]*0x10000 +
188 				    header[iha+IHA_L_TFRADR1+1]*0x100 +
189 				    header[iha+IHA_L_TFRADR1]) & 0x7fffffff;
190 #ifdef INFO
191 			printf("Native Image (VAX)\n");
192 			printf("Header Block Count: %lu\n",hbcnt);
193 			printf("Image Size:         %08lx\n",isize);
194 			printf("Load Address:       %08lx\n",load_addr);
195 			printf("Transfer Address:   %08lx\n",xfr_addr);
196 #endif
197 			break;
198 		case IHD_C_RSX:			/* RSX image produced by TKB */
199 			hbcnt = header[L_BBLK+1]*256 + header[L_BBLK];
200 			isize = (header[L_BLDZ+1]*256 + header[L_BLDZ]) * 64;
201 			load_addr = header[L_BSA+1]*256 + header[L_BSA];
202 			xfr_addr  = header[L_BXFR+1]*256 + header[L_BXFR];
203 #ifdef INFO
204 			printf("RSX Image\n");
205 			printf("Header Block Count: %lu\n",hbcnt);
206 			printf("Image Size:         %08lx\n",isize);
207 			printf("Load Address:       %08lx\n",load_addr);
208 			printf("Transfer Address:   %08lx\n",xfr_addr);
209 #endif
210 			break;
211 		case IHD_C_BPA:			/* BASIC plus analog         */
212 #ifdef INFO
213 			printf("BASIC-Plus Image, not supported\n");
214 #endif
215 			return(-1);
216 			break;
217 		case IHD_C_ALIAS:		/* Alias		     */
218 #ifdef INFO
219 			printf("Alias, not supported\n");
220 #endif
221 			return(-1);
222 			break;
223 		case IHD_C_CLI:			/* Image is CLI		     */
224 #ifdef INFO
225 			printf("CLI, not supported\n");
226 #endif
227 			return(-1);
228 			break;
229 		case IHD_C_PMAX:		/* PMAX system image	     */
230 			isd = (header[IHD_W_SIZE+1]*256 +
231 			       header[IHD_W_SIZE]);
232 			iha = (header[IHD_W_ACTIVOFF+1]*256 +
233 			       header[IHD_W_ACTIVOFF]);
234 			hbcnt = (header[IHD_B_HDRBLKCNT]);
235 			isize = (header[isd+ISD_W_PAGCNT+1]*256 +
236 				 header[isd+ISD_W_PAGCNT]) * 512;
237 			load_addr = (header[isd+ISD_V_VPN+1]*256 +
238 				     header[isd+ISD_V_VPN]) * 512;
239 			xfr_addr = (header[iha+IHA_L_TFRADR1+3]*0x1000000 +
240 				    header[iha+IHA_L_TFRADR1+2]*0x10000 +
241 				    header[iha+IHA_L_TFRADR1+1]*0x100 +
242 				    header[iha+IHA_L_TFRADR1]);
243 #ifdef INFO
244 			printf("PMAX Image \n");
245 			printf("Header Block Count: %lu\n",hbcnt);
246 			printf("Image Size:         %08lx\n",isize);
247 			printf("Load Address:       %08lx\n",load_addr);
248 			printf("Transfer Address:   %08lx\n",xfr_addr);
249 #endif
250 			break;
251 		case IHD_C_ALPHA:		/* ALPHA system image	     */
252 			isd = (header[EIHD_L_ISDOFF+3]*0x1000000 +
253 			       header[EIHD_L_ISDOFF+2]*0x10000 +
254 			       header[EIHD_L_ISDOFF+1]*0x100 +
255 			       header[EIHD_L_ISDOFF]);
256 			hbcnt = (header[EIHD_L_HDRBLKCNT+3]*0x1000000 +
257 				 header[EIHD_L_HDRBLKCNT+2]*0x10000 +
258 				 header[EIHD_L_HDRBLKCNT+1]*0x100 +
259 				 header[EIHD_L_HDRBLKCNT]);
260 			isize = (header[isd+EISD_L_SECSIZE+3]*0x1000000 +
261 				 header[isd+EISD_L_SECSIZE+2]*0x10000 +
262 				 header[isd+EISD_L_SECSIZE+1]*0x100 +
263 				 header[isd+EISD_L_SECSIZE]);
264 			load_addr = 0;
265 			xfr_addr = 0;
266 #ifdef INFO
267 			printf("Alpha Image \n");
268 			printf("Header Block Count: %lu\n",hbcnt);
269 			printf("Image Size:         %08lx\n",isize);
270 			printf("Load Address:       %08lx\n",load_addr);
271 			printf("Transfer Address:   %08lx\n",xfr_addr);
272 #endif
273 			break;
274 		default:
275 #ifdef INFO
276 			printf("Unknown Image (%d)\n",image_type);
277 #endif
278 			return(-1);
279 	}
280 
281 	if (load != NULL) {
282 		*load = load_addr;
283 	}
284 
285 	if (xfr != NULL) {
286 		*xfr  = xfr_addr;
287 	}
288 
289 	return(0);
290 }
291 
292 #ifndef NOAOUT
293 int
294 getMID(old_mid,new_mid)
295 	int	old_mid, new_mid;
296 {
297 	int	mid;
298 
299 	mid = old_mid;
300 
301 	switch (new_mid) {
302 	case MID_I386:
303 		mid = MID_I386;
304 		break;
305 #ifdef MID_M68K
306 	case MID_M68K:
307 		mid = MID_M68K;
308 		break;
309 #endif
310 #ifdef MID_M68K4K
311 	case MID_M68K4K:
312 		mid = MID_M68K4K;
313 		break;
314 #endif
315 #ifdef MID_NS32532
316 	case MID_NS32532:
317 		mid = MID_NS32532;
318 		break;
319 #endif
320 	case MID_SPARC:
321 		mid = MID_SPARC;
322 		break;
323 #ifdef MID_PMAX
324 	case MID_PMAX:
325 		mid = MID_PMAX;
326 		break;
327 #endif
328 #ifdef MID_VAX
329 	case MID_VAX:
330 		mid = MID_VAX;
331 		break;
332 #endif
333 #ifdef MID_ALPHA
334 	case MID_ALPHA:
335 		mid = MID_ALPHA;
336 		break;
337 #endif
338 #ifdef MID_MIPS
339 	case MID_MIPS:
340 		mid = MID_MIPS;
341 		break;
342 #endif
343 #ifdef MID_ARM6
344 	case MID_ARM6:
345 		mid = MID_ARM6;
346 		break;
347 #endif
348 	default:
349 		break;
350 	}
351 
352 	return(mid);
353 }
354 
355 int
356 getCLBYTES(mid)
357 	int	mid;
358 {
359 	int	clbytes;
360 
361 	switch (mid) {
362 #ifdef MID_VAX
363 	case MID_VAX:
364 		clbytes = 1024;
365 		break;
366 #endif
367 	case MID_I386:
368 #ifdef MID_M68K4K
369 	case MID_M68K4K:
370 #endif
371 #ifdef MID_NS32532
372 	case MID_NS32532:
373 #endif
374 	case MID_SPARC:				/* It might be 8192 */
375 #ifdef MID_PMAX
376 	case MID_PMAX:
377 #endif
378 #ifdef MID_MIPS
379 	case MID_MIPS:
380 #endif
381 #ifdef MID_ARM6
382 	case MID_ARM6:
383 #endif
384 		clbytes = 4096;
385 		break;
386 #ifdef MID_M68K
387 	case MID_M68K:
388 #endif
389 #ifdef MID_ALPHA
390 	case MID_ALPHA:
391 #endif
392 #if defined(MID_M68K) || defined(MID_ALPHA)
393 		clbytes = 8192;
394 		break;
395 #endif
396 	default:
397 		clbytes = 0;
398 	}
399 
400 	return(clbytes);
401 }
402 #endif
403 
404 int
405 CheckAOutFile(fd)
406 	int	fd;
407 {
408 #ifdef NOAOUT
409 	return(-1);
410 #else
411 	struct exec ex, ex_swap;
412 	int	mid = -1;
413 
414 	if (read(fd, (char *)&ex, sizeof(ex)) != sizeof(ex))
415 		return(-1);
416 
417 	(void)lseek(fd, (off_t) 0, SEEK_SET);
418 
419 	if (read(fd, (char *)&ex_swap, sizeof(ex_swap)) != sizeof(ex_swap))
420 		return(-1);
421 
422 	(void)lseek(fd, (off_t) 0, SEEK_SET);
423 
424 	mid = getMID(mid, N_GETMID (ex));
425 
426 	if (mid == -1) {
427 		mid = getMID(mid, N_GETMID (ex_swap));
428 	}
429 
430 	if (mid != -1) {
431 		return(0);
432 	} else {
433 		return(-1);
434 	}
435 #endif /* NOAOUT */
436 }
437 
438 int
439 GetAOutFileInfo(fd, load, xfr, a_text, a_text_fill,
440 		a_data, a_data_fill, a_bss, a_bss_fill, aout)
441 	int	fd, *aout;
442 	u_long	*load, *xfr, *a_text, *a_text_fill;
443 	u_long	*a_data, *a_data_fill, *a_bss, *a_bss_fill;
444 {
445 #ifdef NOAOUT
446 	return(-1);
447 #else
448 	struct exec ex, ex_swap;
449 	int	mid = -1;
450 	u_long	magic, clbytes, clofset;
451 
452 	if (read(fd, (char *)&ex, sizeof(ex)) != sizeof(ex))
453 		return(-1);
454 
455 	(void)lseek(fd, (off_t) 0, SEEK_SET);
456 
457 	if (read(fd, (char *)&ex_swap, sizeof(ex_swap)) != sizeof(ex_swap))
458 		return(-1);
459 
460 	mopFileSwapX((u_char *)&ex_swap, 0, 4);
461 
462 	mid = getMID(mid, N_GETMID (ex));
463 
464 	if (mid == -1) {
465 		mid = getMID(mid, N_GETMID (ex_swap));
466 		if (mid != -1) {
467 			mopFileSwapX((u_char *)&ex, 0, 4);
468 		}
469 	}
470 
471 	if (mid == -1) {
472 		return(-1);
473 	}
474 
475 	if (N_BADMAG (ex)) {
476 		return(-1);
477 	}
478 
479 	switch (mid) {
480 	case MID_I386:
481 #ifdef MID_NS32532
482 	case MID_NS32532:
483 #endif
484 #ifdef MID_PMAX
485 	case MID_PMAX:
486 #endif
487 #ifdef MID_VAX
488 	case MID_VAX:
489 #endif
490 #ifdef MID_ALPHA
491 	case MID_ALPHA:
492 #endif
493 #ifdef MID_ARM6
494 	case MID_ARM6:
495 #endif
496 		ex.a_text  = mopFileGetLX((u_char *)&ex_swap,  4, 4);
497 		ex.a_data  = mopFileGetLX((u_char *)&ex_swap,  8, 4);
498 		ex.a_bss   = mopFileGetLX((u_char *)&ex_swap, 12, 4);
499 		ex.a_syms  = mopFileGetLX((u_char *)&ex_swap, 16, 4);
500 		ex.a_entry = mopFileGetLX((u_char *)&ex_swap, 20, 4);
501 		ex.a_trsize= mopFileGetLX((u_char *)&ex_swap, 24, 4);
502 		ex.a_drsize= mopFileGetLX((u_char *)&ex_swap, 28, 4);
503 		break;
504 #ifdef MID_M68K
505 	case MID_M68K:
506 #endif
507 #ifdef MID_M68K4K
508 	case MID_M68K4K:
509 #endif
510 	case MID_SPARC:
511 #ifdef MID_MIPS
512 	case MID_MIPS:
513 #endif
514 		ex.a_text  = mopFileGetBX((u_char *)&ex_swap,  4, 4);
515 		ex.a_data  = mopFileGetBX((u_char *)&ex_swap,  8, 4);
516 		ex.a_bss   = mopFileGetBX((u_char *)&ex_swap, 12, 4);
517 		ex.a_syms  = mopFileGetBX((u_char *)&ex_swap, 16, 4);
518 		ex.a_entry = mopFileGetBX((u_char *)&ex_swap, 20, 4);
519 		ex.a_trsize= mopFileGetBX((u_char *)&ex_swap, 24, 4);
520 		ex.a_drsize= mopFileGetBX((u_char *)&ex_swap, 28, 4);
521 		break;
522 	default:
523 		break;
524 	}
525 
526 #ifdef INFO
527 	printf("a.out image (");
528 	switch (N_GETMID (ex)) {
529 	case MID_I386:
530 		printf("i386");
531 		break;
532 #ifdef MID_M68K
533 	case MID_M68K:
534 		printf("m68k");
535 		break;
536 #endif
537 #ifdef MID_M68K4K
538 	case MID_M68K4K:
539 		printf("m68k 4k");
540 		break;
541 #endif
542 #ifdef MID_NS32532
543 	case MID_NS32532:
544 		printf("pc532");
545 		break;
546 #endif
547 	case MID_SPARC:
548 		printf("sparc");
549 		break;
550 #ifdef MID_PMAX
551 	case MID_PMAX:
552 		printf("pmax");
553 		break;
554 #endif
555 #ifdef MID_VAX
556 	case MID_VAX:
557 		printf("vax");
558 		break;
559 #endif
560 #ifdef MID_ALPHA
561 	case MID_ALPHA:
562 		printf("alpha");
563 		break;
564 #endif
565 #ifdef MID_MIPS
566 	case MID_MIPS:
567 		printf("mips");
568 		break;
569 #endif
570 #ifdef MID_ARM6
571 	case MID_ARM6:
572 		printf("arm32");
573 		break;
574 #endif
575 	default:
576 		break;
577 	}
578 	printf(") Magic: ");
579 	switch (N_GETMAGIC (ex)) {
580 	case OMAGIC:
581 		printf("OMAGIC");
582 		break;
583 	case NMAGIC:
584 		printf("NMAGIC");
585 		break;
586 	case ZMAGIC:
587 		printf("ZMAGIC");
588 		break;
589 	case QMAGIC:
590 		printf("QMAGIC");
591 		break;
592 	default:
593 		printf("Unknown %d",N_GETMAGIC (ex));
594 	}
595 	printf("\n");
596 	printf("Size of text:       %08x\n",ex.a_text);
597 	printf("Size of data:       %08x\n",ex.a_data);
598 	printf("Size of bss:        %08x\n",ex.a_bss);
599 	printf("Size of symbol tab: %08x\n",ex.a_syms);
600 	printf("Transfer Address:   %08x\n",ex.a_entry);
601 	printf("Size of reloc text: %08x\n",ex.a_trsize);
602 	printf("Size of reloc data: %08x\n",ex.a_drsize);
603 #endif
604 	magic = N_GETMAGIC (ex);
605 	clbytes = getCLBYTES(mid);
606 	clofset = clbytes - 1;
607 
608 	if (load != NULL) {
609 		*load   = 0;
610 	}
611 
612 	if (xfr != NULL) {
613 		*xfr    = ex.a_entry;
614 	}
615 
616 	if (a_text != NULL) {
617 		*a_text = ex.a_text;
618 	}
619 
620 	if (a_text_fill != NULL) {
621 		if (magic == ZMAGIC || magic == NMAGIC) {
622 			*a_text_fill = clbytes - (ex.a_text & clofset);
623 			if (*a_text_fill == clbytes) {
624 				*a_text_fill = 0;
625 			}
626 		} else {
627 			*a_text_fill = 0;
628 	        }
629 	}
630 
631 	if (a_data != NULL) {
632 		*a_data = ex.a_data;
633 	}
634 
635 	if (a_data_fill != NULL) {
636 		if (magic == ZMAGIC || magic == NMAGIC) {
637 			*a_data_fill = clbytes - (ex.a_data & clofset);
638 			if (*a_data_fill == clbytes) {
639 				*a_data_fill = 0;
640 			}
641 		} else {
642 			*a_data_fill = 0;
643 	        }
644 	}
645 
646 	if (a_bss != NULL) {
647 		*a_bss  = ex.a_bss;
648 	}
649 
650 	if (a_bss_fill != NULL) {
651 		if (magic == ZMAGIC || magic == NMAGIC) {
652 			*a_bss_fill = clbytes - (ex.a_bss & clofset);
653 			if (*a_bss_fill == clbytes) {
654 				*a_bss_fill = 0;
655 			}
656 		} else {
657 			*a_bss_fill = clbytes -
658 				((ex.a_text+ex.a_data+ex.a_bss) & clofset);
659 			if (*a_text_fill == clbytes) {
660 				*a_text_fill = 0;
661 			}
662 	        }
663 	}
664 
665 	if (aout != NULL) {
666 		*aout = mid;
667 	}
668 
669 	return(0);
670 #endif /* NOAOUT */
671 }
672 
673 int
674 GetFileInfo(fd, load, xfr, aout,
675 	    a_text, a_text_fill, a_data, a_data_fill, a_bss, a_bss_fill)
676 	int	fd, *aout;
677 	u_long	*load, *xfr, *a_text, *a_text_fill;
678 	u_long	*a_data, *a_data_fill, *a_bss, *a_bss_fill;
679 {
680 	int	err;
681 
682 	err = CheckAOutFile(fd);
683 
684 	if (err == 0) {
685 		err = GetAOutFileInfo(fd, load, xfr,
686 				      a_text, a_text_fill,
687 				      a_data, a_data_fill,
688 				      a_bss, a_bss_fill,
689 				      aout);
690 		if (err != 0) {
691 			return(-1);
692 		}
693 	} else {
694 		err = CheckMopFile(fd);
695 
696 		if (err == 0) {
697 			err = GetMopFileInfo(fd, load, xfr);
698 			if (err != 0) {
699 				return(-1);
700 			}
701 			*aout = -1;
702 		} else {
703 			return(-1);
704 		}
705 	}
706 
707 	return(0);
708 }
709 
710 ssize_t
711 mopFileRead(dlslot, buf)
712 	struct dllist *dlslot;
713 	u_char	*buf;
714 {
715 	ssize_t len, outlen;
716 	int	bsz;
717 	long	pos, notdone, total;
718 
719 	if (dlslot->aout == -1) {
720 		len = read(dlslot->ldfd,buf,dlslot->dl_bsz);
721 	} else {
722 		bsz = dlslot->dl_bsz;
723 		pos = dlslot->a_lseek;
724 		len = 0;
725 
726 		total = dlslot->a_text;
727 
728 		if (pos < total) {
729 			notdone = total - pos;
730 			if (notdone <= bsz) {
731 				outlen = read(dlslot->ldfd,&buf[len],notdone);
732 			} else {
733 				outlen = read(dlslot->ldfd,&buf[len],bsz);
734 			}
735 			len = len + outlen;
736 			pos = pos + outlen;
737 			bsz = bsz - outlen;
738 		}
739 
740 		total = total + dlslot->a_text_fill;
741 
742 		if ((bsz > 0) && (pos < total)) {
743 			notdone = total - pos;
744 			if (notdone <= bsz) {
745 				outlen = notdone;
746 			} else {
747 				outlen = bsz;
748 			}
749 			bzero(&buf[len],outlen);
750 			len = len + outlen;
751 			pos = pos + outlen;
752 			bsz = bsz - outlen;
753 		}
754 
755 		total = total + dlslot->a_data;
756 
757 		if ((bsz > 0) && (pos < total)) {
758 			notdone = total - pos;
759 			if (notdone <= bsz) {
760 				outlen = read(dlslot->ldfd,&buf[len],notdone);
761 			} else {
762 				outlen = read(dlslot->ldfd,&buf[len],bsz);
763 			}
764 			len = len + outlen;
765 			pos = pos + outlen;
766 			bsz = bsz - outlen;
767 		}
768 
769 		total = total + dlslot->a_data_fill;
770 
771 		if ((bsz > 0) && (pos < total)) {
772 			notdone = total - pos;
773 			if (notdone <= bsz) {
774 				outlen = notdone;
775 			} else {
776 				outlen = bsz;
777 			}
778 			bzero(&buf[len],outlen);
779 			len = len + outlen;
780 			pos = pos + outlen;
781 			bsz = bsz - outlen;
782 		}
783 
784 		total = total + dlslot->a_bss;
785 
786 		if ((bsz > 0) && (pos < total)) {
787 			notdone = total - pos;
788 			if (notdone <= bsz) {
789 				outlen = notdone;
790 			} else {
791 				outlen = bsz;
792 			}
793 			bzero(&buf[len],outlen);
794 			len = len + outlen;
795 			pos = pos + outlen;
796 			bsz = bsz - outlen;
797 		}
798 
799 		total = total + dlslot->a_bss_fill;
800 
801 		if ((bsz > 0) && (pos < total)) {
802 			notdone = total - pos;
803 			if (notdone <= bsz) {
804 				outlen = notdone;
805 			} else {
806 				outlen = bsz;
807 			}
808 			bzero(&buf[len],outlen);
809 			len = len + outlen;
810 			pos = pos + outlen;
811 			bsz = bsz - outlen;
812 		}
813 
814 		dlslot->a_lseek = pos;
815 
816 	}
817 
818 	return(len);
819 }
820