~ubuntu-branches/ubuntu/lucid/graphviz/lucid-security

« back to all changes in this revision

Viewing changes to tools/sfio/Sfio_dc/sfdcdos.c

  • Committer: Bazaar Package Importer
  • Author(s): Stephen M Moraco
  • Date: 2002-02-05 18:52:12 UTC
  • Revision ID: james.westby@ubuntu.com-20020205185212-8i04c70te00rc40y
Tags: upstream-1.7.16
ImportĀ upstreamĀ versionĀ 1.7.16

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include        "sfdchdr.h"
 
2
 
 
3
/*      Discipline to turn \r\n into \n.
 
4
**      This is useful to deal with DOS text files.
 
5
**
 
6
**      Written by David Korn (03/18/1998).
 
7
*/
 
8
 
 
9
#define MINMAP  8
 
10
#define CHUNK   1024
 
11
 
 
12
struct map
 
13
{
 
14
        off_t   logical;
 
15
        off_t   physical;
 
16
};
 
17
 
 
18
typedef struct _dosdisc
 
19
{
 
20
        Sfdisc_t        disc;
 
21
        struct map      *maptable;
 
22
        int             mapsize;
 
23
        int             maptop;
 
24
        off_t           lhere;
 
25
        off_t           llast;
 
26
        off_t           lmax;
 
27
        off_t           pmax;
 
28
        off_t           phere;
 
29
        off_t           plast;
 
30
        off_t           begin;
 
31
        int             skip;
 
32
        void            *buff;
 
33
        char            last;
 
34
        char            extra;
 
35
        int             bsize;
 
36
} Dosdisc_t;
 
37
 
 
38
#if __STD_C
 
39
static void addmapping(register Dosdisc_t *dp)
 
40
#else
 
41
static void addmapping(dp)
 
42
register Dosdisc_t *dp;
 
43
#endif
 
44
{
 
45
        register int n;
 
46
        if((n=dp->maptop++)>=dp->mapsize)
 
47
        {
 
48
                dp->mapsize *= 2;
 
49
                if(!(dp->maptable=(struct map*)realloc((void*)dp->maptable,(dp->mapsize+1)*sizeof(struct map))))
 
50
                {
 
51
                        dp->maptop--;
 
52
                        dp->mapsize *= 2;
 
53
                        return;
 
54
                }
 
55
        }
 
56
        dp->maptable[n].physical = dp->phere;
 
57
        dp->maptable[n].logical = dp->lhere;
 
58
        dp->maptable[dp->maptop].logical=0;
 
59
}
 
60
 
 
61
#if __STD_C
 
62
static struct map *getmapping(Dosdisc_t *dp, off_t offset, register int whence)
 
63
#else
 
64
static struct map *getmapping(dp, offset, whence)
 
65
Dosdisc_t *dp;
 
66
off_t offset;
 
67
register int whence;
 
68
#endif
 
69
{
 
70
        register struct map *mp;
 
71
        static struct map dummy;
 
72
        if(offset <= dp->begin)
 
73
        {
 
74
                dummy.logical = dummy.physical = offset;
 
75
                return(&dummy);
 
76
        }
 
77
        if(!(mp=dp->maptable))
 
78
        {
 
79
                dummy.logical = dp->begin;
 
80
                dummy.physical = dummy.logical+1;
 
81
                return(&dummy);
 
82
        }
 
83
        while((++mp)->logical && (whence==SEEK_CUR?mp->physical:mp->logical) <= offset);
 
84
        return(mp-1);
 
85
}
 
86
 
 
87
#if __STD_C
 
88
static ssize_t dos_read(Sfio_t *iop, void *buff, size_t size, Sfdisc_t* disc)
 
89
#else
 
90
static ssize_t dos_read(iop, buff, size, disc)
 
91
Sfio_t *iop;
 
92
void *buff;
 
93
size_t size;
 
94
Sfdisc_t* disc;
 
95
#endif
 
