da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1985-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Phong Vo <kpv@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "sfdchdr.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* Discipline to turn \r\n into \n.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin** This is useful to deal with DOS text files.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin**
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin** Written by David Korn (03/18/1998).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define MINMAP 8
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define CHUNK 1024
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct map
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfoff_t logical;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfoff_t physical;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef struct _dosdisc
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfdisc_t disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct map *maptable;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int mapsize;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int maptop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfoff_t lhere;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfoff_t llast;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfoff_t lmax;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfoff_t pmax;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfoff_t phere;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfoff_t plast;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfoff_t begin;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int skip;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin void *buff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char last;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char extra;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int bsize;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin} Dosdisc_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if __STD_C
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void addmapping(register Dosdisc_t *dp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void addmapping(dp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinregister Dosdisc_t *dp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((n=dp->maptop++)>=dp->mapsize)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->mapsize *= 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(dp->maptable=(struct map*)realloc((void*)dp->maptable,(dp->mapsize+1)*sizeof(struct map))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->maptop--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->mapsize *= 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->maptable[n].physical = dp->phere;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->maptable[n].logical = dp->lhere;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->maptable[dp->maptop].logical=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if __STD_C
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic struct map *getmapping(Dosdisc_t *dp, Sfoff_t offset, register int whence)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic struct map *getmapping(dp, offset, whence)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinDosdisc_t *dp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfoff_t offset;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinregister int whence;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct map *mp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static struct map dummy;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(offset <= dp->begin)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dummy.logical = dummy.physical = offset;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(&dummy);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(mp=dp->maptable))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dummy.logical = dp->begin;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dummy.physical = dummy.logical+1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(&dummy);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((++mp)->logical && (whence==SEEK_CUR?mp->physical:mp->logical) <= offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(mp-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if __STD_C
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic ssize_t dos_read(Sfio_t *iop, void *buff, size_t size, Sfdisc_t* disc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic ssize_t dos_read(iop, buff, size, disc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfio_t *iop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid *buff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsize_t size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfdisc_t* disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Dosdisc_t *dp = (Dosdisc_t*)disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp = (char*)buff, *first, *cpmax;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n, count, m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dp->extra)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->extra=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *cp = dp->last;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((n = sfrd(iop,buff,size,disc)) <= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->plast=dp->phere;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->phere +=n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->llast = dp->lhere;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cpmax = cp+n-1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dp->last=='\r' && *cp!='\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* should insert a '\r' */ ;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->last = *cpmax;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n>1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dp->last!='\r')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->lhere++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dp->last=='\r')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(dp->last!='\n' || cpmax[-1]!='\r')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *cpmax = '\r';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->lhere += n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(*cp++ != '\r');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cp > cpmax || *cp=='\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->skip = cp-1 - (char*)buff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* if not \r\n in buffer, just return */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((count = cpmax+1-cp) <=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *cpmax = dp->last;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!dp->maptable)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->begin +=n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->skip++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin count=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!dp->maptable)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->begin += cp - (char*)buff-1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dp->maptable=(struct map*)malloc((MINMAP+1)*sizeof(struct map)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->mapsize = MINMAP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->maptable[0].logical= dp->begin;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->maptable[0].physical = dp->maptable[0].logical+1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->maptable[1].logical=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->maptop = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* save original discipline inside buffer */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(count>dp->bsize)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dp->bsize==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->buff = malloc(count);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->buff = realloc(dp->buff,count);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->bsize = count;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!dp->buff)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(dp->buff, cp, count);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin count=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first=cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cp==cpmax)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(*cp++ != '\r');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cp<=cpmax && *cp!='\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((m=(cp-first)-1) >0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(first-count, first, m);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cp > cpmax)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin count++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cpmax[-count] = dp->last;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->lhere -= count;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindone:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dp->lhere>dp->lmax)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->lmax = dp->lhere;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->pmax = dp->phere;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dp->maptable && dp->lmax > dp->maptable[dp->maptop-1].logical+CHUNK)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin addmapping(dp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(n-count);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * returns the current offset
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * <offset> must be in the current buffer
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if <whence> is SEEK_CUR, physical offset converted to logical offset
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * otherwise, logical offset is converted to physical offset
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if __STD_C
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Sfoff_t cur_offset(Dosdisc_t *dp, Sfoff_t offset,Sfio_t *iop,register int whence)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Sfoff_t cur_offset(dp, offset, iop, whence)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinDosdisc_t *dp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfoff_t offset;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfio_t *iop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinregister int whence;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Sfoff_t n,m=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(whence==SEEK_CUR)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin whence= -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = offset - dp->plast;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop->next = iop->data + n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin offset = dp->llast;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin whence = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = offset - dp->llast;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin offset = dp->plast;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin offset +=n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((n -= dp->skip) > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m=whence;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = (char*)dp->buff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(n--)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*cp++=='\r' && *cp=='\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m += whence;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(whence>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(whence<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop->next += m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(offset+m);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if __STD_C
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Sfoff_t dos_seek(Sfio_t *iop, Sfoff_t offset, register int whence, Sfdisc_t* disc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Sfoff_t dos_seek(iop, offset, whence, disc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfio_t *iop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfoff_t offset;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinregister int whence;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfdisc_t* disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Dosdisc_t *dp = (Dosdisc_t*)disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct map dummy, *mp=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfoff_t physical;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n,size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinretry:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(whence)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case SEEK_CUR:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin offset = sfsk(iop, (Sfoff_t)0,SEEK_CUR,disc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(offset<=dp->begin)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for seek outside buffer */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(offset==dp->phere)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(dp->lhere);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(offset==dp->plast)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(dp->llast);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(offset<dp->plast || offset>dp->phere)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp = getmapping(dp,offset,whence);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case SEEK_SET:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for seek outside buffer */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(offset<dp->llast || offset > dp->lhere)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp = getmapping(dp,offset,whence);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case SEEK_END:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!dp->maptable)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sfsk(iop,offset,SEEK_END,disc));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp = &dummy;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->physical = dp->plast;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->logical = dp->llast;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sfsetbuf(iop,(char*)iop,0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = sfvalue(iop);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = iop->endb-iop->data;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsk(iop,mp->physical,SEEK_SET,disc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->phere = mp->physical;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->lhere = mp->logical;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((*disc->readf)(iop,iop->data,size,disc)<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(whence==SEEK_CUR && dp->phere>=offset)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(whence==SEEK_SET && dp->lhere>=offset)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n=(*disc->readf)(iop,iop->data,size,disc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(whence==SEEK_END && offset<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin offset = dp->lhere;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin whence=SEEK_SET;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto retry;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(whence==SEEK_END)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin offset += dp->lhere;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin physical = cur_offset(dp,offset,iop,whence);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(whence==SEEK_SET)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsk(iop, physical ,SEEK_SET,disc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->phere = physical;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->lhere = offset;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin offset = physical;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if __STD_C
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int dos_except(Sfio_t *iop, int type, void *arg, Sfdisc_t *disc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int dos_except(iop, type, arg, disc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfio_t *iop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint type;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid *arg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfdisc_t *disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Dosdisc_t *dp = (Dosdisc_t*)disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type==SF_DPOP || type==SF_FINAL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dp->bsize>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)dp->buff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dp->mapsize)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)dp->maptable);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)disc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if __STD_C
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfdcdos(Sfio_t *f)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfdcdos(f)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfio_t *f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Dosdisc_t *dos;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* this is a readonly discipline */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sfset(f,0,0)&SF_WRITE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(dos = (Dosdisc_t*)malloc(sizeof(Dosdisc_t))) )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memset(dos,'\0',sizeof(Dosdisc_t));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dos->disc.readf = dos_read;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dos->disc.writef = NIL(Sfwrite_f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dos->disc.seekf = dos_seek;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dos->disc.exceptf = dos_except;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sfdisc(f,(Sfdisc_t*)dos) != (Sfdisc_t*)dos)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { free(dos);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}