added concrete implementations of putc(), getc(), getchar() and gets()
[tangerine.git] / workbench / devs / afs / misc.c
blob70f0c759af2dffd9d723e2a1fc5a973d410405db
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
4 */
5 /*
6 * -date------ -name------------------- -description-----------------------------
7 * 02-jan-2008 [Tomasz Wiszkowski] added disk validation
8 * 04-jan-2008 [Tomasz Wiszkowski] corrected tabulation
9 */
12 #ifndef DEBUG
13 #define DEBUG 0
14 #endif
16 #include "os.h"
17 #include "misc.h"
18 #include "afsblocks.h"
19 #include "bitmap.h"
20 #include "cache.h"
21 #include "checksums.h"
22 #include "extstrings.h"
23 #include "baseredef.h"
24 #include "validator.h"
26 extern ULONG error;
28 /**********************************************
29 Name : writeHeader
30 Descr.: update header information (time)
31 Input : volume -
32 blockbuffer - pointer to struct BlockCache
33 containing the headerblock
34 Output: 0 for success; error code otherwise
35 ***********************************************/
36 ULONG writeHeader
38 struct AFSBase *afsbase,
39 struct Volume *volume,
40 struct BlockCache *blockbuffer
43 struct DateStamp ds;
45 /* store current time as modification date for this object and all its ancestors */
46 DateStamp(&ds);
47 for (;;)
49 blockbuffer->buffer[BLK_DAYS(volume)] = OS_LONG2BE(ds.ds_Days);
50 blockbuffer->buffer[BLK_MINS(volume)] = OS_LONG2BE(ds.ds_Minute);
51 blockbuffer->buffer[BLK_TICKS(volume)] = OS_LONG2BE(ds.ds_Tick);
52 if (blockbuffer->buffer[BLK_PARENT(volume)] == 0)
53 break;
54 writeBlockDeferred(afsbase, volume, blockbuffer, BLK_CHECKSUM);
55 blockbuffer = getBlock
56 (afsbase, volume, OS_BE2LONG(blockbuffer->buffer[BLK_PARENT(volume)]));
57 if (blockbuffer == NULL)
58 return ERROR_UNKNOWN;
60 /* last block is not written yet - it's the rootblock */
61 /* we have to change BLK_VOLUME_xxx */
62 blockbuffer->buffer[BLK_VOLUME_DAYS(volume)] = OS_LONG2BE(ds.ds_Days);
63 blockbuffer->buffer[BLK_VOLUME_MINS(volume)] = OS_LONG2BE(ds.ds_Minute);
64 blockbuffer->buffer[BLK_VOLUME_TICKS(volume)] = OS_LONG2BE(ds.ds_Tick);
65 writeBlockDeferred(afsbase, volume, blockbuffer, BLK_CHECKSUM);
66 return 0;
69 /*******************************************
70 Name : getDiskInfo
71 Descr.: fills a InfoData structure with some
72 Disk info;
73 answer on ACTION_DISK_INFO
74 Input : id - InfoData structure to fill
75 Output: 0 = no error
76 ********************************************/
77 LONG getDiskInfo(struct Volume *volume, struct InfoData *id) {
79 id->id_NumSoftErrors = 0;
80 id->id_UnitNumber = volume->unit;
81 id->id_DiskState = volume->state;
82 id->id_NumBlocks = volume->countblocks-volume->bootblocks;
83 id->id_NumBlocksUsed = volume->usedblockscount;
84 id->id_BytesPerBlock = volume->dosflags==0 ? BLOCK_SIZE(volume)-24 : BLOCK_SIZE(volume);
85 id->id_DiskType = volume->dostype | volume->dosflags;
86 id->id_VolumeNode = 0; /* I think this is useless in AROS */
87 id->id_InUse = (LONG)TRUE; /* if we are here the device should be in use! */
88 return 0;
91 /*******************************************
92 Name : inhibit
93 Descr.: forbid/permit access for this volume
94 Input : volume - the volume
95 forbid - DOSTRUE to forbid
96 DOSFALSE to permit access
97 Output: 0 = no error
98 ********************************************/
99 LONG inhibit(struct AFSBase *afsbase, struct Volume *volume, ULONG forbid) {
100 D(bug("[FFS] inhibit(%ld)\n", forbid));
101 if (forbid)
103 if (volume->inhibitcounter++ == 0)
105 D(bug("[FFS] inhibiting\n"));
106 /* if (exclusiveLocks(&volume->locklist)) return DOSFALSE; */
107 if (mediumPresent(&volume->ioh))
109 flush(afsbase, volume);
110 osMediumFree(afsbase, volume, FALSE);
114 else if (volume->inhibitcounter)
116 if (--volume->inhibitcounter == 0)
118 D(bug("[FFS] uninhibiting\n"));
119 if (diskPresent(afsbase, &volume->ioh))
121 D(bug("[FFS] media inserted\n"));
122 newMedium(afsbase, volume);
123 volume->ioh.ioflags |= IOHF_DISK_IN;
125 else
126 volume->ioh.ioflags &= ~IOHF_DISK_IN;
129 return 0;
132 /*******************************************
133 Name : markBitmaps
134 Descr.: mark newly allocated bitmapblocks
135 (for format)
136 Input : volume - the volume
137 Output: -
138 ********************************************/
139 void markBitmaps(struct AFSBase *afsbase, struct Volume *volume) {
140 struct BlockCache *blockbuffer;
141 ULONG i,curblock;
143 for (i=0; (i<=24) && (volume->bitmapblockpointers[i] != 0); i++)
144 markBlock(afsbase, volume, volume->bitmapblockpointers[i], 0);
145 curblock = volume->bitmapextensionblock;
146 while (curblock != 0)
148 blockbuffer = getBlock(afsbase, volume, curblock);
149 if (blockbuffer == NULL)
150 return;
151 blockbuffer->flags |= BCF_USED;
152 markBlock(afsbase, volume, curblock, 0);
153 for (i=0; i<volume->SizeBlock-1; i++)
155 if (blockbuffer->buffer[i] == 0)
156 break;
157 markBlock(afsbase, volume, OS_BE2LONG(blockbuffer->buffer[i]), 0);
159 curblock = OS_BE2LONG(blockbuffer->buffer[volume->SizeBlock-1]);
160 blockbuffer->flags &= ~BCF_USED;
164 /*******************************************
165 Name : format
166 Descr.: initialize a volume
167 Input : volume - volume to initialize
168 name - name of volume
169 dostype - DOS\0/...
170 Output: 0 for success; error code otherwise
171 ********************************************/
172 LONG format
173 (struct AFSBase *afsbase, struct Volume *volume, STRPTR name, ULONG dostype)
175 struct BlockCache *blockbuffer;
176 struct DateStamp ds;
177 UWORD i;
179 blockbuffer = getFreeCacheBlock(afsbase, volume, 0);
180 if (blockbuffer != NULL)
182 blockbuffer->buffer[0] = OS_LONG2BE(dostype);
183 blockbuffer->buffer[2] = OS_LONG2BE(volume->rootblock);
184 writeBlock(afsbase, volume, blockbuffer, -1);
185 blockbuffer = getFreeCacheBlock(afsbase, volume, volume->rootblock);
186 if (blockbuffer != NULL)
188 blockbuffer->flags |= BCF_USED;
189 DateStamp(&ds);
190 blockbuffer->buffer[BLK_PRIMARY_TYPE] = OS_LONG2BE(T_SHORT);
191 blockbuffer->buffer[1] = 0;
192 blockbuffer->buffer[2] = 0;
193 blockbuffer->buffer[BLK_TABLE_SIZE] = OS_LONG2BE(volume->SizeBlock-56);
194 blockbuffer->buffer[4] = 0;
195 for (i=BLK_TABLE_START; i<=BLK_TABLE_END(volume); i++)
196 blockbuffer->buffer[i] = 0;
197 blockbuffer->buffer[BLK_BITMAP_VALID_FLAG(volume)] = -1;
198 createNewBitmapBlocks(afsbase, volume);
199 for (
200 i=BLK_BITMAP_POINTERS_START(volume);
201 i<=BLK_BITMAP_POINTERS_END(volume);
205 blockbuffer->buffer[i] = OS_LONG2BE
207 volume->bitmapblockpointers[i-BLK_BITMAP_POINTERS_START(volume)]
210 blockbuffer->buffer[BLK_BITMAP_EXTENSION(volume)] =
211 OS_LONG2BE(volume->bitmapextensionblock);
212 blockbuffer->buffer[BLK_ROOT_DAYS(volume)] = OS_LONG2BE(ds.ds_Days);
213 blockbuffer->buffer[BLK_ROOT_MINS(volume)] = OS_LONG2BE(ds.ds_Minute);
214 blockbuffer->buffer[BLK_ROOT_TICKS(volume)] = OS_LONG2BE(ds.ds_Tick);
215 StrCpyToBstr
217 name,
218 (APTR)((char *)blockbuffer->buffer+(BLK_DISKNAME_START(volume)*4)),
219 MAX_NAME_LENGTH
221 blockbuffer->buffer[volume->SizeBlock-12] = 0;
222 blockbuffer->buffer[volume->SizeBlock-11] = 0;
223 blockbuffer->buffer[BLK_VOLUME_DAYS(volume)] = OS_LONG2BE(ds.ds_Days);
224 blockbuffer->buffer[BLK_VOLUME_MINS(volume)] = OS_LONG2BE(ds.ds_Minute);
225 blockbuffer->buffer[BLK_VOLUME_TICKS(volume)] = OS_LONG2BE(ds.ds_Tick);
226 blockbuffer->buffer[BLK_CREATION_DAYS(volume)] = OS_LONG2BE(ds.ds_Days);
227 blockbuffer->buffer[BLK_CREATION_MINS(volume)] = OS_LONG2BE(ds.ds_Minute);
228 blockbuffer->buffer[BLK_CREATION_TICKS(volume)] = OS_LONG2BE(ds.ds_Tick);
229 blockbuffer->buffer[volume->SizeBlock-4] = 0;
230 blockbuffer->buffer[volume->SizeBlock-3] = 0;
231 blockbuffer->buffer[volume->SizeBlock-2] = 0;
232 blockbuffer->buffer[BLK_SECONDARY_TYPE(volume)] = OS_LONG2BE(ST_ROOT);
233 writeBlock(afsbase, volume, blockbuffer, BLK_CHECKSUM);
234 blockbuffer->flags &= ~BCF_USED;
235 invalidBitmap(afsbase, volume);
236 markBlock(afsbase, volume, volume->rootblock, 0);
237 markBitmaps(afsbase, volume);
238 validBitmap(afsbase, volume);
239 return 0;
242 return ERROR_UNKNOWN;
245 /*******************************************
246 Name : relabel
247 Descr.: rename a volume
248 Input : volume - volume to rename
249 name - new name for volume
250 Output: DOSTRUE for success; DOSFALSE otherwise
251 ********************************************/
252 LONG relabel(struct AFSBase *afsbase, struct Volume *volume, STRPTR name) {
253 struct BlockCache *blockbuffer;
254 struct DateStamp ds;
256 if (0 == checkValid(afsbase, volume))
258 error = ERROR_DISK_WRITE_PROTECTED;
259 return DOSFALSE;
261 osMediumFree(afsbase, volume, FALSE);
262 blockbuffer=getBlock(afsbase, volume,volume->rootblock);
263 if (blockbuffer == NULL)
264 return DOSFALSE;
265 StrCpyToBstr
267 name,
268 (APTR)((char *)blockbuffer->buffer+(BLK_DISKNAME_START(volume)*4)),
269 MAX_NAME_LENGTH
271 DateStamp(&ds);
272 blockbuffer->buffer[BLK_ROOT_DAYS(volume)] = OS_LONG2BE(ds.ds_Days);
273 blockbuffer->buffer[BLK_ROOT_MINS(volume)] = OS_LONG2BE(ds.ds_Minute);
274 blockbuffer->buffer[BLK_ROOT_TICKS(volume)] = OS_LONG2BE(ds.ds_Tick);
275 blockbuffer->buffer[BLK_VOLUME_DAYS(volume)] = OS_LONG2BE(ds.ds_Days);
276 blockbuffer->buffer[BLK_VOLUME_MINS(volume)] = OS_LONG2BE(ds.ds_Minute);
277 blockbuffer->buffer[BLK_VOLUME_TICKS(volume)] = OS_LONG2BE(ds.ds_Tick);
278 writeBlock(afsbase, volume, blockbuffer, BLK_CHECKSUM);
279 /* update os specific information of the medium */
280 osMediumInit(afsbase, volume, blockbuffer);
281 return DOSTRUE;