96
{
 
97
        register Dosdisc_t *dp = (Dosdisc_t*)disc;
 
98
        register char *cp = (char*)buff, *first, *cpmax;
 
99
        register int n, count, m;
 
100
        if(dp->extra)
 
101
        {
 
102
                dp->extra=0;
 
103
                *cp = dp->last;
 
104
                return(1);
 
105
        }
 
106
        while(1)
 
107
        {
 
108
                if((n = sfrd(iop,buff,size,disc)) <= 0)
 
109
                        return(n);
 
110
                dp->plast=dp->phere;
 
111
                dp->phere +=n;
 
112
                dp->llast = dp->lhere;
 
113
                cpmax = cp+n-1;
 
114
                if(dp->last=='\r' && *cp!='\n')
 
115
                {
 
116
                        /* should insert a '\r' */ ;
 
117
                }
 
118
                dp->last = *cpmax;
 
119
                if(n>1)
 
120
                        break;
 
121
                if(dp->last!='\r')
 
122
                {
 
123
                        dp->lhere++;
 
124
                        return(1);
 
125
                }
 
126
        }
 
127
        if(dp->last=='\r')
 
128
                n--;
 
129
        else if(dp->last!='\n' || cpmax[-1]!='\r')
 
130
                *cpmax = '\r';
 
131
        dp->lhere += n;
 
132
        while(1)
 
133
        {
 
134
                while(*cp++ != '\r');
 
135
                if(cp > cpmax || *cp=='\n')
 
136
                        break;
 
137
        }
 
138
        dp->skip = cp-1 - (char*)buff;
 
139
        /* if not \r\n in buffer, just return */
 
140
        if((count = cpmax+1-cp) <=0)
 
141
        {
 
142
                *cpmax = dp->last;
 
143
                if(!dp->maptable)
 
144
                        dp->begin +=n;
 
145
                dp->skip++;
 
146
                count=0;
 
147
                goto done;
 
148
        }
 
149
        if(!dp->maptable)
 
150
        {
 
151
                dp->begin += cp - (char*)buff-1;
 
152
                if(dp->maptable=(struct map*)malloc((MINMAP+1)*sizeof(struct map)))
 
153
                {
 
154
                        dp->mapsize = MINMAP;
 
155
                        dp->maptable[0].logical=  dp->begin;
 
156
                        dp->maptable[0].physical = dp->maptable[0].logical+1;
 
157
                        dp->maptable[1].logical=0;
 
158
                        dp->maptop = 1;
 
159
                }
 
160
        }
 
161
        /* save original discipline inside buffer */
 
162
        if(count>dp->bsize)
 
163
        {
 
164
                if(dp->bsize==0)
 
165
                        dp->buff = malloc(count);
 
166
                else
 
167
                        dp->buff = realloc(dp->buff,count);
 
168
                dp->bsize = count;
 
169
                if(!dp->buff)
 
170
                        return(-1);
 
171
        }
 
172
        memcpy(dp->buff, cp, count);
 
173
        count=1;
 
174
        while(1)
 
175
        {
 
176
                first=cp;
 
177
                if(cp==cpmax)
 
178
                        cp++;
 
179
                else
 
180
                        while(*cp++ != '\r');
 
181
                if(cp<=cpmax && *cp!='\n')
 
182
                        continue;
 
183
                if((m=(cp-first)-1) >0)
 
184
                        memcpy(first-count, first, m);
 
185
                if(cp > cpmax)
 
186
                        break;
 
187
                count++;
 
188
        }
 
189
        cpmax[-count] = dp->last;
 
190
        dp->lhere -= count;
 
191
done:
 
192
        if(dp->lhere>dp->lmax)
 
193
        {
 
194
                dp->lmax = dp->lhere;
 
195
                dp->pmax = dp->phere;
 
196
                if(dp->maptable && dp->lmax > dp->maptable[dp->maptop-1].logical+CHUNK)
 
197
                        addmapping(dp);
 
198
        }
 
199
        return(n-count);
 
200
}
 
201
 
 
202
/*
 
203
 * returns the current offset
 
204
 * <offset> must be in the current buffer
 
205
 * if <whence> is SEEK_CUR, physical offset converted to logical offset
 
206
 *  otherwise, logical offset is converted to physical offset
 
207
 */
 
208
#if __STD_C
 
209
static off_t cur_offset(Dosdisc_t *dp, off_t offset,Sfio_t *iop,register int whence)
 
210
#else
 
211
static off_t cur_offset(dp, offset, iop, whence)
 
212
Dosdisc_t *dp;
 
213
off_t offset;
 
214
Sfio_t *iop;
 
215
register int whence;
 
216
#endif
 
217
{
 
218
        register off_t n,m=0;
 
219
        register char *cp;
 
220
 
 
221
        if(whence==SEEK_CUR)
 
222
        {
 
223
                whence= -1;
 
224
                n = offset - dp->plast;
 
225
                iop->next = iop->data + n;
 
226
                offset =  dp->llast;
 
227
        }
 
228
        else
 
229
        {
 
230
                whence = 1;
 
231
                n = offset - dp->llast;
 
232
                offset = dp->plast;
 
233
        }
 
234
        offset +=n;
 
235
        if((n -= dp->skip) > 0)
 
236
        {
 
237
                m=whence;
 
238
                cp = (char*)dp->buff;
 
239
                while(n--)
 
240
                {
 
241
                        if(*cp++=='\r' && *cp=='\n')
 
242
                        {
 
243
                                m += whence;
 
244
                                if(whence>0)
 
245
                                        n++;
 
246
                        }
 
247
                }
 
248
        }
 
249
        if(whence<0)
 
250
                iop->next += m;
 
251
        return(offset+m);
 
252
}
 
253
 
 
254
#if __STD_C
 
255
static Sfoff_t dos_seek(Sfio_t *iop, Sfoff_t offset, register int whence, Sfdisc_t* disc)
 
256
#else
 
257
static Sfoff_t dos_seek(iop, offset, whence, disc)
 
258
Sfio_t *iop;
 
259
Sfoff_t offset;
 
260
register int whence;
 
261
Sfdisc_t* disc;
 
262
#endif
 
