blob: 97a13515e0cc3a1a7959f7f1b88a29324c1dfa6e [file] [log] [blame]
Alistair Delvabeaee832021-02-24 11:27:23 -08001/* Copyright 1996,1997,1999,2001,2002,2008,2009 Alain Knaff.
2 * This file is part of mtools.
3 *
4 * Mtools is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * Mtools is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with Mtools. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "sysincludes.h"
19#include "msdos.h"
20#include "stream.h"
21
22int batchmode = 0;
23
Yi Kong39bbd962022-01-09 19:41:38 +080024void limitSizeToOffT(size_t *len, mt_off_t maxLen)
25{
26#if SIZEOF_SIZE_T >= SIZEOF_MT_OFF_T
27 if(*len > (size_t) maxLen)
28#else
29 if(*len > maxLen)
30#endif
31 *len = (size_t) maxLen;
32}
33
34void init_head(Stream_t *Stream, struct Class_t *Class, Stream_t *Next)
35{
36 Stream->Class = Class;
37 Stream->refs = 1;
38 Stream->Next = Next;
39}
40
Alistair Delvabeaee832021-02-24 11:27:23 -080041int flush_stream(Stream_t *Stream)
42{
43 int ret=0;
44 if(!batchmode) {
45 if(Stream->Class->flush)
46 ret |= Stream->Class->flush(Stream);
47 if(Stream->Next)
48 ret |= flush_stream(Stream->Next);
49 }
50 return ret;
51}
52
53Stream_t *copy_stream(Stream_t *Stream)
54{
55 if(Stream)
56 Stream->refs++;
57 return Stream;
58}
59
60int free_stream(Stream_t **Stream)
61{
62 int ret=0;
63
64 if(!*Stream)
65 return -1;
66 if(! --(*Stream)->refs){
67 if((*Stream)->Class->flush)
68 ret |= (*Stream)->Class->flush(*Stream);
69 if((*Stream)->Class->freeFunc)
70 ret |= (*Stream)->Class->freeFunc(*Stream);
71 if((*Stream)->Next)
72 ret |= free_stream(&(*Stream)->Next);
73 Free(*Stream);
Yi Kong39bbd962022-01-09 19:41:38 +080074 }
Alistair Delvabeaee832021-02-24 11:27:23 -080075 *Stream = NULL;
76 return ret;
77}
78
79
80#define GET_DATA(stream, date, size, type, address) \
81(stream)->Class->get_data( (stream), (date), (size), (type), (address) )
82
Yi Kong39bbd962022-01-09 19:41:38 +080083int set_geom_pass_through(Stream_t *Stream, device_t *dev, device_t *orig_dev)
84{
85 return SET_GEOM(Stream->Next, dev, orig_dev);
86}
Alistair Delvabeaee832021-02-24 11:27:23 -080087
Yi Kong39bbd962022-01-09 19:41:38 +080088int set_geom_noop(Stream_t *Stream UNUSEDP,
89 device_t *dev UNUSEDP,
90 device_t *orig_dev UNUSEDP)
91{
92 return 0;
93}
94
95int get_data_pass_through(Stream_t *Stream, time_t *date, mt_off_t *size,
96 int *type, uint32_t *address)
Alistair Delvabeaee832021-02-24 11:27:23 -080097{
98 return GET_DATA(Stream->Next, date, size, type, address);
99}
100
Yi Kong39bbd962022-01-09 19:41:38 +0800101ssize_t pread_pass_through(Stream_t *Stream, char *buf,
102 mt_off_t start, size_t len)
Alistair Delvabeaee832021-02-24 11:27:23 -0800103{
Yi Kong39bbd962022-01-09 19:41:38 +0800104 return PREADS(Stream->Next, buf, start, len);
Alistair Delvabeaee832021-02-24 11:27:23 -0800105}
106
Yi Kong39bbd962022-01-09 19:41:38 +0800107ssize_t pwrite_pass_through(Stream_t *Stream, char *buf,
108 mt_off_t start, size_t len)
Alistair Delvabeaee832021-02-24 11:27:23 -0800109{
Yi Kong39bbd962022-01-09 19:41:38 +0800110 return PWRITES(Stream->Next, buf, start, len);
Alistair Delvabeaee832021-02-24 11:27:23 -0800111}
112
113doscp_t *get_dosConvert_pass_through(Stream_t *Stream)
114{
115 return GET_DOSCONVERT(Stream->Next);
116}
Yi Kong39bbd962022-01-09 19:41:38 +0800117
118/*
119 * Adjust number of total sectors by given offset in bytes
120 */
121int adjust_tot_sectors(struct device *dev, mt_off_t offset, char *errmsg)
122{
123 if(!dev->tot_sectors)
124 /* tot_sectors not set, do nothing */
125 return 0;
126
127 mt_off_t offs_sectors = offset /
128 (dev->sector_size ? dev->sector_size : 512);
129 if(offs_sectors > 0 && dev->tot_sectors < (smt_off_t) offs_sectors) {
130 if(errmsg)
131 sprintf(errmsg,"init: Offset bigger than base image");
132 return -1;
133 }
134 dev->tot_sectors -= (uint32_t) offs_sectors;
135 return 0;
136}