udftools

- Main Page
- Classes
- Files

- File List
- File Members

All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
wrudf.c
Go to the documentation of this file.
1 /* wrudf.c
2 *
3 * Maintains a UDF filing system
4 *
5 */
6
7 #include "config.h"
8
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <unistd.h>
12 #include <string.h>
13 #include <sys/resource.h>
14
15 #include "wrudf.h"
16
17 char *devicename; /* "/dev/cdrom" or disk image filename */
18 int device; /* the file descriptor */
19 int devicetype;
20 enum MEDIUM medium;
21 int ignoreReadError; /* used while reading VRS which may be absent on open CDR */
22
23 #ifdef _GNU_SOURCE
24 char *line;
25 #define GETLINE(prompt) readLine(prompt);
26 #else
27 char line[256];
28 #define GETLINE(prompt) printf(prompt); fgets(line, 256, stdin); *strchr(line, '\n') = 0;
29 #endif
30
31
32 int cmndc;
33 int cmndvSize;
34 char** cmndv;
35
36 #define FOUND_BEA01 1
37 #define FOUND_NSR02 1<<1
38 #define FOUND_TEA01 1<<2
39 #define FOUND_PVD 1<<8
40 #define FOUND_LVD 1<<9
41 #define FOUND_PD 1<<10
42 #define FOUND_USD 1<<11
43 uint32_t found;
44
45 uint32_t options;
46
47
48 Directory *rootDir, *curDir;
49 timestamp timeStamp;
50 regid entityWRUDF = { 0, "-wrudf (" PACKAGE_VERSION ")", "\x04\x05"};
51
52 extent_ad extentMainVolDescSeq;
53 extent_ad extentRsrvVolDescSeq;
54 extent_ad extentNextVolDescSeq;
55 extent_ad extentLogVolIntegritySeq;
56 uint32_t integrityDescBlocknumber; /* where to write LVID when finished */
57 extent_ad extentLogVolIntegrityDesc; /* (continuation) extent for current LVIDs */
58
59 extern uint64_t CDRuniqueID; /* in wrudf-cdr.c ex VAT FE */
60
61
62 struct partitionDesc *pd; /* for the writable partition */
63 uint16_t virtualPartitionNum = 0xFFFF;
64 uint32_t *vat;
65 uint32_t newVATindex;
66 uint32_t maxVATindex;
67 uint32_t prevVATlbn;
68 struct logicalVolDesc *lvd;
69 struct unallocSpaceDesc *usd;
70 struct spaceBitmapDesc *spaceMap;
71 struct logicalVolIntegrityDesc *lvid;
72 struct fileSetDesc *fsd;
73 unsigned int usedSparingEntries;
74 struct sparingTable *st;
75
76 int spaceMapDirty, usdDirty, sparingTableDirty;
77
78
79 char* readLine(char* prompt) {
80 if( line ) {
81 free(line);
82 }
83 return line = readline(prompt);
84 }
85
86
87 void
88 initialise(char *devicename)
89 {
90 uint32_t i, len, blkno, lastblk, size;
91 long_ad *fsdAd;
92 short_ad *adSpaceMap;
93 struct sparablePartitionMap *spm;
94 char zeroes[5];
95 char fsdOut[91];
96 int fsdLen;
97 struct generic_desc *p;
98 struct volStructDesc *vsd;
99
100 initIO(devicename);
101 memset(zeroes, 0, 5);
102
103 /* read Volume Recognition Sequence */
104 ignoreReadError = 1;
105 for( blkno = 16; blkno < 256; blkno++ ) {
106 vsd = readSingleBlock(blkno);
107
108 if( vsd == NULL || memcmp(vsd->stdIdent, zeroes, 5) == 0 )
109 break;
110
111 if( strncmp((char *)vsd->stdIdent, "BEA01", VSD_STD_ID_LEN) == 0 ) {
112 found |= FOUND_BEA01;
113 continue;
114 }
115 if( strncmp((char *)vsd->stdIdent, "NSR02", VSD_STD_ID_LEN) == 0 ) {
116 found |= FOUND_NSR02;
117 continue;
118 }
119 if( strncmp((char *)vsd->stdIdent, "TEA01", 5) == 0 ) {
120 found |= FOUND_TEA01;
121 continue;
122 }
123 }
124 ignoreReadError = 0;
125
126 if( !(found & FOUND_BEA01) || !(found & FOUND_NSR02) || !(found & FOUND_TEA01) )
127 printf("No UDF VRS\n");
128
129 p = NULL;
130
131 if( medium == CDR ) {
132 p = readSingleBlock(512);
133 if( p == NULL || p->descTag.tagIdent != TAG_IDENT_AVDP )
134 fail("No AVDP at block 512 on CDR disc\n");
135 }
136
137 if( !p ) {
138 p = readTaggedBlock(256, ABSOLUTE);
139 if( p->descTag.tagIdent != TAG_IDENT_AVDP ) {
140 p = readTaggedBlock(trackSize - 1, ABSOLUTE);
141 if( p->descTag.tagIdent != TAG_IDENT_AVDP ) {
142 p = readTaggedBlock(trackSize - 256, ABSOLUTE);
143 if( p->descTag.tagIdent != TAG_IDENT_AVDP )
144 fail("No AVDP at block 256, N-256 or N-1 \n");
145 }
146 }
147 }
148
149 extentMainVolDescSeq = ((struct anchorVolDescPtr*)p)->mainVolDescSeqExt;
150 extentRsrvVolDescSeq = ((struct anchorVolDescPtr*)p)->reserveVolDescSeqExt;
151
152 /* read Volume Descriptor Sequence */
153 blkno = extentMainVolDescSeq.extLocation;
154 len = extentMainVolDescSeq.extLength;
155
156 for( i = 0; i < len; blkno++, i += 2048 ) {
157 int inMainSeq = 1;
158
159 if( (p = readTaggedBlock(blkno, ABSOLUTE)) == NULL ) {
160 if( !inMainSeq )
161 fail("Volume Descriptor Sequences read failure\n");
162 blkno = extentRsrvVolDescSeq.extLocation;
163 len = extentRsrvVolDescSeq.extLength;
164 inMainSeq = 0;
165 i = 0;
166 }
167 switch( p->descTag.tagIdent ) {
168 case TAG_IDENT_PVD:
169 found |= FOUND_PVD;
170 break;
171 case TAG_IDENT_VDP:
172 blkno = ((struct volDescPtr*)p)->nextVolDescSeqExt.extLocation - 1;
173 len = ((struct volDescPtr*)p)->nextVolDescSeqExt.extLength;
174 i = (uint32_t) -2048;
175 break;
176 case TAG_IDENT_IUVD:
177 break;
178 case TAG_IDENT_PD:
179 /* must have one (re)writable partition */
180 /* may have at most one RDONLY partition */
181 switch( ((struct partitionDesc *)p)->accessType ) {
182 case PD_ACCESS_TYPE_READ_ONLY:
183 break;
184 case PD_ACCESS_TYPE_REWRITABLE:
185 case PD_ACCESS_TYPE_WRITE_ONCE:
186 found |= FOUND_PD;
187 if( !pd )
188 pd = (struct partitionDesc*) calloc(512, 1);
189 if( p->volDescSeqNum > pd->volDescSeqNum )
190 memcpy(pd, p, 512);
191 break;
192 case PD_ACCESS_TYPE_OVERWRITABLE:
193 printf("Partition with overwritable accesstype is not supported\n");
194 break;
195 default:
196 printf("What to do with an accesstype %d partition?\n",
197 ((struct partitionDesc*)p)->accessType);
198 break;
199 }
200 break;
201 case TAG_IDENT_LVD:
202 found |= FOUND_LVD;
203 if( !lvd )
204 lvd = (struct logicalVolDesc*) calloc(512, 1);
205 if( p->volDescSeqNum > lvd->volDescSeqNum )
206 memcpy(lvd, p, 512);
207 break;
208 case TAG_IDENT_USD:
209 found |= FOUND_USD;
210 if( !usd )
211 usd = (struct unallocSpaceDesc*) calloc(512, 1);
212 if( p->volDescSeqNum > usd->volDescSeqNum )
213 memcpy(usd, p, 512);
214 break;
215 case TAG_IDENT_TD:
216 i = len;
217 break;
218 default:
219 printf("Unexpected tag ID %04X\n in Volume Descriptor Sequence block %d", p->descTag.tagIdent, blkno);
220 }
221 }
222
223 if( (found & FOUND_LVD) == 0 )
224 fail("No LVD found \n");
225
226 if( (found & FOUND_PD) == 0 )
227 fail("No PD found\n");
228
229 if( lvd->logicalBlockSize != 2048 )
230 fail("Blocksize not 2048\n");
231
232 spm = (struct sparablePartitionMap*)lvd->partitionMaps;
233 for( i = 0; i < lvd->numPartitionMaps; i++ ) {
234 if( spm->partitionMapType == 2 ) {
235
236 if( strncmp((char *)spm->partIdent.ident, UDF_ID_SPARABLE, strlen(UDF_ID_SPARABLE)) == 0 ) {
237 unsigned int j;
238
239 if( spm->sizeSparingTable > 2048 )
240 fail("Cannot handle SparingTable > 2048 bytes");
241 st = (struct sparingTable*)malloc(2048);
242 p = readTaggedBlock(spm->locSparingTable[0], ABSOLUTE);
243 memcpy(st, p, spm->sizeSparingTable);
244
245 /* if #1 fails, try #2; should pick copy with highest sequenceNum */
246
247 for( j = usedSparingEntries = 0; j < (spm->sizeSparingTable >> 3); j++ ) {
248 if( st->mapEntry[j].origLocation < 0xFFFFFFF0 )
249 usedSparingEntries++;
250 }
251 } else if( strncmp((char *)spm->partIdent.ident, UDF_ID_VIRTUAL, strlen(UDF_ID_VIRTUAL)) == 0 )
252 virtualPartitionNum = i;
253 }
254 spm = (struct sparablePartitionMap*)((char*)spm + spm->partitionMapLength);
255 }
256
257 if( medium == CDR ) {
258 if( virtualPartitionNum != 0xFFFF )
259 readVATtable();
260 else
261 fail("No Virtual Partition Map on CDR\n");
262 }
263
264 if( medium != CDR && (found & FOUND_USD) == 0 )
265 fail("Did not find Unallocated Space Descriptor\n");
266
267 /* Read Fileset Descriptor Sequence */
268 fsdAd = (long_ad*) lvd->logicalVolContentsUse;
269 for( i = 0; i < (fsdAd->extLength >> 11); i++ ) {
270 blkno = pd->partitionStartingLocation + fsdAd->extLocation.logicalBlockNum + i;
271 if( !(p = readTaggedBlock(blkno, ABSOLUTE)) )
272 exit(1);
273 switch( p->descTag.tagIdent ) {
274 case TAG_IDENT_TD:
275 i = fsdAd->extLength;
276 break;
277 case TAG_IDENT_FSD:
278 if( fsd && (lvd->volDescSeqNum > p->volDescSeqNum) )
279 break;
280 fsd = (struct fileSetDesc*)malloc(512);
281 memcpy(fsd, p, 512);
282 break;
283 default:
284 printf("Unxpected tag id %d, where File Set Desc(256) expected\n", p->descTag.tagIdent);
285 }
286 }
287
288 if( !fsd )
289 fail("No File Set Descriptor\n");
290
291 /* load Spacemap extent */
292 adSpaceMap = (short_ad*) &((struct partitionHeaderDesc*)pd->partitionContentsUse)->unallocSpaceBitmap;
293
294 if( adSpaceMap->extLength != 0 ) {
295 blkno = adSpaceMap->extPosition;
296 len = adSpaceMap->extLength;
297 spaceMap = (struct spaceBitmapDesc*) malloc((len + 2047) & ~2047);
298
299 for( i = 0; i < len; i += 2048 ) {
300 p = readBlock(blkno, 0);
301 memcpy( (uint8_t*)spaceMap + i, (uint8_t*) p, 2048);
302 freeBlock(blkno++, 0);
303 }
304
305 if( spaceMap->descTag.tagIdent != TAG_IDENT_SBD )
306 fail("SpaceBitmap not found\n");
307 }
308
309 if ((fsdLen = decode_utf8(fsd->fileSetIdent, fsdOut, fsd->fileSetIdent[31]))>=0)
310 fsdOut[fsdLen] = '\0';
311
312 printf("You are going to update fileset '%s'\nProceed (y/N) : ", fsdOut);
313 readLine(NULL);
314
315 if( !line || line[0] != 'y' )
316 fail("wrudf terminated\n");
317
318 /* Read Logical Volume Integrity sequence */
319 blkno = lvd->integritySeqExt.extLocation;
320 lastblk = blkno + (lvd->integritySeqExt.extLength >> 11);
321 extentLogVolIntegrityDesc = lvd->integritySeqExt;
322
323 for( ; blkno < lastblk; blkno++ ) {
324 if( !(p = readTaggedBlock(blkno, ABSOLUTE)) )
325 fail("Read failure in Integrity Sequence, blk %d\n", blkno);
326
327 switch( p->descTag.tagIdent ) {
328 case TAG_IDENT_TD:
329 blkno = lastblk;
330 break;
331 case TAG_IDENT_LVID:
332 size = sizeof(struct logicalVolIntegrityDesc) + sizeof(struct logicalVolIntegrityDescImpUse)
333 + 2 * sizeof(uint32_t) * ((struct logicalVolIntegrityDesc*)p)->numOfPartitions;
334 if( !lvid )
335 lvid = (struct logicalVolIntegrityDesc*) malloc(size);
336 integrityDescBlocknumber = blkno;
337 memcpy(lvid, p, size);
338
339 if( lvid->nextIntegrityExt.extLocation ) {
340 extentLogVolIntegrityDesc = lvid->nextIntegrityExt;
341 blkno = lvid->nextIntegrityExt.extLocation;
342 lastblk = blkno + (lvid->nextIntegrityExt.extLength >> 11);
343 blkno--; /* incremented again in for statement */
344 }
345 break;
346 default:
347 printf("Unxpected tag %X in Integrity Sequence; blk %d\n", p->descTag.tagIdent, blkno);
348 blkno = lastblk;
349 break;
350 }
351 }
352
353 if( !lvid || lvid->descTag.tagIdent != TAG_IDENT_LVID )
354 fail("No Logical Volume Integrity Descriptor\n");
355
356 if( medium == CDR && lvid->integrityType == LVID_INTEGRITY_TYPE_CLOSE )
357 fail("CDR volume has been closed\n");
358
359 if( medium == CDR )
360 // take from VAT FileEntry
361 ((struct logicalVolHeaderDesc*)lvid->logicalVolContentsUse)->uniqueID = CDRuniqueID;
362
363 curDir = rootDir = (Directory*)malloc(sizeof(Directory));
364 memset(rootDir, 0, sizeof(Directory));
365 rootDir->dataSize = 4096;
366 rootDir->data = malloc(4096);
367 rootDir->name = "";
368 readDirectory( NULL, &fsd->rootDirectoryICB, "");
369
370 if( medium == CDR )
371 return;
372
373 if( lvid->integrityType == LVID_INTEGRITY_TYPE_OPEN ) {
374 GETLINE("** Volume was not closed; do you wish to proceed (y/N) : ");
375 if( (line[0] | 0x20) != 'y' )
376 exit(0);
377 }
378
379 /* If prevailing LVID is in one before last block of extent
380 * then next LVID will be in last and must contain continuation extent */
381
382 if( integrityDescBlocknumber + 2 ==
383 extentLogVolIntegrityDesc.extLocation + (extentLogVolIntegrityDesc.extLength >> 11) )
384 {
385 getUnallocSpaceExtent( 32 * 2048, extentLogVolIntegrityDesc.extLocation, &lvid->nextIntegrityExt);
386 if( lvid->nextIntegrityExt.extLength == 0 ) {
387 printf("No more unallocated space for Integrity Sequence\n");
388 }
389 } else {
390 lvid->nextIntegrityExt.extLength = 0;
391 lvid->nextIntegrityExt.extLocation = 0;
392 }
393
394 integrityDescBlocknumber++;
395
396 updateTimestamp(0,0);
397 memcpy(lvid->impUse + 2 * sizeof(uint32_t) * lvid->numOfPartitions, &entityWRUDF, sizeof(regid));
398 lvid->recordingDateAndTime = timeStamp;
399 lvid->integrityType = LVID_INTEGRITY_TYPE_OPEN;
400 lvid->descTag.tagLocation = integrityDescBlocknumber;
401
402 size = sizeof(struct logicalVolIntegrityDesc) + sizeof(struct logicalVolIntegrityDescImpUse)
403 + 2 * sizeof(uint32_t) * lvid->numOfPartitions;
404
405 lvid->descTag.descCRCLength = size - sizeof(tag);
406 setChecksum(lvid);
407
408 p = readTaggedBlock(integrityDescBlocknumber, ABSOLUTE);
409 memcpy( p, lvid, size);
410 dirtyBlock(integrityDescBlocknumber, ABSOLUTE); /* not written because of buffering : Force unit access? */
411
412 }
413
414
415 int
416 finalise(void)
417 {
418 int i, lbn, len, size, blkno ;
419 struct generic_desc *p;
420 short_ad *adSpaceMap;
421
422 updateDirectory(rootDir); /* and any dirty children */
423
424 if( medium == CDR ) {
425 writeVATtable();
426 } else {
427 /* rewrite Space Bitmap */
428 if( spaceMapDirty) {
429 adSpaceMap = (short_ad*) &((struct partitionHeaderDesc*)pd->partitionContentsUse)->unallocSpaceBitmap;
430 lbn = adSpaceMap->extPosition;
431 len = adSpaceMap->extLength;
432
433 for( i = 0; i < len; i += 2048 ) {
434 p = readBlock(lbn, 0);
435 memcpy( p, (uint8_t*)spaceMap + i, 2048);
436 dirtyBlock(lbn, 0);
437 freeBlock(lbn++, 0);
438 }
439 }
440
441 if( sparingTableDirty )
442 updateSparingTable();
443
444 /* write closed Logical Volume Integrity Descriptor */
445 lvid->integrityType = LVID_INTEGRITY_TYPE_CLOSE;
446 updateTimestamp(0,0);
447 lvid->recordingDateAndTime = timeStamp;
448 lvid->descTag.tagLocation = integrityDescBlocknumber;
449 size = sizeof(struct logicalVolIntegrityDesc) + sizeof(struct logicalVolIntegrityDescImpUse)
450 + 2 * sizeof(uint32_t) * lvid->numOfPartitions;
451 lvid->descTag.descCRCLength = size - sizeof(tag);
452 setChecksum(lvid);
453 p = readBlock(integrityDescBlocknumber, ABSOLUTE);
454 memcpy(p, lvid, size);
455 dirtyBlock(integrityDescBlocknumber, ABSOLUTE);
456 freeBlock(integrityDescBlocknumber, ABSOLUTE);
457
458 /* terminating descriptor */
459 blkno = lvid->nextIntegrityExt.extLocation;
460 if( !blkno )
461 blkno = integrityDescBlocknumber + 1;
462
463 p = readBlock(blkno, ABSOLUTE);
464 memset(p, 0, 2048);
465 p->descTag.tagLocation = blkno;
466 p->descTag.tagSerialNum = lvid->descTag.tagSerialNum;
467 p->descTag.tagIdent = TAG_IDENT_TD;
468 p->descTag.descCRCLength = 512 - sizeof(tag);
469 setChecksum(p);
470 dirtyBlock(blkno, ABSOLUTE);
471 freeBlock(blkno, ABSOLUTE);
472
473 if( usdDirty ) {
474 size = sizeof(struct unallocSpaceDesc) + usd->numAllocDescs * sizeof(extent_ad);
475 usd->descTag.descCRCLength = size - sizeof(tag);
476 setChecksum(usd);
477 p = readBlock(usd->descTag.tagLocation, ABSOLUTE);
478 memcpy(p, usd, size);
479 dirtyBlock(usd->descTag.tagLocation, ABSOLUTE);
480 freeBlock(usd->descTag.tagLocation, ABSOLUTE);
481
482 /* now rewrite in Reserve Sequence which must be exact copy of Main Sequence */
483 usd->descTag.tagLocation +=
484 extentRsrvVolDescSeq.extLocation - extentMainVolDescSeq.extLocation;
485 setChecksum(usd);
486 p = readBlock(usd->descTag.tagLocation, ABSOLUTE);
487 memcpy(p, usd, size);
488 dirtyBlock(usd->descTag.tagLocation, ABSOLUTE);
489 freeBlock(usd->descTag.tagLocation, ABSOLUTE);
490 }
491 } // end not CDR
492
493 closeIO(); /* clears packet buffers; closes device */
494
495 /* free allocated space */
496 if(pd) free(pd);
497 if(lvd) free(lvd);
498 if(fsd) free(fsd);
499 if(usd) free (usd);
500 if(spaceMap) free(spaceMap);
501 if(lvid) free(lvid);
502 if(st) free(st);
503 if(vat) free(vat);
504 return 0;
505 }
506
507 int
508 parseCmnd(char* line)
509 {
510 char *p, *q, next, term;
511 int i, j;
512 int cmnd;
513
514 if( !cmndvSize ) {
515 cmndvSize = 64;
516 cmndv = malloc(cmndvSize * sizeof(char*));
517 }
518
519 if( !line || line[0] == 0 )
520 return CMND_FAILED;
521
522 cmndc = 0;
523 for( p = line; *p == ' '; p++ ) ;
524 for( q = p; *q && (*q != ' '); q++ ) ;
525 next = *q;
526 *q = 0;
527
528 if( !strcmp(p, "cd") || !strcmp(p, "ls") ) {
529 printf("Specify cdh/lsh or cdc/lsc for Harddisk or CompactDisc\n");
530 return CMND_FAILED;
531 }
532
533 if( !strcmp(p, "cp") ) cmnd = CMND_CP;
534 else if( !strcmp(p, "rm") ) cmnd = CMND_RM;
535 else if( !strcmp(p, "mkdir") ) cmnd = CMND_MKDIR;
536 else if( !strcmp(p, "rmdir") ) cmnd = CMND_RMDIR;
537 else if( !strcmp(p, "lsc") ) cmnd = CMND_LSC;
538 else if( !strcmp(p, "lsh") ) cmnd = CMND_LSH;
539 else if( !strcmp(p, "cdc") ) cmnd = CMND_CDC;
540 else if( !strcmp(p, "cdh") ) cmnd = CMND_CDH;
541 else if( !strcmp(p, "quit") ) cmnd = CMND_QUIT;
542 else if( !strcmp(p, "exit") ) cmnd = CMND_QUIT;
543 else if( !strcmp(p, "help") ) {
544 printf(
545 "Available commands:\n"
546 "\tcp\n"
547 "\trm\n"
548 "\tmkdir\n"
549 "\trmdir\n"
550 "\tlsc\n"
551 "\tlsh\n"
552 "\tcdc\n"
553 "\tcdh\n"
554 "Specify cdh/lsh or cdc/lsc to do cd or ls for Harddisk or CompactDisc.\n"
555 "\tquit\n"
556 "\texit\n"
557 );
558 return CMND_FAILED;
559 } else {
560 printf("Invalid command\n");
561 return CMND_FAILED;
562 }
563
564 while( next != 0 ) {
565 if( cmndc == cmndvSize ) {
566 cmndvSize += 32;
567 cmndv = realloc(cmndv, cmndvSize);
568 if( !cmndv )
569 fail("cmndv reallocation failed\n");
570 }
571 p = q + 1;
572 while( *p == ' ') p++;
573 if( *p == 0 )
574 break;
575 if( *p == '"' ) {
576 term = '"'; q = p+1;
577 } else {
578 term = ' '; q = p;
579 }
580 while( *q && *q != term ) q++;
581
582 next = *q;
583 if( *p == '"' ) {
584 if( *q == 0 )
585 return CMND_ARG_INVALID;
586 cmndv[cmndc++] = p+1;
587 *(q-1) = 0;
588 } else {
589 cmndv[cmndc++] = p;
590 *q = 0;
591 }
592 }
593
594 options = 0;
595 for( i = 0; i < cmndc; i ++ ) {
596 if( cmndv[i][0] == '-' ) {
597 for( j = 1; cmndv[i][j]; j++ ) {
598 switch( cmndv[i][j] ) {
599 case 'f':
600 options |= OPT_FORCE;
601 break;
602 case 'r':
603 options |= OPT_RECURSIVE;
604 break;
605 default:
606 return CMND_ARG_INVALID;
607 }
608 }
609 cmndv[i] = NULL;
610 }
611 }
612
613 for( i = j = 0; i < cmndc; i++ ) {
614 if( i != j )
615 cmndv[j] = cmndv[i];
616 if( cmndv[j] != NULL )
617 j++;
618 }
619
620 cmndc = j;
621
622 /* could check whether options valid for command */
623
624 return cmnd;
625 }
626
627 int show_help()
628 {
629 char *msg =
630 "Interactive tool to maintain an UDF filesystem.\n"
631 "Usage:\n"
632 "\twrudf [device]\n"
633 "Available commands:\n"
634 "\tcp\n"
635 "\trm\n"
636 "\tmkdir\n"
637 "\trmdir\n"
638 "\tlsc\n"
639 "\tlsh\n"
640 "\tcdc\n"
641 "\tcdh\n"
642 "Specify cdh/lsh or cdc/lsc to do cd or ls for Harddisk or CompactDisc.\n"
643 "\tquit\n"
644 "\texit\n";
645 printf("%s", msg);
646 return 0;
647 }
648
649 int
650 main(int argc, char** argv)
651 {
652 int rv=0;
653 int cmnd;
654 char prompt[256];
655 char *ptr;
656 size_t len;
657 Directory *d;
658
659 printf("wrudf from " PACKAGE_NAME " " PACKAGE_VERSION "\n");
660 devicename= "/dev/cdrom";
661
662 if( argc > 2 || (argc == 2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "-help") || !strcmp(argv[1], "--help"))) )
663 return show_help();
664 else if( argc == 2 )
665 devicename = argv[1]; /* can specify disk image filename */
666
667 if( setpriority(PRIO_PROCESS, 0, -10) ) {
668 printf("setpriority(): %m\n");
669 }
670
671 hdWorkingDir = getcwd(NULL, 0);
672 initialise(devicename);
673
674 for(;;) {
675 d = rootDir;
676 prompt[0] = 0;
677 ptr = prompt;
678 while( curDir != d ) {
679 len = strlen(d->name);
680 if( ptr + len + 1 >= prompt + sizeof(prompt) - 7 )
681 break;
682 memcpy(ptr, d->name, len);
683 ptr[len] = '/';
684 ptr += len + 1;
685 d = d->child;
686 }
687 len = strlen(d->name);
688 if( ptr + len + 1 >= prompt + sizeof(prompt) - 7 ) {
689 memcpy(ptr, "...", 3);
690 ptr += 3;
691 } else if( d->name[0] == 0 ) {
692 *(ptr++) = '/';
693 } else {
694 memcpy(ptr, d->name, len);
695 ptr += len;
696 }
697
698 memcpy(ptr, " > ", 4);
699
700 GETLINE(prompt);
701
702 cmnd = parseCmnd(line);
703
704 if( cmnd == CMND_FAILED )
705 continue;
706
707 if( cmnd == CMND_QUIT )
708 break;
709
710 switch( cmnd ) {
711 case CMND_CP:
712 rv = cpCommand();
713 break;
714 case CMND_RM:
715 rv = rmCommand();
716 break;
717 case CMND_MKDIR:
718 rv = mkdirCommand();
719 break;
720 case CMND_RMDIR:
721 rv = rmdirCommand();
722 break;
723 case CMND_LSC:
724 rv = lscCommand();
725 break;
726 case CMND_LSH:
727 rv = lshCommand();
728 break;
729 case CMND_CDC:
730 rv = cdcCommand();
731 break;
732 case CMND_CDH:
733 rv = cdhCommand();
734 break;
735 }
736
737 switch( rv ) {
738 case CMND_OK:
739 break;
740 case CMND_FAILED:
741 printf("Failed\n");
742 break;
743 case WRONG_NO_ARGS:
744 printf("Incorrect number of arguments\n");
745 break;
746 case CMND_ARG_INVALID:
747 printf("Invalid argument\n");
748 break;
749 case NOT_IN_RW_PARTITION:
750 printf("Not in RW partition\n");
751 break;
752 case DIR_INVALID:
753 printf("Invalid directory\n");
754 break;
755 case DIR_NOT_EMPTY:
756 printf("Directory not empty\n");
757 break;
758 case EXISTING_DIR:
759 printf("Dir already exists\n");
760 break;
761 case DOES_NOT_EXIST:
762 printf("File/directory does not exist\n");
763 break;
764 case PERMISSION_DENIED:
765 printf("Permission denied\n");
766 break;
767 case IS_DIRECTORY:
768 printf("Is a directory\n");
769 break;
770 default:
771 printf("Unknown return value %d\n", rv);
772 }
773 }
774 free(hdWorkingDir);
775 return finalise();
776 }
timeStamp
timestamp timeStamp
Definition: wrudf.c:49
device
int device
Definition: wrudf.c:18
setChecksum
void setChecksum(void *descriptor)
Definition: wrudf-cdrw.c:229
closeIO
int closeIO(void)
Definition: wrudf-cdrw.c:927
NOT_IN_RW_PARTITION
Definition: wrudf.h:60
PD_ACCESS_TYPE_REWRITABLE
#define PD_ACCESS_TYPE_REWRITABLE
Definition: ecma_167.h:292
TAG_IDENT_PVD
#define TAG_IDENT_PVD
Definition: ecma_167.h:182
fileSetDesc::rootDirectoryICB
long_ad rootDirectoryICB
Definition: ecma_167.h:441
options
uint32_t options
Definition: wrudf.c:45
extentNextVolDescSeq
extent_ad extentNextVolDescSeq
Definition: wrudf.c:54
partitionDesc::partitionContentsUse
uint8_t partitionContentsUse[128]
Definition: ecma_167.h:267
logicalVolDesc::integritySeqExt
extent_ad integritySeqExt
Definition: ecma_167.h:309
DOES_NOT_EXIST
Definition: wrudf.h:61
line
char line[256]
Definition: wrudf.c:27
readTaggedBlock
void * readTaggedBlock(uint32_t lbn, uint16_t partition)
Definition: wrudf-cdrw.c:639
_dir_::dataSize
uint32_t dataSize
Definition: wrudf.h:89
parseCmnd
int parseCmnd(char *line)
Definition: wrudf.c:508
sparingTable::mapEntry
struct sparingEntry mapEntry[0]
Definition: osta_udf.h:199
logicalVolDesc::logicalBlockSize
uint32_t logicalBlockSize
Definition: ecma_167.h:302
maxVATindex
uint32_t maxVATindex
Definition: wrudf.c:66
sparingTable
Definition: osta_udf.h:192
OPT_RECURSIVE
#define OPT_RECURSIVE
Definition: wrudf.h:72
readSingleBlock
void * readSingleBlock(uint32_t pbn)
Definition: wrudf-cdrw.c:564
extentRsrvVolDescSeq
extent_ad extentRsrvVolDescSeq
Definition: wrudf.c:53
extentLogVolIntegrityDesc
extent_ad extentLogVolIntegrityDesc
Definition: wrudf.c:57
logicalVolDesc::volDescSeqNum
uint32_t volDescSeqNum
Definition: ecma_167.h:299
LVID_INTEGRITY_TYPE_OPEN
#define LVID_INTEGRITY_TYPE_OPEN
Definition: ecma_167.h:375
sparablePartitionMap::sizeSparingTable
uint32_t sizeSparingTable
Definition: osta_udf.h:152
logicalVolIntegrityDesc::logicalVolContentsUse
uint8_t logicalVolContentsUse[32]
Definition: ecma_167.h:366
sparablePartitionMap::locSparingTable
uint32_t locSparingTable[4]
Definition: osta_udf.h:153
updateSparingTable
void updateSparingTable()
Definition: wrudf-cdrw.c:371
FOUND_LVD
#define FOUND_LVD
Definition: wrudf.c:40
fsd
struct fileSetDesc * fsd
Definition: wrudf.c:72
partitionDesc::volDescSeqNum
uint32_t volDescSeqNum
Definition: ecma_167.h:263
unallocSpaceDesc::descTag
tag descTag
Definition: ecma_167.h:346
fileSetDesc::fileSetIdent
dstring fileSetIdent[32]
Definition: ecma_167.h:438
VSD_STD_ID_LEN
#define VSD_STD_ID_LEN
Definition: ecma_167.h:100
lshCommand
int lshCommand()
Definition: wrudf-cmnd.c:1039
anchorVolDescPtr
Definition: ecma_167.h:233
ignoreReadError
int ignoreReadError
Definition: wrudf.c:21
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
extentLogVolIntegritySeq
extent_ad extentLogVolIntegritySeq
Definition: wrudf.c:55
finalise
int finalise(void)
Definition: wrudf.c:416
spaceMapDirty
int spaceMapDirty
Definition: wrudf.c:76
rmdirCommand
int rmdirCommand(void)
Definition: wrudf-cmnd.c:924
sparablePartitionMap
Definition: osta_udf.h:141
writeVATtable
void writeVATtable()
Definition: wrudf-cdr.c:309
PD_ACCESS_TYPE_WRITE_ONCE
#define PD_ACCESS_TYPE_WRITE_ONCE
Definition: ecma_167.h:291
integrityDescBlocknumber
uint32_t integrityDescBlocknumber
Definition: wrudf.c:56
TAG_IDENT_TD
#define TAG_IDENT_TD
Definition: ecma_167.h:189
_dir_::name
char * name
Definition: wrudf.h:92
prompt
int prompt(const char *format,...)
Simple prompt printing out message and accepting y/Y/n/N. Anything else restarts prompt.
Definition: utils.c:184
main
int main(int argc, char **argv)
Definition: wrudf.c:650
decode_utf8
size_t decode_utf8(dstring *, char *, size_t)
Definition: unicode.c:32
mkdirCommand
int mkdirCommand(void)
Definition: wrudf-cmnd.c:891
FOUND_PVD
#define FOUND_PVD
Definition: wrudf.c:39
CMND_LSC
Definition: wrudf.h:64
generic_desc
Definition: wrudf.h:28
cpCommand
int cpCommand(void)
Definition: wrudf-cmnd.c:763
spaceBitmapDesc::descTag
tag descTag
Definition: ecma_167.h:751
_dir_::child
struct _dir_ * child
Definition: wrudf.h:88
MEDIUM
MEDIUM
Definition: wrudf.h:40
accessType
uint32_t accessType
Definition: ecma_167.h:70
unallocSpaceBitmap
short_ad unallocSpaceBitmap
Definition: ecma_167.h:65
TAG_IDENT_SBD
#define TAG_IDENT_SBD
Definition: ecma_167.h:420
sparablePartitionMap::partitionMapLength
uint8_t partitionMapLength
Definition: osta_udf.h:144
virtualPartitionNum
uint16_t virtualPartitionNum
Definition: wrudf.c:63
devicename
char * devicename
Definition: wrudf.c:17
readBlock
void * readBlock(uint32_t lbn, uint16_t part)
Definition: wrudf-cdrw.c:543
freeBlock
void freeBlock(uint32_t lbn, uint16_t part)
Definition: wrudf-cdrw.c:592
getUnallocSpaceExtent
void getUnallocSpaceExtent(uint32_t requestLength, uint32_t requestAfter, extent_ad *alloc)
Definition: wrudf-cdrw.c:198
TAG_IDENT_IUVD
#define TAG_IDENT_IUVD
Definition: ecma_167.h:185
TAG_IDENT_VDP
#define TAG_IDENT_VDP
Definition: ecma_167.h:184
found
uint32_t found
Definition: wrudf.c:43
TAG_IDENT_PD
#define TAG_IDENT_PD
Definition: ecma_167.h:186
logicalVolDesc
Definition: ecma_167.h:296
CMND_CDC
Definition: wrudf.h:64
partitionHeaderDesc
Definition: ecma_167.h:449
EXISTING_DIR
Definition: wrudf.h:61
lvid
struct logicalVolIntegrityDesc * lvid
Definition: wrudf.c:71
numOfPartitions
uint32_t numOfPartitions
Definition: ecma_167.h:69
volStructDesc::stdIdent
uint8_t stdIdent[VSD_STD_ID_LEN]
Definition: ecma_167.h:104
CMND_FAILED
Definition: wrudf.h:60
dirtyBlock
void dirtyBlock(uint32_t lbn, uint16_t part)
Definition: wrudf-cdrw.c:610
generic_desc::descTag
tag descTag
Definition: wrudf.h:30
TAG_IDENT_FSD
#define TAG_IDENT_FSD
Definition: ecma_167.h:412
hdWorkingDir
char * hdWorkingDir
Definition: wrudf-cmnd.c:37
lscCommand
int lscCommand(void)
Definition: wrudf-cmnd.c:964
WRONG_NO_ARGS
Definition: wrudf.h:60
FOUND_NSR02
#define FOUND_NSR02
Definition: wrudf.c:37
logicalVolIntegrityDesc::nextIntegrityExt
extent_ad nextIntegrityExt
Definition: ecma_167.h:365
logicalVolIntegrityDesc::impUse
uint8_t impUse[0]
Definition: ecma_167.h:371
devicetype
int devicetype
Definition: wrudf.c:19
volDescPtr
Definition: ecma_167.h:242
extentMainVolDescSeq
extent_ad extentMainVolDescSeq
Definition: wrudf.c:52
TAG_IDENT_LVD
#define TAG_IDENT_LVD
Definition: ecma_167.h:187
usdDirty
int usdDirty
Definition: wrudf.c:76
CDR
Definition: wrudf.h:40
ABSOLUTE
#define ABSOLUTE
Definition: wrudf.h:146
fail
void fail(char *fmt,...)
Definition: ide-pc.c:43
usd
struct unallocSpaceDesc * usd
Definition: wrudf.c:69
rootDir
Directory * rootDir
Definition: wrudf.c:48
cmndc
int cmndc
Definition: wrudf.c:32
fileSetDesc
Definition: ecma_167.h:425
CDRuniqueID
uint64_t CDRuniqueID
Definition: wrudf-cdr.c:19
PD_ACCESS_TYPE_OVERWRITABLE
#define PD_ACCESS_TYPE_OVERWRITABLE
Definition: ecma_167.h:293
readLine
char * readLine(char *prompt)
Definition: wrudf.c:79
DIR_NOT_EMPTY
Definition: wrudf.h:62
TAG_IDENT_LVID
#define TAG_IDENT_LVID
Definition: ecma_167.h:190
rv
static int rv
Definition: ide-pc.c:39
FOUND_USD
#define FOUND_USD
Definition: wrudf.c:42
OPT_FORCE
#define OPT_FORCE
Definition: wrudf.h:71
logicalVolIntegrityDesc::descTag
tag descTag
Definition: ecma_167.h:362
sparingTableDirty
int sparingTableDirty
Definition: wrudf.c:76
FOUND_BEA01
#define FOUND_BEA01
Definition: wrudf.c:36
msg
void msg(const char *format,...)
Message output.
Definition: utils.c:344
FOUND_PD
#define FOUND_PD
Definition: wrudf.c:41
logicalVolHeaderDesc
Definition: ecma_167.h:782
_dir_
Definition: wrudf.h:87
PERMISSION_DENIED
Definition: wrudf.h:62
rmCommand
int rmCommand(void)
Definition: wrudf-cmnd.c:859
UDF_ID_SPARABLE
#define UDF_ID_SPARABLE
Definition: osta_udf.h:64
CMND_OK
Definition: wrudf.h:60
DIR_INVALID
Definition: wrudf.h:61
st
struct sparingTable * st
Definition: wrudf.c:74
PD_ACCESS_TYPE_READ_ONLY
#define PD_ACCESS_TYPE_READ_ONLY
Definition: ecma_167.h:290
prevVATlbn
uint32_t prevVATlbn
Definition: wrudf.c:67
spaceMap
struct spaceBitmapDesc * spaceMap
Definition: wrudf.c:70
entityWRUDF
regid entityWRUDF
Definition: wrudf.c:50
cdhCommand
int cdhCommand()
Definition: wrudf-cmnd.c:1022
FOUND_TEA01
#define FOUND_TEA01
Definition: wrudf.c:38
CMND_ARG_INVALID
Definition: wrudf.h:60
newVATindex
uint32_t newVATindex
Definition: wrudf.c:65
cdcCommand
int cdcCommand()
Definition: wrudf-cmnd.c:948
logicalVolIntegrityDesc
Definition: ecma_167.h:360
CMND_RMDIR
Definition: wrudf.h:64
CMND_CP
Definition: wrudf.h:64
volStructDesc
Definition: ecma_167.h:101
CMND_RM
Definition: wrudf.h:64
generic_desc::volDescSeqNum
uint32_t volDescSeqNum
Definition: wrudf.h:31
initialise
void initialise(char *devicename)
Definition: wrudf.c:88
logicalVolIntegrityDesc::recordingDateAndTime
timestamp recordingDateAndTime
Definition: ecma_167.h:363
logicalVolIntegrityDesc::numOfPartitions
uint32_t numOfPartitions
Definition: ecma_167.h:367
CMND_CDH
Definition: wrudf.h:64
logicalVolDesc::partitionMaps
uint8_t partitionMaps[0]
Definition: ecma_167.h:310
CMND_MKDIR
Definition: wrudf.h:64
updateTimestamp
void updateTimestamp(time_t t, uint32_t ut)
Definition: wrudf-cdrw.c:243
cmndvSize
int cmndvSize
Definition: wrudf.c:33
curDir
Directory * curDir
Definition: wrudf.c:48
IS_DIRECTORY
Definition: wrudf.h:62
unallocSpaceDesc::volDescSeqNum
uint32_t volDescSeqNum
Definition: ecma_167.h:347
initIO
int initIO(char *filename)
Definition: wrudf-cdrw.c:779
vat
uint32_t * vat
Definition: wrudf.c:64
CMND_LSH
Definition: wrudf.h:64
logicalVolIntegrityDesc::integrityType
uint32_t integrityType
Definition: ecma_167.h:364
wrudf.h
trackSize
uint32_t trackSize
Definition: wrudf-cdrw.c:62
sparablePartitionMap::partIdent
regid partIdent
Definition: osta_udf.h:146
GETLINE
#define GETLINE(prompt)
Definition: wrudf.c:28
_dir_::data
char * data
Definition: wrudf.h:90
UDF_ID_VIRTUAL
#define UDF_ID_VIRTUAL
Definition: osta_udf.h:63
lvd
struct logicalVolDesc * lvd
Definition: wrudf.c:68
unallocSpaceDesc
Definition: ecma_167.h:344
CMND_QUIT
Definition: wrudf.h:64
logicalVolDesc::logicalVolContentsUse
uint8_t logicalVolContentsUse[16]
Definition: ecma_167.h:304
sparablePartitionMap::partitionMapType
uint8_t partitionMapType
Definition: osta_udf.h:143
updateDirectory
int updateDirectory(Directory *dir)
Definition: wrudf-cmnd.c:453
sparingEntry::origLocation
uint32_t origLocation
Definition: osta_udf.h:188
partitionDesc
Definition: ecma_167.h:260
readVATtable
void readVATtable()
Definition: wrudf-cdr.c:283
show_help
int show_help()
Definition: wrudf.c:627
pd
struct partitionDesc * pd
Definition: wrudf.c:62
readDirectory
Directory * readDirectory(Directory *parentDir, long_ad *icb, char *name)
Definition: wrudf-cmnd.c:383
spaceBitmapDesc
Definition: ecma_167.h:749
LVID_INTEGRITY_TYPE_CLOSE
#define LVID_INTEGRITY_TYPE_CLOSE
Definition: ecma_167.h:376
TAG_IDENT_USD
#define TAG_IDENT_USD
Definition: ecma_167.h:188
numPartitionMaps
uint32_t numPartitionMaps
Definition: ecma_167.h:72
TAG_IDENT_AVDP
#define TAG_IDENT_AVDP
Definition: ecma_167.h:183
usedSparingEntries
unsigned int usedSparingEntries
Definition: wrudf.c:73