xref: /aosp_15_r20/external/mtools/stream.c (revision d5c9a868b113e0ec0db2f27bc2ce8a253e77c4b0)
1 /*  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 
22 int batchmode = 0;
23 
limitSizeToOffT(size_t * len,mt_off_t maxLen)24 void 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 
init_head(Stream_t * Stream,struct Class_t * Class,Stream_t * Next)34 void 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 
flush_stream(Stream_t * Stream)41 int 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 
copy_stream(Stream_t * Stream)53 Stream_t *copy_stream(Stream_t *Stream)
54 {
55 	if(Stream)
56 		Stream->refs++;
57 	return Stream;
58 }
59 
free_stream(Stream_t ** Stream)60 int 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);
74 	}
75 	*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 
set_geom_pass_through(Stream_t * Stream,device_t * dev,device_t * orig_dev)83 int 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 }
87 
set_geom_noop(Stream_t * Stream UNUSEDP,device_t * dev UNUSEDP,device_t * orig_dev UNUSEDP)88 int set_geom_noop(Stream_t *Stream UNUSEDP,
89 		  device_t *dev UNUSEDP,
90 		  device_t *orig_dev UNUSEDP)
91 {
92 	return 0;
93 }
94 
get_data_pass_through(Stream_t * Stream,time_t * date,mt_off_t * size,int * type,uint32_t * address)95 int get_data_pass_through(Stream_t *Stream, time_t *date, mt_off_t *size,
96 			  int *type, uint32_t *address)
97 {
98        return GET_DATA(Stream->Next, date, size, type, address);
99 }
100 
pread_pass_through(Stream_t * Stream,char * buf,mt_off_t start,size_t len)101 ssize_t pread_pass_through(Stream_t *Stream, char *buf,
102 			   mt_off_t start, size_t len)
103 {
104 	return PREADS(Stream->Next, buf, start, len);
105 }
106 
pwrite_pass_through(Stream_t * Stream,char * buf,mt_off_t start,size_t len)107 ssize_t pwrite_pass_through(Stream_t *Stream, char *buf,
108 			    mt_off_t start, size_t len)
109 {
110 	return PWRITES(Stream->Next, buf, start, len);
111 }
112 
get_dosConvert_pass_through(Stream_t * Stream)113 doscp_t *get_dosConvert_pass_through(Stream_t *Stream)
114 {
115 	return GET_DOSCONVERT(Stream->Next);
116 }
117 
118 /*
119  * Adjust number of total sectors by given offset in bytes
120  */
adjust_tot_sectors(struct device * dev,mt_off_t offset,char * errmsg)121 int 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 }
137