263
{
 
264
        register Dosdisc_t *dp = (Dosdisc_t*)disc;
 
265
        struct map dummy, *mp=0;
 
266
        off_t physical;
 
267
        register int n,size;
 
268
retry:
 
269
        switch(whence)
 
270
        {
 
271
            case SEEK_CUR:
 
272
                offset = sfsk(iop, (off_t)0,SEEK_CUR,disc);
 
273
                if(offset<=dp->begin)
 
274
                        return(offset);
 
275
                /* check for seek outside buffer */
 
276
                if(offset==dp->phere)
 
277
                        return(dp->lhere);
 
278
                else if(offset==dp->plast)
 
279
                        return(dp->llast);
 
280
                else if(offset<dp->plast || offset>dp->phere)
 
281
                        mp = getmapping(dp,offset,whence);
 
282
                break;
 
283
            case SEEK_SET:
 
284
                /* check for seek outside buffer */
 
285
                if(offset<dp->llast || offset > dp->lhere)
 
286
                        mp = getmapping(dp,offset,whence);
 
287
                break;
 
288
            case SEEK_END:
 
289
                if(!dp->maptable)
 
290
                        return(sfsk(iop,offset,SEEK_END,disc));
 
291
                mp = &dummy;
 
292
                mp->physical = dp->plast;
 
293
                mp->logical = dp->llast;
 
294
                break;
 
295
        }
 
296
        if(sfsetbuf(iop,(char*)iop,0))
 
297
                size = sfslen();
 
298
        else
 
299
                size = iop->endb-iop->data;
 
300
        if(mp)
 
301
        {
 
302
                sfsk(iop,mp->physical,SEEK_SET,disc);
 
303
                dp->phere = mp->physical;
 
304
                dp->lhere = mp->logical;
 
305
                if((*disc->readf)(iop,iop->data,size,disc)<0)
 
306
                        return(-1);
 
307
        }
 
308
        while(1)
 
309
        {
 
310
                if(whence==SEEK_CUR && dp->phere>=offset)
 
311
                        break;
 
312
                if(whence==SEEK_SET && dp->lhere>=offset)
 
313
                        break;
 
314
                n=(*disc->readf)(iop,iop->data,size,disc);
 
315
                if(n < 0)
 
316
                        return(-1);
 
317
                if(n==0)
 
318
                {
 
319
                        if(whence==SEEK_END && offset<0)
 
320
                        {
 
321
                                offset = dp->lhere;
 
322
                                whence=SEEK_SET;
 
323
                                goto retry;
 
324
                        }
 
325
                        break;
 
326
                }
 
327
        }
 
328
        if(whence==SEEK_END)
 
329
                offset += dp->lhere;
 
330
        else
 
331
        {
 
332
                physical = cur_offset(dp,offset,iop,whence);
 
333
                if(whence==SEEK_SET)
 
334
                {
 
335
                        sfsk(iop, physical ,SEEK_SET,disc);
 
336
                        dp->phere = physical;
 
337
                        dp->lhere = offset;
 
338
                }
 
339
                else
 
340
                        offset = physical;
 
341
        }
 
342
        return(offset);
 
343
}
 
344
 
 
345
#if __STD_C
 
346
static int dos_except(Sfio_t *iop, int type, void *arg, Sfdisc_t *disc)
 
347
#else
 
348
static int dos_except(iop, type, arg, disc)
 
349
Sfio_t *iop;
 
350
int type;
 
351
void *arg;
 
352
Sfdisc_t *disc;
 
353
#endif
 
354
{
 
355
        register Dosdisc_t *dp = (Dosdisc_t*)disc;
 
356
        if(type==SF_DPOP || type==SF_FINAL)
 
357
        {
 
358
                if(dp->bsize>0)
 
359
                        free((void*)dp->buff);
 
360
                if(dp->mapsize)
 
361
                        free((void*)dp->maptable);
 
362
                free((void*)disc);
 
363
        }
 
364
        return(0);
 
365
}
 
366
 
 
367
#if __STD_C
 
368
int sfdcdos(Sfio_t *f)
 
369
#else
 
370
int sfdcdos(f)
 
371
Sfio_t *f;
 
372
#endif
 
373
{
 
374
        Dosdisc_t *dos;
 
375
 
 
376
        /* this is a readonly discipline */
 
377
        if(sfset(f,0,0)&SF_WRITE)
 
378
                return(-1);
 
379
 
 
380
        if(!(dos = (Dosdisc_t*)malloc(sizeof(Dosdisc_t))) )
 
381
                return -1;
 
382
        memset(dos,'\0',sizeof(Dosdisc_t));
 
383
 
 
384
        dos->disc.readf = dos_read;
 
385
        dos->disc.writef = NIL(Sfwrite_f);
 
386
        dos->disc.seekf = dos_seek;
 
387
        dos->disc.exceptf = dos_except;
 
388
 
 
389
        if(sfdisc(f,(Sfdisc_t*)dos) != (Sfdisc_t*)dos)
 
390
        {       free(dos);
 
391
                return -1;
 
392
        }
 
393
 
 
394
        return(0);
 
395
}