udftools

- Main Page
- Classes
- Files

- File List
- File Members

All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
wrudf-cmnd.c
Go to the documentation of this file.
1 /* wrudf-cmnd.c
2 *
3 * PURPOSE
4 * High level wrudf command functions
5 *
6 * COPYRIGHT
7 * This file is distributed under the terms of the GNU General Public
8 * License (GPL). Copies of the GPL can be obtained from:
9 * ftp://prep.ai.mit.edu/pub/gnu/GPL
10 *
11 * (C) 2001 Enno Fennema <e.fennema@dataweb.nl>
12 *
13 * HISTORY
14 * 16 Aug 01 ef Created.
15 */
16
17 #include "config.h"
18
19 #include <stddef.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <fcntl.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <dirent.h>
26 #include <sys/stat.h>
27 #include <errno.h>
28
29 #include "wrudf.h"
30
31
32 int deleteDirectory(Directory *dir, struct fileIdentDesc *fid);
33 Directory *makeDir(Directory *dir, char* name);
34 int questionOverwrite(Directory *dir, struct fileIdentDesc *fid, char* name);
35 int directoryIsEmpty(Directory *dir);
36
37 char *hdWorkingDir;
38
39 /* copyFile()
40 * Write File Entry immediately followed by data
41 * A verify error on CDR causes a further packet with
42 * the new FE followed by copies of the defective blocks only
43 */
44 int
45 copyFile(Directory *dir, char* inName, char*newName, struct stat *fileStat)
46 {
47 uint32_t i=0;
48 int fd, blkno;
49 uint32_t nBytes, blkInPkt;
50 uint32_t maxVarPktSize; // in bytes
51 struct fileIdentDesc *fid;
52 struct fileEntry *fe;
53 uint8_t p[2048];
54
55 fd = open(inName, O_RDONLY);
56 if( fd == 0 ) {
57 printf("'%s' does not exist\n", inName);
58 return CMND_FAILED;
59 }
60
61 printf("Copy file %s\n", inName);
62 fid = findFileIdentDesc(dir, newName);
63
64 if( fid && questionOverwrite(dir, fid, newName) ) {
65 close(fd);
66 return CMND_OK;
67 }
68
69 fid = makeFileIdentDesc(newName); // could reuse FID if overwrite allowed
70
71 fe = makeFileEntry();
72 fe->uid = fileStat->st_uid;
73 fe->gid = fileStat->st_gid;
74 if( fileStat->st_mode & S_IRUSR ) fe->permissions |= FE_PERM_U_READ;
75 if( fileStat->st_mode & S_IWUSR ) fe->permissions |= FE_PERM_U_WRITE | FE_PERM_U_DELETE | FE_PERM_U_CHATTR;;
76 if( fileStat->st_mode & S_IXUSR ) fe->permissions |= FE_PERM_U_EXEC;
77 if( fileStat->st_mode & S_IRGRP ) fe->permissions |= FE_PERM_G_READ;
78 if( fileStat->st_mode & S_IWGRP ) fe->permissions |= FE_PERM_G_WRITE | FE_PERM_G_DELETE | FE_PERM_G_CHATTR;
79 if( fileStat->st_mode & S_IXGRP ) fe->permissions |= FE_PERM_G_EXEC;
80 if( fileStat->st_mode & S_IROTH ) fe->permissions |= FE_PERM_O_READ;
81 if( fileStat->st_mode & S_IWOTH ) fe->permissions |= FE_PERM_O_WRITE | FE_PERM_O_DELETE | FE_PERM_O_CHATTR;;
82 if( fileStat->st_mode & S_IXOTH ) fe->permissions |= FE_PERM_O_EXEC;
83 if( fileStat->st_mode & S_ISUID ) fe->icbTag.flags |= ICBTAG_FLAG_SETUID;
84 if( fileStat->st_mode & S_ISGID ) fe->icbTag.flags |= ICBTAG_FLAG_SETGID;
85
86 fe->informationLength = fileStat->st_size;
87 updateTimestamp(fileStat->st_atime, 0);
88 fe->accessTime = timeStamp;
89 updateTimestamp(fileStat->st_mtime, 0);
90 fe->modificationTime = timeStamp;
91 updateTimestamp(fileStat->st_ctime, 0);
92 fe->attrTime = timeStamp;
93
94 /* check whether embedding of data is possible */
95 fe->logicalBlocksRecorded = ((fileStat->st_size + 2047) & ~2047) >> 11;
96
97 if( medium == CDR ) {
98 /* File data written in physical space but fileEntry in virtual space
99 * so must use long allocation descriptors
100 *
101 * Variable packet length restricted by drive buffer size.
102 * Must break up long file over several var packets.
103 * Only 116 long_ad's fit in fileEntry without going to extended alloc descs
104 */
105 long_ad *ad;
106 uint32_t loc;
107
108 maxVarPktSize = getMaxVarPktSize();
109
110 if( fe->informationLength / maxVarPktSize > 116 ) {
111 printf("Cannot handle files longer than %d\n", 116 * maxVarPktSize);
112 close(fd);
113 free(fe);
114 free(fid);
115 return CMND_FAILED;
116 }
117
118 fe->icbTag.flags |= ICBTAG_FLAG_AD_LONG;
119 /* +1 as the fileEntry itself occupies block NWA */
120 loc = getNWA() + 1 - pd->partitionStartingLocation;
121 nBytes = (uint32_t) fe->informationLength ;
122
123 for( ad = (long_ad*)(fe->allocDescs + fe->lengthExtendedAttr); nBytes > 0; ad++ ) {
124 if( nBytes > maxVarPktSize ) {
125 ad->extLength = maxVarPktSize;
126 nBytes -= maxVarPktSize;
127 } else {
128 ad->extLength = nBytes;
129 nBytes = 0;
130 }
131 ad->extLocation.logicalBlockNum = loc;
132 ad->extLocation.partitionReferenceNum = pd->partitionNumber;
133 *(uint32_t*)&((struct allocDescImpUse*)(ad->impUse))->impUse = (uint32_t) fe->uniqueID;
134 loc += ((ad->extLength + 2047) >> 11) + 7;
135 }
136
137 if( ((ad-1)->extLength & 2047) == 0 ) {
138 memset(ad, 0, sizeof(long_ad));
139 *(uint32_t*)&((struct allocDescImpUse*)(ad->impUse))->impUse = (uint32_t) fe->uniqueID;
140 ad++;
141 }
142
143 fe->lengthAllocDescs = (uint8_t*)ad - (fe->allocDescs + fe->lengthExtendedAttr);
144 fe->descTag.descCRCLength = sizeof(struct fileEntry) +
145 fe->lengthExtendedAttr + fe->lengthAllocDescs - sizeof(tag);
146 fe->descTag.tagLocation = newVATentry();
147
148 for( ;; ) { /* retry loop for verify failure */
149 int blknoFE, skipped, retries;
150 long_ad *extent;
151
152 setChecksum(fe);
153 skipped = 0;
154 retries = 0;
155 lseek(fd, 0, SEEK_SET);
156
157 /* write FE */
158 blknoFE = vat[fe->descTag.tagLocation] = writeCDR(fe) - pd->partitionStartingLocation;
159 fid->icb.extLocation.logicalBlockNum = fe->descTag.tagLocation;
160 fid->icb.extLocation.partitionReferenceNum = virtualPartitionNum;
161
162 /* write file data */
163 extent = (long_ad*)(fe->allocDescs + fe->lengthExtendedAttr);
164
165 for( blkInPkt = nBytes = 0; nBytes < fe->informationLength; extent++ ) {
166 blkno = extent->extLocation.logicalBlockNum;
167 if( blkno < blknoFE ) {
168 nBytes += extent->extLength;
169 skipped = 1;
170 continue;
171 }
172 for( i = 0; i < extent->extLength; blkno++, i += 2048 ) {
173 memset(p, 0, 2048);
174 if( skipped ) {
175 lseek(fd, nBytes, SEEK_SET);
176 skipped = 0;
177 }
178 nBytes += read(fd, p, 2048);
179 writeCDR(p);
180 if( ++blkInPkt == (maxVarPktSize >> 11) ) {
181 syncCDR();
182 blkInPkt = 0;
183 }
184 }
185 }
186
187 syncCDR();
188 if( verifyCDR(fe) == 0 ) // verify the file data
189 break;
190
191 if( retries++ > 3 ) {
192 printf("Retry count 3 exceeded\n");
193 break;
194 }
195 }
196 } else {
197 short_ad *extent, extentFE[2];
198
199 if( getExtents(2048, extentFE ) != 16 ) { /* extent for File Entry */
200 printf("No space for File Entry\n");
201 close(fd);
202 free(fe);
203 free(fid);
204 return CMND_FAILED;
205 }
206 fe->descTag.tagLocation = extentFE[0].extPosition;
207 // must mark allocated; otherwise allocated for a second time before being written
208 markBlock(ALLOC, fe->descTag.tagLocation);
209
210 fe->lengthAllocDescs = /* extents for the file data */
211 getExtents(fe->informationLength, (short_ad*)(fe->allocDescs + fe->lengthExtendedAttr));
212 if( !fe->lengthAllocDescs ) {
213 printf("No space for file\n");
214 close(fd);
215 free(fe);
216 free(fid);
217 return CMND_FAILED;
218 }
219 /* write FE */
220 fe->descTag.descCRCLength = sizeof(struct fileEntry) +
221 fe->lengthExtendedAttr + fe->lengthAllocDescs - sizeof(tag);
222 setChecksum(fe);
223 writeBlock(fe->descTag.tagLocation, pd->partitionNumber, fe);
224 fid->icb.extLocation.logicalBlockNum = fe->descTag.tagLocation;
225 fid->icb.extLocation.partitionReferenceNum = pd->partitionNumber;
226
227 /* write file data */
228 extent = (short_ad*)(fe->allocDescs + fe->lengthExtendedAttr);
229 for( nBytes = 0; nBytes < fe->informationLength; extent++ ) {
230 blkno = extent->extPosition;
231 for( i = 0; i < extent->extLength; blkno++, i += 2048 ) {
232 memset(p, 0, 2048);
233 nBytes += read(fd, p, 2048);
234 writeBlock(blkno, pd->partitionNumber, p);
235 }
236 }
237 }
238
239 if( devicetype == DISK_IMAGE && medium == CDR )
240 writeHDlink();
241
242 *(uint32_t*)(&( (struct allocDescImpUse*)fid->icb.impUse)->impUse) = (uint32_t) fe->uniqueID;
243 insertFileIdentDesc(dir, fid);
244 ((struct logicalVolIntegrityDescImpUse*)
245 (lvid->impUse + 2 * sizeof(uint32_t) * lvid->numOfPartitions))->numFiles++;
246
247 close(fd);
248 free(fe);
249 free(fid);
250 return CMND_OK;
251 }
252
253
254 int
255 copyDirectory(Directory *dir, char* name)
256 {
257 DIR *srcDir;
258 Directory *workDir;
259 struct dirent *dirEnt;
260 struct stat dirEntStat;
261 struct fileIdentDesc *fid;
262
263 if( !(srcDir = opendir(name)) ) {
264 printf("Open dir '%s': %m\n", name);
265 return CMND_FAILED;
266 }
267
268 if( chdir(name) != 0 ) {
269 printf("Change dir '%s': %m\n", name);
270 closedir(srcDir);
271 return CMND_FAILED;
272 }
273
274 printf("Now in %s\n", getcwd(NULL, 0));
275 workDir = dir;
276
277 while( (dirEnt = readdir(srcDir)) ) {
278 if( !strcmp(dirEnt->d_name, ".") || !strcmp(dirEnt->d_name, "..") )
279 continue;
280
281 if( lstat(dirEnt->d_name, &dirEntStat) != 0 ) { // do not follow links
282 printf("Stat dirEnt '%s' failed: %s\n", dirEnt->d_name, strerror(errno));
283 continue;
284 }
285
286 if( S_ISDIR(dirEntStat.st_mode) ) {
287 if( !(options & OPT_RECURSIVE) ) {
288 printf("Not recursive. Ignoring '%s' directory\n", dirEnt->d_name);
289 continue;
290 }
291 fid = findFileIdentDesc(dir, dirEnt->d_name);
292
293 if( fid && !(fid->fileCharacteristics & FID_FILE_CHAR_DIRECTORY ) ) {
294 printf("'%s' exists but is not a directory\n", dirEnt->d_name);
295 continue;
296 }
297 if( fid && (fid->fileCharacteristics & FID_FILE_CHAR_DELETED) ) {
298 removeFID(dir, fid);
299 fid = NULL;
300 }
301 if( !fid )
302 workDir = makeDir(dir, dirEnt->d_name);
303 else
304 workDir = readDirectory(dir, &fid->icb, dirEnt->d_name);
305 copyDirectory(workDir, dirEnt->d_name);
306 } else {
307 if( S_ISREG(dirEntStat.st_mode) )
308 copyFile(workDir, dirEnt->d_name, dirEnt->d_name, &dirEntStat);
309 }
310 }
311
312 if( chdir("..") != 0 )
313 printf("Change dir '..': %m\n");
314
315 closedir(srcDir);
316 return CMND_OK;
317 }
318
319
320 /* deleteDirectory()
321 *
322 * Recursing into subdirectories.
323 * If anywhere no permission, query deletion but proceed if 'yes'
324 * Returns 0 if fid freed, 1 if fid not empty
325 */
326 int
327 deleteDirectory(Directory *dir, struct fileIdentDesc* fid)
328 {
329 uint64_t i;
330 int rv, notEmpty;
331 char *name;
332 struct fileIdentDesc *childFid;
333 Directory *childDir;
334
335 rv = 0;
336
337 if( fid->fileCharacteristics & FID_FILE_CHAR_DELETED )
338 return CMND_OK;
339
340 if( (fid->fileCharacteristics & FID_FILE_CHAR_DIRECTORY) == 0 )
341 return deleteFID(dir, fid); /* delete regular files */
342
343 name = malloc(fid->lengthFileIdent + 1);
344 strncpy(name, (char *)(fid->fileIdent + fid->lengthOfImpUse), fid->lengthFileIdent);
345 name[fid->lengthFileIdent] = 0;
346 readDirectory(dir, &fid->icb, name);
347 childDir = dir->child;
348
349 /* check permission */
350
351 notEmpty = 0;
352
353 for( i = 0; i < childDir->fe.informationLength;
354 i += ((sizeof(struct fileIdentDesc) + childFid->lengthOfImpUse + childFid->lengthFileIdent + 3) & ~3) )
355 {
356 childFid = (struct fileIdentDesc*)(childDir->data + i);
357 if( childFid->fileCharacteristics & (FID_FILE_CHAR_DELETED | FID_FILE_CHAR_PARENT) )
358 continue;
359 if( childFid->fileCharacteristics & FID_FILE_CHAR_DIRECTORY )
360 deleteDirectory( childDir, childFid);
361 else
362 deleteFID(childDir, childFid);
363 }
364
365 if( directoryIsEmpty(childDir) ) {
366 rv |= deleteFID(dir, fid);
367 } else {
368 childDir->dirDirty = 1;
369 updateDirectory(childDir);
370 rv = notEmpty;
371 }
372 free(name);
373 return rv;
374 }
375
376
377 /* readDirectory()
378 * All fileIdentDesc's are put into the data area of the Directory structure.
379 * irrespective whether they were embedded or separately in allocated extents.
380 * updateDirectory() will embed or write in separate extents as appropriate.
381 */
382 Directory *
383 readDirectory(Directory *parentDir, long_ad* icb, char *name)
384 {
385 char *p;
386 uint32_t len;
387 Directory *dir;
388
389 if( parentDir == NULL )
390 dir = rootDir;
391 else {
392 dir = parentDir->child;
393 if( dir == NULL ) {
394 parentDir->child = dir = (Directory*)malloc(sizeof(Directory));
395 memset(dir, 0, sizeof(Directory));
396 dir->parent = parentDir;
397 dir->dataSize = 4096;
398 dir->data = malloc(4096);
399 if( dir->name ) free(dir->name);
400 dir->name = malloc(strlen(name) + 1);
401 strcpy(dir->name, name);
402 } else
403 if( dir->icb.extLocation.logicalBlockNum == icb->extLocation.logicalBlockNum
404 && dir->icb.extLocation.partitionReferenceNum == icb->extLocation.partitionReferenceNum )
405 return dir; // already the one requested
406 }
407
408 if( dir->dirDirty )
409 updateDirectory(dir);
410
411 dir->icb = *icb;
412 if( name[0] ) {
413 if( dir->name ) free(dir->name);
414 dir->name = malloc(strlen(name) + 1);
415 strcpy(dir->name, name);
416 }
417 p = readTaggedBlock(icb->extLocation.logicalBlockNum, icb->extLocation.partitionReferenceNum);
418 memcpy(&dir->fe, p, 2048);
419
420 if( (dir->fe.icbTag.flags & ICBTAG_FLAG_AD_MASK) == ICBTAG_FLAG_AD_IN_ICB ) {
421 memcpy(dir->data, dir->fe.allocDescs + dir->fe.lengthExtendedAttr, dir->fe.lengthAllocDescs);
422 memset(dir->fe.allocDescs + dir->fe.lengthExtendedAttr, 0, dir->fe.lengthAllocDescs);
423 } else {
424 if( dir->fe.informationLength > dir->dataSize ) {
425 len = (dir->fe.informationLength + 2047) & ~2047;
426 dir->data = realloc(dir->data, len);
427 if( !dir->data ) {
428 printf("Realloc directory data failed\n");
429 return NULL;
430 }
431 dir->dataSize = len;
432 }
433 readExtents(dir->data, (dir->fe.icbTag.flags & ICBTAG_FLAG_AD_MASK) == ICBTAG_FLAG_AD_SHORT,
434 dir->fe.allocDescs + dir->fe.lengthExtendedAttr);
435 if( medium == CDRW ) {
436 if( (dir->fe.icbTag.flags & ICBTAG_FLAG_AD_MASK) == ICBTAG_FLAG_AD_SHORT )
437 freeShortExtents((short_ad*)(dir->fe.allocDescs + dir->fe.lengthExtendedAttr));
438 else if( (dir->fe.icbTag.flags & ICBTAG_FLAG_AD_MASK) == ICBTAG_FLAG_AD_LONG )
439 freeLongExtents((long_ad*)(dir->fe.allocDescs + dir->fe.lengthExtendedAttr));
440 }
441 }
442 printf("Read dir %s\n", dir->name);
443 return dir;
444 }
445
446
447 /* updateDirectory()
448 * Extents and ICB AllocMask are unchanged since reading the directory from CD.
449 * Based on current informationLength will have to decide embedding or on output extents required
450 * and free any superfluous extents
451 */
452 int
453 updateDirectory(Directory* dir)
454 {
455 uint64_t i;
456 struct fileIdentDesc *fid;
457
458 if( dir->child )
459 updateDirectory(dir->child);
460
461 if( !dir->dirDirty )
462 return CMND_OK;
463
464 if( sizeof(struct fileEntry) + dir->fe.lengthExtendedAttr + dir->fe.informationLength <= 2048 ) {
465 /* fileIdentDescs embedded in directory ICB */
466 dir->fe.logicalBlocksRecorded = 0;
467 dir->fe.icbTag.flags = (dir->fe.icbTag.flags & ~ICBTAG_FLAG_AD_MASK) | ICBTAG_FLAG_AD_IN_ICB;
468 dir->fe.lengthAllocDescs = dir->fe.informationLength;
469 memcpy(dir->fe.allocDescs + dir->fe.lengthExtendedAttr, dir->data, dir->fe.lengthAllocDescs);
470
471 /* UDF2.00 2.2.1.3 - For a structure in virtual space, tagLocation is the virtual location */
472 for( i = 0; i < dir->fe.informationLength;
473 i += (sizeof(struct fileIdentDesc) + fid->lengthOfImpUse + fid->lengthFileIdent + 3) & ~3 )
474 {
475 fid = (struct fileIdentDesc*) (dir->fe.allocDescs + i);
476 fid->descTag.tagLocation = dir->icb.extLocation.logicalBlockNum;
477 setChecksum(&fid->descTag);
478 }
479 } else {
480 /* get new extents for the directory data */
481 dir->fe.logicalBlocksRecorded = ((dir->fe.informationLength + 2047) & ~2047) >> 11;
482
483 if( medium == CDR ) {
484 long_ad *ad;
485 uint32_t blkno;
486
487 dir->fe.icbTag.flags = (dir->fe.icbTag.flags & ~ ICBTAG_FLAG_AD_MASK) | ICBTAG_FLAG_AD_LONG;
488 ad = (long_ad*)(dir->fe.allocDescs + dir->fe.lengthExtendedAttr);
489 ad->extLength = dir->fe.informationLength;
490 ad->extLocation.logicalBlockNum = blkno = getNWA() + 1 - pd->partitionStartingLocation;
491 ad->extLocation.partitionReferenceNum = pd->partitionNumber;
492 *(uint32_t*)&((struct allocDescImpUse*)(ad->impUse))->impUse = (uint32_t) dir->fe.uniqueID;
493 memset(ad + 1, 0, sizeof(long_ad)); /* necessary only if infolength multiple of 2048 */
494 dir->fe.lengthAllocDescs = 2 * sizeof(long_ad);
495
496 /* set tagLocation in all FIDs */
497 for( i = 0; i < dir->fe.informationLength;
498 i += (sizeof(struct fileIdentDesc) + fid->lengthOfImpUse + fid->lengthFileIdent + 3) & ~3 )
499 {
500 fid = (struct fileIdentDesc*) (dir->data + i);
501 fid->descTag.tagLocation = blkno + (i >> 11);
502 fid->descTag.descCRCLength =
503 ((sizeof(struct fileIdentDesc) + fid->lengthOfImpUse + fid->lengthFileIdent + 3) & ~3) - sizeof(tag);
504 setChecksum(fid);
505 }
506
507 } else {
508 uint32_t *blocks, blkno, len;
509 short_ad *extent;
510
511 extent =(short_ad*)(dir->fe.allocDescs + dir->fe.lengthExtendedAttr);
512 dir->fe.lengthAllocDescs = getExtents(dir->fe.informationLength, extent);
513 dir->fe.icbTag.flags = (dir->fe.icbTag.flags & ~ICBTAG_FLAG_AD_MASK) | ICBTAG_FLAG_AD_SHORT;
514
515 /* find which blocks are to going be used to set tagLocations */
516 blocks = (uint32_t*)malloc(dir->fe.logicalBlocksRecorded * sizeof(uint32_t));
517 blkno = extent->extPosition;
518 len = extent->extLength;
519 for( i = 0; i < dir->fe.logicalBlocksRecorded; i++ ) {
520 blocks[i] = blkno;
521 if( len <= 2048 ) {
522 extent++;
523 blkno = extent->extPosition;
524 len = extent->extLength;
525 } else {
526 len -= 2048;
527 blkno++;
528 }
529 }
530 /* set tagLocation */
531 for( i = 0; i < dir->fe.informationLength;
532 i += (sizeof(struct fileIdentDesc) + fid->lengthOfImpUse + fid->lengthFileIdent + 3) & ~3 )
533 {
534 fid = (struct fileIdentDesc*) (dir->data + i);
535 fid->descTag.tagLocation = blocks[i >> 11];
536 fid->descTag.descCRCLength =
537 ((sizeof(struct fileIdentDesc) + fid->lengthOfImpUse + fid->lengthFileIdent + 3) & ~3) - sizeof(tag);
538 setChecksum(fid);
539 }
540 free(blocks);
541 }
542 }
543
544 dir->fe.descTag.descCRCLength =
545 sizeof(struct fileEntry) + dir->fe.lengthExtendedAttr + dir->fe.lengthAllocDescs - sizeof(tag);
546 setChecksum(&dir->fe);
547
548 if( medium == CDRW ) {
549 /* write the directory fileEntry */
550 writeBlock(dir->icb.extLocation.logicalBlockNum, dir->icb.extLocation.partitionReferenceNum, &dir->fe);
551
552 if( dir->fe.logicalBlocksRecorded ) {
553 /* write any directory data */
554 writeExtents(dir->data, 1, (short_ad*)(dir->fe.allocDescs + dir->fe.lengthExtendedAttr));
555 }
556 } else { /* medium == CDR */
557 int retries;
558
559 retries = 0;
560
561 for( ;; ) { /* loop only when verify failed */
562 uint32_t pbn;
563
564 /* write the directory fileEntry */
565 pbn = writeCDR(&dir->fe);
566 vat[((long_ad*)&dir->icb)->extLocation.logicalBlockNum] = pbn - pd->partitionStartingLocation;
567
568 if( dir->fe.logicalBlocksRecorded )
569 for( i = 0; i < dir->fe.informationLength; i += 2048 )
570 writeCDR(dir->data + i);
571
572 if( verifyCDR(&dir->fe) == 0 )
573 break;
574
575 if( ++retries > 3 ) {
576 printf("updateDirectory: '%s' failed\n", dir->name);
577 return CMND_FAILED;
578 }
579 }
580 }
581 dir->dirDirty = 0;
582 printf("Wrote dir %s\n", dir->name);
583 return CMND_OK;
584 }
585
586
587 /* Create subdirectory called 'name' in 'dir'
588 */
589 Directory *
590 makeDir(Directory *dir, char* name )
591 {
592 Directory *newDir;
593 struct fileEntry *fe;
594 struct fileIdentDesc *backFid, *forwFid;
595 short_ad allocDescs[2];
596
597
598 /* back reference to parent in new directory */
599 backFid = makeFileIdentDesc("");
600 backFid->icb = dir->icb;
601 backFid->fileCharacteristics = FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT;
602 backFid->descTag.descCRCLength = ((sizeof(struct fileIdentDesc) + 3) & ~3) - sizeof(tag);
603
604 fe = makeFileEntry();
605 fe->icbTag.fileType = ICBTAG_FILE_TYPE_DIRECTORY;
606 fe->icbTag.flags = ICBTAG_FLAG_AD_IN_ICB;
607 fe->informationLength = (sizeof(struct fileIdentDesc) + 3) & ~3;
608
609 /* forward reference to new directory in parent directory */
610 forwFid = makeFileIdentDesc(name);
611 forwFid->fileCharacteristics = FID_FILE_CHAR_DIRECTORY;
612 *(uint32_t*)(&( (struct allocDescImpUse*)forwFid->icb.impUse)->impUse) = (uint32_t) fe->uniqueID;
613
614 if( medium == CDR ) {
615 fe->descTag.tagLocation = newVATentry();
616 forwFid->icb.extLocation.logicalBlockNum = fe->descTag.tagLocation;
617 forwFid->icb.extLocation.partitionReferenceNum = virtualPartitionNum;
618 } else {
619 if( getExtents( 2048, allocDescs) != 16 )
620 fail("makeDir: Could not get File Entry extent\n");
621
622 markBlock(ALLOC, allocDescs[0].extPosition);
623 fe->descTag.tagLocation = allocDescs[0].extPosition;
624 backFid->descTag.tagLocation = allocDescs[0].extPosition;
625 forwFid->icb.extLocation.logicalBlockNum = allocDescs[0].extPosition;
626 forwFid->icb.extLocation.partitionReferenceNum = pd->partitionNumber;
627 setChecksum(&backFid->descTag);
628 fe->descTag.descCRCLength = sizeof(struct fileEntry) + fe->lengthAllocDescs - sizeof(tag);
629 setChecksum(fe);
630 }
631
632 insertFileIdentDesc(dir, forwFid);
633 dir->fe.fileLinkCount++;
634 dir->dirDirty = 1;
635
636 /* setup directory structure for new directory */
637 newDir = dir->child;
638
639 if( newDir != NULL )
640 updateDirectory(newDir);
641 else {
642 newDir = (Directory*)malloc(sizeof(Directory));
643 memset(newDir, 0, sizeof(Directory));
644 newDir->parent = dir;
645 newDir->dataSize = 4096;
646 newDir->data = malloc(4096);
647 dir->child = newDir;
648 }
649
650 memset(newDir->data, 0, newDir->dataSize);
651 newDir->name = malloc(strlen(name)+1);
652 strcpy(newDir->name, name);
653 newDir->icb = forwFid->icb;
654 memcpy(&newDir->fe, fe, 2048);
655 memcpy(newDir->data, backFid, fe->informationLength);
656 newDir->dirDirty = 1;
657
658 ((struct logicalVolIntegrityDescImpUse*)
659 (lvid->impUse + 2 * sizeof(uint32_t) * lvid->numOfPartitions))->numDirs++;
660 free(backFid);
661 free(forwFid);
662 free(fe);
663 return newDir;
664 }
665
666
667 /* analyzeDest()
668 *
669 * The last argument in a command is the destination for copying or the object
670 * to act on. The argument consists of / separated components
671 * eg. /src/test/udf/wrudf.h or /src/test/iso/
672 * or just a single component eg. . or / or wrudf.c
673 *
674 * All but the last component must be existing directories and curDir points to
675 * the last directopry in that chain, eg. udf, otherwise result DIR_INVALID.
676 *
677 * When the last component does not exist, return result DOES_NOT_EXIST.
678 * name --> last component eg. wrudf.h or iso
679 *
680 * If the last component identifies a directory return EXISTING_DIR or DELETED_DIR,
681 * *fid = NULL, *name = last component name eg. iso.
682 *
683 * If the last component is a file return EXISTING_FILE or DELETED_FILE.
684 * *fid points to FID entry in curDir with name equal the last component.
685 * *name --> last component name eg. wrudf.h
686 */
687 enum RV
688 analyzeDest(char* arg, struct fileIdentDesc** fid, char** name)
689 {
690 int len;
691 char *comp, *endComp;
692
693 if( arg[0] == '/' ) {
694 curDir = rootDir;
695 comp = arg + 1;
696 } else {
697 comp = arg;
698 }
699
700 len = strlen(comp);
701 if( len > 1 && comp[len-1] == '/' )
702 comp[len-1] = 0; /* remove any trailing slash */
703
704 for( ; ( endComp = strchr(comp, '/') ) != NULL; comp = ++endComp ) {
705 *endComp = 0;
706
707 if( strcmp(comp, ".") == 0 )
708 continue;
709
710 if( strcmp(comp, "..") == 0 ) {
711 if( !curDir->parent )
712 return DIR_INVALID;
713 curDir = curDir->parent;
714 continue;
715 }
716
717 *fid = findFileIdentDesc(curDir, comp);
718 if( *fid == NULL )
719 return DIR_INVALID;
720 if( ! ((*fid)->fileCharacteristics & FID_FILE_CHAR_DIRECTORY ))
721 return DIR_INVALID;
722 if( (*fid)->fileCharacteristics & FID_FILE_CHAR_DELETED )
723 return DIR_INVALID;
724
725 // curDir = readDirectory(curDir->child, &(*fid)->icb, comp);
726 curDir = readDirectory(curDir, &(*fid)->icb, comp);
727 }
728
729 // final component
730 *name = comp;
731
732 if( comp[0] == 0 || strcmp(comp, ".") == 0 )
733 return EXISTING_DIR;
734
735 if( strcmp(comp, "..") == 0 ) {
736 if( !curDir->parent )
737 return DIR_INVALID;
738 curDir = curDir->parent;
739 return EXISTING_DIR;
740 }
741
742 *fid = findFileIdentDesc(curDir, comp);
743
744 if( *fid == NULL )
745 return DOES_NOT_EXIST;
746
747 if( (*fid)->fileCharacteristics & FID_FILE_CHAR_DIRECTORY ) {
748 if( (*fid)->fileCharacteristics & FID_FILE_CHAR_DELETED )
749 return DELETED_DIR;
750 else {
751 curDir = readDirectory(curDir, &(*fid)->icb, comp);
752 return EXISTING_DIR;
753 }
754 } else {
755 if( (*fid)->fileCharacteristics & FID_FILE_CHAR_DELETED )
756 return DELETED_FILE;
757 }
758 return EXISTING_FILE;
759 }
760
761
762 int
763 cpCommand(void)
764 {
765 int i, rv;
766 enum RV state;
767 char *srcname, *name, *p;
768 Directory *cpyDir;
769 struct fileIdentDesc *fid, *newFid;
770 struct stat fileStat;
771
772 if( cmndc < 2 )
773 return WRONG_NO_ARGS;
774
775 name = NULL;
776 state = analyzeDest(cmndv[cmndc-1], &fid, &name);
777
778 if( state == DIR_INVALID )
779 return DIR_INVALID;
780
781 if( state == DELETED_DIR ) {
782 printf("Cannot reuse deleted directory name yet\n");
783 return CMND_FAILED;
784 }
785
786 if( state == DELETED_FILE ) {
787 removeFID(curDir, fid);
788 state = DOES_NOT_EXIST;
789 }
790
791 if( state == EXISTING_FILE ) {
792 if( questionOverwrite(curDir, fid, name) )
793 return CMND_FAILED;
794 state = DOES_NOT_EXIST;
795 }
796
797 /* do I have write permission for the destination directory ? */
798
799 /* process source arguments */
800 for( i = 0; i < cmndc - 1; i++ ) {
801 p = strrchr(cmndv[i], '/');
802
803 if( p && p > cmndv[i] && *(p+1) == 0 ) *p = 0; // remove any trailing slash (except in "/")
804
805 p = strrchr(cmndv[i], '/');
806
807 if( p ) {
808 srcname = p+1;
809 } else
810 srcname = cmndv[i];
811
812 if( (rv = lstat(cmndv[i], &fileStat)) < 0 ) { // do not follow soft links
813 printf("stat failed on %s\n", cmndv[i]);
814 continue;
815 }
816
817 if( S_ISDIR(fileStat.st_mode) ) {
818 if( state == EXISTING_DIR ) {
819 newFid = findFileIdentDesc(curDir, srcname);
820 if( newFid == NULL ) {
821 cpyDir = makeDir(curDir, srcname);
822 newFid = findFileIdentDesc(curDir, srcname);
823 } else {
824 if( newFid->fileCharacteristics != FID_FILE_CHAR_DIRECTORY ) {
825 printf("Destination is not a directory\n");
826 return CMND_FAILED;
827 }
828 cpyDir = readDirectory(curDir, &newFid->icb, srcname);
829 }
830 if( chdir(cmndv[i]) != 0 )
831 printf("Change dir '%s': %m\n", cmndv[i]);
832 else
833 copyDirectory(cpyDir, ".");
834 } else
835 printf("Destination is not a directory\n");
836
837 if( chdir(hdWorkingDir) != 0 ) {
838 printf("Change dir '%s': %m\n", hdWorkingDir);
839 return CMND_FAILED;
840 }
841 continue;
842 }
843
844 if( !S_ISREG(fileStat.st_mode) ) {
845 printf("Can only copy regular files or directories\n");
846 return CMND_FAILED;
847 }
848
849 if( state == DOES_NOT_EXIST || state == EXISTING_DIR )
850 name = srcname;
851
852 copyFile(curDir, cmndv[i], name, &fileStat);
853 }
854 return CMND_OK;
855 }
856
857
858 int
859 rmCommand(void)
860 {
861 enum RV state;
862 int i;
863 struct fileIdentDesc *fid;
864 char* name;
865
866 if( cmndc < 1 )
867 return CMND_ARG_INVALID;
868
869 for( i = 0; i < cmndc; i++ ) {
870 state = analyzeDest(cmndv[i], &fid, &name);
871
872 if( state == EXISTING_FILE ) {
873 deleteFID(curDir, fid);
874 continue;
875 }
876
877 if( state != EXISTING_DIR )
878 return state;
879
880 if( options & OPT_RECURSIVE ) {
881 deleteDirectory(curDir, fid);
882 continue;
883 } else
884 printf("Cannot delete directory '%s' without -r option\n", cmndv[i]);
885 }
886 return CMND_OK;
887 }
888
889
890 int
891 mkdirCommand(void)
892 {
893 int rv;
894 char *name;
895 struct fileIdentDesc *fid;
896 Directory *newDir;
897
898 if( cmndc != 1 )
899 return WRONG_NO_ARGS;
900
901 rv = analyzeDest(cmndv[0], &fid, &name);
902
903 if( rv == DIR_INVALID )
904 return DIR_INVALID;
905
906 if( rv == EXISTING_FILE || rv == EXISTING_DIR ) {
907 if( fid->fileCharacteristics & FID_FILE_CHAR_DELETED ) {
908 removeFID(curDir, fid);
909 } else
910 return rv;
911 }
912
913 newDir = makeDir(curDir, name);
914
915 if( !newDir )
916 return CMND_FAILED;
917
918 curDir = newDir;
919 return CMND_OK;
920 }
921
922
923 int
924 rmdirCommand(void)
925 {
926 int state;
927 struct fileIdentDesc *fid;
928 char* name;
929
930 if( cmndc != 1 )
931 return WRONG_NO_ARGS;
932
933 state = analyzeDest(cmndv[0], &fid, &name);
934
935 if( state != EXISTING_DIR )
936 return state;
937
938 if( !directoryIsEmpty(curDir) )
939 return DIR_NOT_EMPTY;
940
941 if( !curDir->parent ) {
942 printf("Cannot remove root directory\n");
943 return CMND_FAILED;
944 }
945 return deleteFID(curDir, fid);
946 }
947
948 int cdcCommand() {
949 int state;
950 struct fileIdentDesc *fid;
951 char* name;
952
953 if( cmndc != 1 )
954 return WRONG_NO_ARGS;
955
956 state = analyzeDest(cmndv[0], &fid, &name);
957
958 if( state != EXISTING_DIR )
959 return state;
960
961 return CMND_OK;
962 }
963
964 int lscCommand(void) {
965 struct fileIdentDesc *fid;
966 struct fileEntry *fe;
967 char *name, filename[512];
968 uint64_t i;
969 int state;
970
971 if( cmndc > 1 )
972 return WRONG_NO_ARGS;
973
974 if( cmndc == 1 ) {
975 state = analyzeDest(cmndv[0], &fid, &name);
976
977 if( state != EXISTING_DIR )
978 return state;
979 }
980
981 for( i = 0; i < curDir->fe.informationLength;
982 i += ((sizeof(struct fileIdentDesc) + fid->lengthOfImpUse + fid->lengthFileIdent + 3) & ~3) )
983 {
984 fid = (struct fileIdentDesc*)(curDir->data + i);
985 if( fid->fileCharacteristics & FID_FILE_CHAR_DELETED )
986 continue;
987
988 if( fid->fileCharacteristics & FID_FILE_CHAR_PARENT )
989 strcpy(filename, "..");
990 else {
991 memset(filename, 0, sizeof(filename));
992 strncpy(filename, (char *)(fid->fileIdent + fid->lengthOfImpUse + 1), fid->lengthFileIdent - 1);
993 /* Look at udf filesystem how to convert dstring to ordinary characters */
994 }
995
996 fe = readTaggedBlock( fid->icb.extLocation.logicalBlockNum, fid->icb.extLocation.partitionReferenceNum);
997
998 printf("%s %6d:%c%c%c%c%c %6d:%c%c%c%c%c other:%c%c%c%c%c links:%2d info:%12d %s\n",
999 fe->icbTag.fileType == ICBTAG_FILE_TYPE_DIRECTORY ? "DIR" : " ",
1000 fe->uid,
1001 fe->permissions & FE_PERM_U_READ ? 'r' : '-',
1002 fe->permissions & FE_PERM_U_WRITE ? 'w' : '-',
1003 fe->permissions & FE_PERM_U_EXEC ? 'x' : '-',
1004 fe->permissions & FE_PERM_U_CHATTR ? 'a' : '-',
1005 fe->permissions & FE_PERM_U_DELETE ? 'd' : '-',
1006 fe->gid,
1007 fe->permissions & FE_PERM_G_READ ? 'r' : '-',
1008 fe->permissions & FE_PERM_G_WRITE ? 'w' : '-',
1009 fe->permissions & FE_PERM_G_EXEC ? 'x' : '-',
1010 fe->permissions & FE_PERM_G_CHATTR ? 'a' : '-',
1011 fe->permissions & FE_PERM_G_DELETE ? 'd' : '-',
1012 fe->permissions & FE_PERM_O_READ ? 'r' : '-',
1013 fe->permissions & FE_PERM_O_WRITE ? 'w' : '-',
1014 fe->permissions & FE_PERM_O_EXEC ? 'x' : '-',
1015 fe->permissions & FE_PERM_O_CHATTR ? 'a' : '-',
1016 fe->permissions & FE_PERM_O_DELETE ? 'd' : '-',
1017 fe->fileLinkCount, (uint32_t)fe->informationLength, filename);
1018 }
1019 return CMND_OK;
1020 }
1021
1022 int cdhCommand()
1023 {
1024 if( cmndc > 1 )
1025 return WRONG_NO_ARGS;
1026
1027 if( chdir(cmndv[0]) != 0 ) {
1028 printf("Change dir '%s': %m\n", cmndv[0]);
1029 return CMND_FAILED;
1030 }
1031
1032 if( hdWorkingDir ) free(hdWorkingDir);
1033 hdWorkingDir = getcwd(NULL, 0);
1034 printf("Harddisk working directory set to %s\n", cmndv[0]);
1035 return CMND_OK;
1036 }
1037
1038
1039 int lshCommand() {
1040 char cmnd[128];
1041
1042 if( cmndc > 1 )
1043 return WRONG_NO_ARGS;
1044
1045 strcpy(cmnd, "ls -l ");
1046
1047 if( cmndc == 1 )
1048 strncat(cmnd, cmndv[0], sizeof(cmnd)-strlen("ls -l ")-1);
1049
1050 if( system(cmnd) != 0 )
1051 return CMND_FAILED;
1052
1053 return CMND_OK;
1054 }
1055
1056
1057
1058 /* directoryIsEmpty()
1059 * Return 1 if a directory contains only a parent dir entry and, possibly 0, deleted entries;
1060 * Otherwise return 0;
1061 */
1062 int
1063 directoryIsEmpty(Directory *dir)
1064 {
1065 uint64_t i;
1066 struct fileIdentDesc *fid;
1067
1068 for( i = 0; i < dir->fe.informationLength;
1069 i += ((sizeof(struct fileIdentDesc) + fid->lengthOfImpUse + fid->lengthFileIdent + 3) & ~3) )
1070 {
1071 fid = (struct fileIdentDesc*)(dir->data + i);
1072 if( fid->fileCharacteristics & (FID_FILE_CHAR_DELETED | FID_FILE_CHAR_PARENT) )
1073 continue;
1074 return 0;
1075 }
1076 return 1;
1077 }
1078
1079
1080 /* questionOverwrite()
1081 * Query whether to overwrite existing file.
1082 * Remove the FID entry from the directory if reply was 'y' and return 0.
1083 * Return 1 if don't overwrite.
1084 */
1085 int
1086 questionOverwrite(Directory *dir, struct fileIdentDesc *fid, char* name)
1087 {
1088 printf("File %s already exists. Overwrite ? (y/N) : ", name);
1089 #ifdef _GNU_SOURCE
1090 readLine(NULL);
1091 #else
1092 fgets(line, 256, stdin);
1093 #endif
1094 if( !line || line[0] != 'y' )
1095 return 1;
1096 deleteFID(dir, fid);
1097 return 0;
1098 }
1099
1100
timeStamp
timestamp timeStamp
Definition: wrudf.c:49
allocDescs
extent_ad allocDescs[0]
Definition: ecma_167.h:67
setChecksum
void setChecksum(void *descriptor)
Definition: wrudf-cdrw.c:229
FE_PERM_G_CHATTR
#define FE_PERM_G_CHATTR
Definition: ecma_167.h:593
options
uint32_t options
Definition: wrudf.c:45
fileEntry::lengthExtendedAttr
uint32_t lengthExtendedAttr
Definition: ecma_167.h:578
fileEntry::uid
uint32_t uid
Definition: ecma_167.h:562
DOES_NOT_EXIST
Definition: wrudf.h:61
line
char line[256]
Definition: wrudf.c:27
getMaxVarPktSize
uint32_t getMaxVarPktSize()
Definition: wrudf-cdr.c:48
readTaggedBlock
void * readTaggedBlock(uint32_t lbn, uint16_t partition)
Definition: wrudf-cdrw.c:639
_dir_::dataSize
uint32_t dataSize
Definition: wrudf.h:89
freeLongExtents
int freeLongExtents(long_ad *extents)
Definition: wrudf-cdrw.c:176
fileEntry::icbTag
icbtag icbTag
Definition: ecma_167.h:561
FE_PERM_G_DELETE
#define FE_PERM_G_DELETE
Definition: ecma_167.h:594
directoryIsEmpty
int directoryIsEmpty(Directory *dir)
Definition: wrudf-cmnd.c:1063
OPT_RECURSIVE
#define OPT_RECURSIVE
Definition: wrudf.h:72
_dir_::parent
struct _dir_ * parent
Definition: wrudf.h:88
FID_FILE_CHAR_PARENT
#define FID_FILE_CHAR_PARENT
Definition: ecma_167.h:477
deleteDirectory
int deleteDirectory(Directory *dir, struct fileIdentDesc *fid)
Definition: wrudf-cmnd.c:327
partitionDesc::partitionNumber
uint16_t partitionNumber
Definition: ecma_167.h:265
DELETED_DIR
Definition: wrudf.h:61
fileEntry::logicalBlocksRecorded
uint64_t logicalBlocksRecorded
Definition: ecma_167.h:570
lshCommand
int lshCommand()
Definition: wrudf-cmnd.c:1039
partitionDesc::partitionStartingLocation
uint32_t partitionStartingLocation
Definition: ecma_167.h:269
cmndv
char ** cmndv
Definition: wrudf.c:34
medium
enum MEDIUM medium
Definition: wrudf.c:20
markBlock
void markBlock(enum markAction action, uint32_t blkno)
Definition: wrudf-cdrw.c:74
ICBTAG_FLAG_AD_MASK
#define ICBTAG_FLAG_AD_MASK
Definition: ecma_167.h:525
rmdirCommand
int rmdirCommand(void)
Definition: wrudf-cmnd.c:924
makeFileIdentDesc
struct fileIdentDesc * makeFileIdentDesc(char *name)
Definition: wrudf-desc.c:187
FE_PERM_O_CHATTR
#define FE_PERM_O_CHATTR
Definition: ecma_167.h:588
FE_PERM_G_EXEC
#define FE_PERM_G_EXEC
Definition: ecma_167.h:590
_dir_::name
char * name
Definition: wrudf.h:92
fileEntry::permissions
uint32_t permissions
Definition: ecma_167.h:564
FE_PERM_G_WRITE
#define FE_PERM_G_WRITE
Definition: ecma_167.h:591
mkdirCommand
int mkdirCommand(void)
Definition: wrudf-cmnd.c:891
icb
long_ad icb
Definition: ecma_167.h:68
makeDir
Directory * makeDir(Directory *dir, char *name)
Definition: wrudf-cmnd.c:590
FE_PERM_U_DELETE
#define FE_PERM_U_DELETE
Definition: ecma_167.h:599
cpCommand
int cpCommand(void)
Definition: wrudf-cmnd.c:763
_dir_::child
struct _dir_ * child
Definition: wrudf.h:88
CDRW
Definition: wrudf.h:40
verifyCDR
int verifyCDR(struct fileEntry *fe)
Definition: wrudf-cdr.c:200
FE_PERM_U_READ
#define FE_PERM_U_READ
Definition: ecma_167.h:597
writeHDlink
void writeHDlink()
Definition: wrudf-cdr.c:107
syncCDR
void syncCDR()
Definition: wrudf-cdr.c:96
RV
RV
Definition: wrudf.h:60
virtualPartitionNum
uint16_t virtualPartitionNum
Definition: wrudf.c:63
fileEntry::fileLinkCount
uint16_t fileLinkCount
Definition: ecma_167.h:565
insertFileIdentDesc
int insertFileIdentDesc(Directory *dir, struct fileIdentDesc *fid)
Definition: wrudf-desc.c:211
fileEntry::accessTime
timestamp accessTime
Definition: ecma_167.h:571
FID_FILE_CHAR_DIRECTORY
#define FID_FILE_CHAR_DIRECTORY
Definition: ecma_167.h:475
deleteFID
int deleteFID(Directory *dir, struct fileIdentDesc *fid)
Definition: wrudf-desc.c:49
ICBTAG_FLAG_AD_SHORT
#define ICBTAG_FLAG_AD_SHORT
Definition: ecma_167.h:526
EXISTING_DIR
Definition: wrudf.h:61
lvid
struct logicalVolIntegrityDesc * lvid
Definition: wrudf.c:71
readExtents
int readExtents(char *dest, int usesShort, void *extents)
Definition: wrudf-cdrw.c:684
FE_PERM_U_CHATTR
#define FE_PERM_U_CHATTR
Definition: ecma_167.h:598
ICBTAG_FLAG_AD_LONG
#define ICBTAG_FLAG_AD_LONG
Definition: ecma_167.h:527
FE_PERM_O_READ
#define FE_PERM_O_READ
Definition: ecma_167.h:587
CMND_FAILED
Definition: wrudf.h:60
FE_PERM_G_READ
#define FE_PERM_G_READ
Definition: ecma_167.h:592
hdWorkingDir
char * hdWorkingDir
Definition: wrudf-cmnd.c:37
lscCommand
int lscCommand(void)
Definition: wrudf-cmnd.c:964
WRONG_NO_ARGS
Definition: wrudf.h:60
logicalVolIntegrityDesc::impUse
uint8_t impUse[0]
Definition: ecma_167.h:371
devicetype
int devicetype
Definition: wrudf.c:19
ICBTAG_FLAG_SETUID
#define ICBTAG_FLAG_SETUID
Definition: ecma_167.h:533
fileIdentDesc::fileCharacteristics
uint8_t fileCharacteristics
Definition: ecma_167.h:464
_dir_::fe
struct fileEntry fe
Definition: wrudf.h:94
EXISTING_FILE
Definition: wrudf.h:61
CDR
Definition: wrudf.h:40
fail
void fail(char *fmt,...)
Definition: ide-pc.c:43
fileIdentDesc::lengthOfImpUse
uint16_t lengthOfImpUse
Definition: ecma_167.h:467
rootDir
Directory * rootDir
Definition: wrudf.c:48
fileEntry
Definition: ecma_167.h:558
removeFID
int removeFID(Directory *dir, struct fileIdentDesc *fid)
Definition: wrudf-desc.c:31
cmndc
int cmndc
Definition: wrudf.c:32
questionOverwrite
int questionOverwrite(Directory *dir, struct fileIdentDesc *fid, char *name)
Definition: wrudf-cmnd.c:1086
makeFileEntry
struct fileEntry * makeFileEntry()
Definition: wrudf-desc.c:158
readLine
char * readLine(char *prompt)
Definition: wrudf.c:79
DIR_NOT_EMPTY
Definition: wrudf.h:62
copyDirectory
int copyDirectory(Directory *dir, char *name)
Definition: wrudf-cmnd.c:255
DELETED_FILE
Definition: wrudf.h:61
rv
static int rv
Definition: ide-pc.c:39
getExtents
int getExtents(uint32_t requestedLength, short_ad *extents)
Definition: wrudf-cdrw.c:98
fileEntry::informationLength
uint64_t informationLength
Definition: ecma_167.h:569
_dir_::dirDirty
uint32_t dirDirty
Definition: wrudf.h:93
allocDescImpUse
Definition: osta_udf.h:204
_dir_
Definition: wrudf.h:87
ICBTAG_FLAG_SETGID
#define ICBTAG_FLAG_SETGID
Definition: ecma_167.h:534
rmCommand
int rmCommand(void)
Definition: wrudf-cmnd.c:859
fileEntry::lengthAllocDescs
uint32_t lengthAllocDescs
Definition: ecma_167.h:579
CMND_OK
Definition: wrudf.h:60
DIR_INVALID
Definition: wrudf.h:61
fileEntry::descTag
tag descTag
Definition: ecma_167.h:560
cdhCommand
int cdhCommand()
Definition: wrudf-cmnd.c:1022
fileEntry::gid
uint32_t gid
Definition: ecma_167.h:563
CMND_ARG_INVALID
Definition: wrudf.h:60
fileIdentDesc::lengthFileIdent
uint8_t lengthFileIdent
Definition: ecma_167.h:465
cdcCommand
int cdcCommand()
Definition: wrudf-cmnd.c:948
FE_PERM_O_WRITE
#define FE_PERM_O_WRITE
Definition: ecma_167.h:586
FE_PERM_U_WRITE
#define FE_PERM_U_WRITE
Definition: ecma_167.h:596
fileEntry::modificationTime
timestamp modificationTime
Definition: ecma_167.h:572
writeBlock
void writeBlock(uint32_t lbn, uint16_t part, void *src)
Definition: wrudf-cdrw.c:625
FE_PERM_U_EXEC
#define FE_PERM_U_EXEC
Definition: ecma_167.h:595
fileEntry::uniqueID
uint64_t uniqueID
Definition: ecma_167.h:577
_dir_::icb
long_ad icb
Definition: wrudf.h:91
logicalVolIntegrityDesc::numOfPartitions
uint32_t numOfPartitions
Definition: ecma_167.h:367
FID_FILE_CHAR_DELETED
#define FID_FILE_CHAR_DELETED
Definition: ecma_167.h:476
updateTimestamp
void updateTimestamp(time_t t, uint32_t ut)
Definition: wrudf-cdrw.c:243
fileIdentDesc::descTag
tag descTag
Definition: ecma_167.h:462
ICBTAG_FLAG_AD_IN_ICB
#define ICBTAG_FLAG_AD_IN_ICB
Definition: ecma_167.h:529
curDir
Directory * curDir
Definition: wrudf.c:48
FE_PERM_O_DELETE
#define FE_PERM_O_DELETE
Definition: ecma_167.h:589
vat
uint32_t * vat
Definition: wrudf.c:64
DISK_IMAGE
#define DISK_IMAGE
Definition: wrudf.h:38
wrudf.h
findFileIdentDesc
struct fileIdentDesc * findFileIdentDesc(Directory *dir, char *name)
Definition: wrudf-desc.c:113
ICBTAG_FILE_TYPE_DIRECTORY
#define ICBTAG_FILE_TYPE_DIRECTORY
Definition: ecma_167.h:513
logicalVolIntegrityDescImpUse
Definition: osta_udf.h:94
_dir_::data
char * data
Definition: wrudf.h:90
writeExtents
int writeExtents(char *src, int usesShort, void *extents)
Definition: wrudf-cdrw.c:733
fileEntry::attrTime
timestamp attrTime
Definition: ecma_167.h:573
freeShortExtents
int freeShortExtents(short_ad *extents)
Definition: wrudf-cdrw.c:159
updateDirectory
int updateDirectory(Directory *dir)
Definition: wrudf-cmnd.c:453
fileIdentDesc::fileIdent
uint8_t fileIdent[0]
Definition: ecma_167.h:469
fileIdentDesc
Definition: ecma_167.h:460
pd
struct partitionDesc * pd
Definition: wrudf.c:62
readDirectory
Directory * readDirectory(Directory *parentDir, long_ad *icb, char *name)
Definition: wrudf-cmnd.c:383
getNWA
uint32_t getNWA()
Definition: wrudf-cdr.c:35
fileEntry::allocDescs
uint8_t allocDescs[0]
Definition: ecma_167.h:581
newVATentry
uint32_t newVATentry()
Definition: wrudf-cdr.c:22
copyFile
int copyFile(Directory *dir, char *inName, char *newName, struct stat *fileStat)
Definition: wrudf-cmnd.c:45
fileIdentDesc::icb
long_ad icb
Definition: ecma_167.h:466
ALLOC
Definition: wrudf.h:127
analyzeDest
enum RV analyzeDest(char *arg, struct fileIdentDesc **fid, char **name)
Definition: wrudf-cmnd.c:688
FE_PERM_O_EXEC
#define FE_PERM_O_EXEC
Definition: ecma_167.h:585
writeCDR
uint32_t writeCDR(void *src)
Definition: wrudf-cdr.c:121