isolib.c 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590
  1. /*
  2. * This code is based on the ISO filesystem support in MILO (by
  3. * Dave Rusling).
  4. *
  5. * This is a set of functions that provides minimal filesystem
  6. * functionality to the Linux bootstrapper. All we can do is
  7. * open and read files... but that's all we need 8-)
  8. */
  9. #include <linux/stat.h>
  10. #include <sys/types.h>
  11. #include "string.h"
  12. #include "iso.h"
  13. #include "isolib.h"
  14. #include "utils.h"
  15. /* iso9660 support code */
  16. #define MAX_OPEN_FILES 5
  17. static struct inode_table_entry {
  18. struct iso_inode inode;
  19. int inumber;
  20. int free;
  21. unsigned short old_mode;
  22. unsigned size;
  23. int nlink;
  24. int mode;
  25. void *start;
  26. } inode_table[MAX_OPEN_FILES];
  27. static unsigned long root_inode = 0;
  28. static struct isofs_super_block sb;
  29. static char data_block[1024];
  30. static char big_data_block[2048];
  31. #ifndef S_IRWXUGO
  32. # define S_IRWXUGO (S_IRWXU|S_IRWXG|S_IRWXO)
  33. # define S_IXUGO (S_IXUSR|S_IXGRP|S_IXOTH)
  34. # define S_IRUGO (S_IRUSR|S_IRGRP|S_IROTH)
  35. #endif
  36. extern long iso_dev_read (void * buf, long offset, long size);
  37. static int parse_rock_ridge_inode(struct iso_directory_record * de,
  38. struct iso_inode * inode);
  39. static char *get_rock_ridge_symlink(struct iso_inode *inode);
  40. static int get_rock_ridge_filename(struct iso_directory_record * de,
  41. char * retname,
  42. struct iso_inode * inode);
  43. int
  44. isonum_711 (char * p)
  45. {
  46. return (*p & 0xff);
  47. }
  48. int
  49. isonum_712 (char * p)
  50. {
  51. int val;
  52. val = *p;
  53. if (val & 0x80)
  54. val |= 0xffffff00;
  55. return val;
  56. }
  57. int
  58. isonum_721 (char * p)
  59. {
  60. return ((p[0] & 0xff) | ((p[1] & 0xff) << 8));
  61. }
  62. int
  63. isonum_722 (char * p)
  64. {
  65. return (((p[0] & 0xff) << 8) | (p[1] & 0xff));
  66. }
  67. int
  68. isonum_723 (char * p)
  69. {
  70. return isonum_721(p);
  71. }
  72. int
  73. isonum_731 (char * p)
  74. {
  75. return ((p[0] & 0xff)
  76. | ((p[1] & 0xff) << 8)
  77. | ((p[2] & 0xff) << 16)
  78. | ((p[3] & 0xff) << 24));
  79. }
  80. int
  81. isonum_732 (char * p)
  82. {
  83. return (((p[0] & 0xff) << 24)
  84. | ((p[1] & 0xff) << 16)
  85. | ((p[2] & 0xff) << 8)
  86. | (p[3] & 0xff));
  87. }
  88. int
  89. isonum_733 (char * p)
  90. {
  91. return isonum_731(p);
  92. }
  93. static int
  94. iso_bmap (struct iso_inode *inode, int block)
  95. {
  96. if (block < 0) {
  97. printf("iso_bmap: block<0");
  98. return 0;
  99. }
  100. return (inode->i_first_extent >> sb.s_blocksize_bits) + block;
  101. }
  102. static int
  103. iso_breadi (struct iso_inode *ip, long blkno, long nblks, char * buffer)
  104. {
  105. long i_size, abs_blkno;
  106. /* do some error checking */
  107. if (!ip || !ip->i_first_extent)
  108. return -1;
  109. i_size = ((struct inode_table_entry *) ip)->size;
  110. /* as in ext2.c - cons_read() doesn't really cope well with
  111. EOF conditions - actually it should be fixed */
  112. if ((blkno+nblks) * sb.s_blocksize > i_size)
  113. nblks = ((i_size + sb.s_blocksize)
  114. / sb.s_blocksize) - blkno;
  115. /* figure out which iso block number(s) we're being asked for */
  116. abs_blkno = iso_bmap(ip, blkno);
  117. if (!abs_blkno)
  118. return -1;
  119. /* now try and read them (easy since ISO files are continguous) */
  120. return iso_dev_read(buffer, abs_blkno * sb.s_blocksize,
  121. nblks * sb.s_blocksize);
  122. }
  123. /*
  124. * Release our hold on an inode. Since this is a read-only application,
  125. * don't worry about putting back any changes...
  126. */
  127. static void
  128. iso_iput (struct iso_inode *ip)
  129. {
  130. struct inode_table_entry *itp;
  131. /* Find and free the inode table slot we used... */
  132. itp = (struct inode_table_entry *) ip;
  133. itp->inumber = 0;
  134. itp->free = 1;
  135. }
  136. /*
  137. * Read the specified inode from the disk and return it to the user.
  138. * Returns NULL if the inode can't be read...
  139. *
  140. * Uses data_block
  141. */
  142. static struct iso_inode *
  143. iso_iget (int ino)
  144. {
  145. int i;
  146. struct iso_inode *inode;
  147. struct inode_table_entry *itp;
  148. struct iso_directory_record * raw_inode;
  149. unsigned char *pnt = NULL;
  150. void *cpnt = NULL;
  151. int high_sierra;
  152. int block;
  153. #ifdef DEBUG_ISO
  154. printf("iso_iget(ino=%d)\n", ino);
  155. #endif
  156. /* find a free inode to play with */
  157. inode = NULL;
  158. itp = NULL;
  159. for (i = 0; i < MAX_OPEN_FILES; i++) {
  160. if (inode_table[i].free) {
  161. itp = &(inode_table[i]);
  162. inode = &(itp->inode);
  163. break;
  164. }
  165. }
  166. if ((inode == NULL) || (itp == NULL)) {
  167. printf("iso9660 (iget): no free inodes\n");
  168. return (NULL);
  169. }
  170. block = ino >> sb.s_blocksize_bits;
  171. if (iso_dev_read(data_block, block * sb.s_blocksize, sb.s_blocksize)
  172. != sb.s_blocksize) {
  173. printf("iso9660: unable to read i-node block");
  174. return NULL;
  175. }
  176. pnt = ((unsigned char *) data_block + (ino & (sb.s_blocksize - 1)));
  177. raw_inode = ((struct iso_directory_record *) pnt);
  178. high_sierra = sb.s_high_sierra;
  179. if ((ino & (sb.s_blocksize - 1)) + *pnt > sb.s_blocksize){
  180. int frag1, offset;
  181. offset = (ino & (sb.s_blocksize - 1));
  182. frag1 = sb.s_blocksize - offset;
  183. cpnt = big_data_block;
  184. memcpy(cpnt, data_block + offset, frag1);
  185. offset += *pnt - sb.s_blocksize; /* DUH! pnt would get
  186. wiped out by the
  187. iso_dev_read here. */
  188. if (iso_dev_read(data_block, ++block * sb.s_blocksize,
  189. sb.s_blocksize)
  190. != sb.s_blocksize) {
  191. printf("unable to read i-node block");
  192. return NULL;
  193. }
  194. memcpy((char *)cpnt+frag1, data_block, offset);
  195. pnt = ((unsigned char *) cpnt);
  196. raw_inode = ((struct iso_directory_record *) pnt);
  197. }
  198. if (raw_inode->flags[-high_sierra] & 2) {
  199. itp->mode = S_IRUGO | S_IXUGO | S_IFDIR;
  200. itp->nlink = 1; /* Set to 1. We know there are 2, but
  201. the find utility tries to optimize
  202. if it is 2, and it screws up. It is
  203. easier to give 1 which tells find to
  204. do it the hard way. */
  205. } else {
  206. itp->mode = sb.s_mode; /* Everybody gets to read the file. */
  207. itp->nlink = 1;
  208. itp->mode |= S_IFREG;
  209. /*
  210. * If there are no periods in the name, then set the
  211. * execute permission bit
  212. */
  213. for(i=0; i< raw_inode->name_len[0]; i++)
  214. if(raw_inode->name[i]=='.' || raw_inode->name[i]==';')
  215. break;
  216. if(i == raw_inode->name_len[0] || raw_inode->name[i] == ';')
  217. itp->mode |= S_IXUGO; /* execute permission */
  218. }
  219. itp->size = isonum_733 (raw_inode->size);
  220. /* There are defective discs out there - we do this to protect
  221. ourselves. A cdrom will never contain more than 700Mb */
  222. if((itp->size < 0 || itp->size > 700000000) &&
  223. sb.s_cruft == 'n')
  224. {
  225. printf("Warning: defective cdrom. "
  226. "Enabling \"cruft\" mount option.\n");
  227. sb.s_cruft = 'y';
  228. }
  229. /*
  230. * Some dipshit decided to store some other bit of information
  231. * in the high byte of the file length. Catch this and
  232. * holler. WARNING: this will make it impossible for a file
  233. * to be > 16Mb on the CDROM!!!
  234. */
  235. if(sb.s_cruft == 'y' &&
  236. itp->size & 0xff000000)
  237. {
  238. itp->size &= 0x00ffffff;
  239. }
  240. if (raw_inode->interleave[0]) {
  241. printf("Interleaved files not (yet) supported.\n");
  242. itp->size = 0;
  243. }
  244. /* I have no idea what file_unit_size is used for, so
  245. we will flag it for now */
  246. if (raw_inode->file_unit_size[0] != 0){
  247. printf("File unit size != 0 for ISO file (%d).\n", ino);
  248. }
  249. /* I have no idea what other flag bits are used for, so
  250. we will flag it for now */
  251. #ifdef DEBUG_ISO
  252. if ((raw_inode->flags[-high_sierra] & ~2)!= 0){
  253. printf("Unusual flag settings for ISO file (%d %x).\n",
  254. ino, raw_inode->flags[-high_sierra]);
  255. }
  256. #endif
  257. inode->i_first_extent = (isonum_733 (raw_inode->extent) +
  258. isonum_711 (raw_inode->ext_attr_length))
  259. << sb.s_log_zone_size;
  260. /* Now we check the Rock Ridge extensions for further info */
  261. if (sb.s_rock)
  262. parse_rock_ridge_inode(raw_inode,inode);
  263. /* Will be used for previous directory */
  264. inode->i_backlink = 0xffffffff;
  265. switch (sb.s_conversion) {
  266. case 'a':
  267. inode->i_file_format = ISOFS_FILE_UNKNOWN; /* File type */
  268. break;
  269. case 'b':
  270. inode->i_file_format = ISOFS_FILE_BINARY; /* File type */
  271. break;
  272. case 't':
  273. inode->i_file_format = ISOFS_FILE_TEXT; /* File type */
  274. break;
  275. case 'm':
  276. inode->i_file_format = ISOFS_FILE_TEXT_M; /* File type */
  277. break;
  278. }
  279. /* keep our inode table correct */
  280. itp->free = 0;
  281. itp->inumber = ino;
  282. /* return a pointer to it */
  283. return inode;
  284. }
  285. /*
  286. * ok, we cannot use strncmp, as the name is not in our data space.
  287. * Thus we'll have to use iso_match. No big problem. Match also makes
  288. * some sanity tests.
  289. *
  290. * NOTE! unlike strncmp, iso_match returns 1 for success, 0 for failure.
  291. */
  292. static int
  293. iso_match (int len, const char *name, const char *compare, int dlen)
  294. {
  295. if (!compare)
  296. return 0;
  297. #ifdef DEBUG_ISO
  298. printf("iso_match: comparing %d chars of %s with %s\n",
  299. dlen, name, compare);
  300. #endif
  301. /* check special "." and ".." files */
  302. if (dlen == 1) {
  303. /* "." */
  304. if (compare[0] == 0) {
  305. if (!len)
  306. return 1;
  307. compare = ".";
  308. } else if (compare[0] == 1) {
  309. compare = "..";
  310. dlen = 2;
  311. }
  312. }
  313. if (dlen != len)
  314. return 0;
  315. return !memcmp(name, compare, len);
  316. }
  317. /*
  318. * Find an entry in the specified directory with the wanted name. It
  319. * returns the cache buffer in which the entry was found, and the entry
  320. * itself (as an inode number). It does NOT read the inode of the
  321. * entry - you'll have to do that yourself if you want to.
  322. *
  323. * uses data_block
  324. */
  325. static int
  326. iso_find_entry (struct iso_inode *dir, const char *name, int namelen,
  327. unsigned long *ino, unsigned long *ino_back)
  328. {
  329. unsigned long bufsize = sb.s_blocksize;
  330. unsigned char bufbits = sb.s_blocksize_bits;
  331. unsigned int block, f_pos, offset, inode_number = 0; /*shut up, gcc*/
  332. void * cpnt = NULL;
  333. unsigned int old_offset;
  334. unsigned int backlink;
  335. int dlen, match, i;
  336. struct iso_directory_record * de;
  337. char c;
  338. struct inode_table_entry *itp = (struct inode_table_entry *) dir;
  339. *ino = 0;
  340. if (!dir) return -1;
  341. if (!(block = dir->i_first_extent)) return -1;
  342. f_pos = 0;
  343. offset = 0;
  344. block = iso_bmap(dir,f_pos >> bufbits);
  345. if (!block) return -1;
  346. if (iso_dev_read(data_block, block * sb.s_blocksize, sb.s_blocksize)
  347. != sb.s_blocksize) return -1;
  348. while (f_pos < itp->size) {
  349. de = (struct iso_directory_record *) (data_block + offset);
  350. backlink = itp->inumber;
  351. inode_number = (block << bufbits) + (offset & (bufsize - 1));
  352. /* If byte is zero, this is the end of file, or time to move to
  353. the next sector. Usually 2048 byte boundaries. */
  354. if (*((unsigned char *) de) == 0) {
  355. offset = 0;
  356. /* round f_pos up to the nearest blocksize */
  357. f_pos = ((f_pos & ~(ISOFS_BLOCK_SIZE - 1))
  358. + ISOFS_BLOCK_SIZE);
  359. block = iso_bmap(dir,f_pos>>bufbits);
  360. if (!block) return -1;
  361. if (iso_dev_read(data_block,
  362. block * sb.s_blocksize,
  363. sb.s_blocksize)
  364. != sb.s_blocksize) return -1;
  365. continue; /* Will kick out if past end of directory */
  366. }
  367. old_offset = offset;
  368. offset += *((unsigned char *) de);
  369. f_pos += *((unsigned char *) de);
  370. /* Handle case where the directory entry spans two blocks.
  371. Usually 1024 byte boundaries */
  372. if (offset >= bufsize) {
  373. unsigned int frag1;
  374. frag1 = bufsize - old_offset;
  375. cpnt = big_data_block;
  376. memcpy(cpnt, data_block + old_offset, frag1);
  377. de = (struct iso_directory_record *) cpnt;
  378. offset = f_pos & (bufsize - 1);
  379. block = iso_bmap(dir,f_pos>>bufbits);
  380. if (!block) return -1;
  381. if (iso_dev_read(data_block,
  382. block * sb.s_blocksize,
  383. sb.s_blocksize)
  384. != sb.s_blocksize) return 0;
  385. memcpy((char *)cpnt+frag1, data_block, offset);
  386. }
  387. /* Handle the '.' case */
  388. if (de->name[0]==0 && de->name_len[0]==1) {
  389. inode_number = itp->inumber;
  390. backlink = 0;
  391. }
  392. /* Handle the '..' case */
  393. if (de->name[0]==1 && de->name_len[0]==1) {
  394. if((int) sb.s_firstdatazone != itp->inumber)
  395. inode_number = (isonum_733(de->extent) +
  396. isonum_711(de->ext_attr_length))
  397. << sb.s_log_zone_size;
  398. else
  399. inode_number = itp->inumber;
  400. backlink = 0;
  401. }
  402. {
  403. /* should be sufficient, since get_rock_ridge_filename
  404. * truncates at 254 chars */
  405. char retname[256];
  406. dlen = get_rock_ridge_filename(de, retname, dir);
  407. if (dlen) {
  408. strcpy(de->name, retname);
  409. } else {
  410. dlen = isonum_711(de->name_len);
  411. if(sb.s_mapping == 'n') {
  412. for (i = 0; i < dlen; i++) {
  413. c = de->name[i];
  414. if (c >= 'A' && c <= 'Z') c |= 0x20; /* lower case */
  415. if (c == ';' && i == dlen-2
  416. && de->name[i+1] == '1') {
  417. dlen -= 2;
  418. break;
  419. }
  420. if (c == ';') c = '.';
  421. de->name[i] = c;
  422. }
  423. /* This allows us to match with and without a trailing
  424. period. */
  425. if(de->name[dlen-1] == '.' && namelen == dlen-1)
  426. dlen--;
  427. }
  428. }
  429. }
  430. /*
  431. * Skip hidden or associated files unless unhide is set
  432. */
  433. match = 0;
  434. if( !(de->flags[-sb.s_high_sierra] & 5)
  435. || sb.s_unhide == 'y' )
  436. {
  437. match = iso_match(namelen, name, de->name, dlen);
  438. }
  439. if (cpnt) cpnt = NULL;
  440. if (match) {
  441. if ((int) inode_number == -1) {
  442. /* Should never happen */
  443. printf("iso9660: error inode_number = -1\n");
  444. return -1;
  445. }
  446. *ino = inode_number;
  447. *ino_back = backlink;
  448. #ifdef DEBUG_ISO
  449. printf("iso_find_entry returning successfully (ino = %d)\n",
  450. inode_number);
  451. #endif
  452. return 0;
  453. }
  454. }
  455. #ifdef DEBUG_ISO
  456. printf("iso_find_entry returning unsuccessfully (ino = %d)\n",
  457. inode_number);
  458. #endif
  459. return -1;
  460. }
  461. /*
  462. * Look up name in the current directory and return its corresponding
  463. * inode if it can be found.
  464. *
  465. */
  466. struct iso_inode *
  467. iso_lookup(struct iso_inode *dir, const char *name)
  468. {
  469. struct inode_table_entry *itp = (struct inode_table_entry *) dir;
  470. unsigned long ino, ino_back;
  471. struct iso_inode *result = NULL;
  472. int first, last;
  473. #ifdef DEBUG_ISO
  474. printf("iso_lookup: %s\n", name);
  475. #endif
  476. /* is the current inode a directory? */
  477. if (!S_ISDIR(itp->mode)) {
  478. #ifdef DEBUG_ISO
  479. printf("iso_lookup: inode %d not a directory\n", itp->inumber);
  480. #endif
  481. iso_iput(dir);
  482. return NULL;
  483. }
  484. /* work through the name finding each directory in turn */
  485. ino = 0;
  486. first = last = 0;
  487. while (last < (int) strlen(name)) {
  488. if (name[last] == '/') {
  489. if (iso_find_entry(dir, &name[first], last - first,
  490. &ino, &ino_back))
  491. return NULL;
  492. /* throw away the old directory inode, we
  493. don't need it anymore */
  494. iso_iput(dir);
  495. if (!(dir = iso_iget(ino)))
  496. return NULL;
  497. first = last + 1;
  498. last = first;
  499. } else
  500. last++;
  501. }
  502. {
  503. int rv;
  504. if ((rv = iso_find_entry(dir, &name[first], last - first, &ino, &ino_back))) {
  505. iso_iput(dir);
  506. return NULL;
  507. }
  508. }
  509. if (!(result = iso_iget(ino))) {
  510. iso_iput(dir);
  511. return NULL;
  512. }
  513. /*
  514. * We need this backlink for the ".." entry unless the name
  515. * that we are looking up traversed a mount point (in which
  516. * case the inode may not even be on an iso9660 filesystem,
  517. * and writing to u.isofs_i would only cause memory
  518. * corruption).
  519. */
  520. result->i_backlink = ino_back;
  521. iso_iput(dir);
  522. return result;
  523. }
  524. /* follow a symbolic link, returning the inode of the file it points to */
  525. static struct iso_inode *
  526. iso_follow_link(struct iso_inode *from, const char *basename)
  527. {
  528. struct inode_table_entry *itp = (struct inode_table_entry *)from;
  529. struct iso_inode *root = iso_iget(root_inode);
  530. /* HK: iso_iget expects an "int" but root_inode is "long" ?? */
  531. struct iso_inode *result = NULL;
  532. char *linkto;
  533. #ifdef DEBUG_ISO
  534. printf("iso_follow_link(%s): ",basename);
  535. #endif
  536. if (!S_ISLNK(itp->mode)) /* Hey, that's not a link! */
  537. return NULL;
  538. if (!itp->size)
  539. return NULL;
  540. if (!(linkto = get_rock_ridge_symlink(from)))
  541. return NULL;
  542. linkto[itp->size]='\0';
  543. #ifdef DEBUG_ISO
  544. printf("%s->%s\n",basename,linkto ? linkto : "[failed]");
  545. #endif
  546. /* Resolve relative links. */
  547. if (linkto[0] !='/') {
  548. char *end = strrchr(basename, '/');
  549. if (end) {
  550. char fullname[(end - basename + 1) + strlen(linkto) + 1];
  551. strncpy(fullname, basename, end - basename + 1);
  552. fullname[end - basename + 1] = '\0';
  553. strcat(fullname, linkto);
  554. #ifdef DEBUG_ISO
  555. printf("resolved to %s\n", fullname);
  556. #endif
  557. result = iso_lookup(root,fullname);
  558. } else {
  559. /* Assume it's in the root */
  560. result = iso_lookup(root,linkto);
  561. }
  562. } else {
  563. result = iso_lookup(root,linkto);
  564. }
  565. free(linkto);
  566. iso_iput(root);
  567. return result;
  568. }
  569. /*
  570. * look if the driver can tell the multi session redirection value
  571. */
  572. static inline unsigned int
  573. iso_get_last_session (void)
  574. {
  575. #ifdef DEBUG_ISO
  576. printf("iso_get_last_session() called\n");
  577. #endif
  578. return 0;
  579. }
  580. int
  581. iso_read_super (void *data, int silent)
  582. {
  583. static int first_time = 1;
  584. int high_sierra;
  585. unsigned int iso_blknum, vol_desc_start;
  586. char rock = 'y';
  587. int i;
  588. struct iso_volume_descriptor *vdp;
  589. struct hs_volume_descriptor *hdp;
  590. struct iso_primary_descriptor *pri = NULL;
  591. struct hs_primary_descriptor *h_pri = NULL;
  592. struct iso_directory_record *rootp;
  593. /* Initialize the inode table */
  594. for (i = 0; i < MAX_OPEN_FILES; i++) {
  595. inode_table[i].free = 1;
  596. inode_table[i].inumber = 0;
  597. }
  598. #ifdef DEBUG_ISO
  599. printf("iso_read_super() called\n");
  600. #endif
  601. /* set up the block size */
  602. sb.s_blocksize = 1024;
  603. sb.s_blocksize_bits = 10;
  604. sb.s_high_sierra = high_sierra = 0; /* default is iso9660 */
  605. vol_desc_start = iso_get_last_session();
  606. for (iso_blknum = vol_desc_start+16; iso_blknum < vol_desc_start+100;
  607. iso_blknum++) {
  608. #ifdef DEBUG_ISO
  609. printf("iso_read_super: iso_blknum=%d\n", iso_blknum);
  610. #endif
  611. if (iso_dev_read(data_block, iso_blknum * 2048,
  612. sb.s_blocksize) != sb.s_blocksize)
  613. {
  614. printf("iso_read_super: bread failed, dev "
  615. "iso_blknum %d\n", iso_blknum);
  616. return -1;
  617. }
  618. vdp = (struct iso_volume_descriptor *)data_block;
  619. hdp = (struct hs_volume_descriptor *)data_block;
  620. if (strncmp (hdp->id, HS_STANDARD_ID, sizeof hdp->id) == 0) {
  621. if (isonum_711 (hdp->type) != ISO_VD_PRIMARY)
  622. return -1;
  623. if (isonum_711 (hdp->type) == ISO_VD_END)
  624. return -1;
  625. sb.s_high_sierra = 1;
  626. high_sierra = 1;
  627. rock = 'n';
  628. h_pri = (struct hs_primary_descriptor *)vdp;
  629. break;
  630. }
  631. if (strncmp (vdp->id, ISO_STANDARD_ID, sizeof vdp->id) == 0) {
  632. if (isonum_711 (vdp->type) != ISO_VD_PRIMARY)
  633. return -1;
  634. if (isonum_711 (vdp->type) == ISO_VD_END)
  635. return -1;
  636. pri = (struct iso_primary_descriptor *)vdp;
  637. break;
  638. }
  639. }
  640. if(iso_blknum == vol_desc_start + 100) {
  641. if (!silent)
  642. printf("iso: Unable to identify CD-ROM format.\n");
  643. return -1;
  644. }
  645. if (high_sierra) {
  646. rootp = (struct iso_directory_record *)
  647. h_pri->root_directory_record;
  648. #if 0
  649. //See http://www.y-adagio.com/public/standards/iso_cdromr/sect_1.htm
  650. //Section 4.16 and 4.17 for explanation why this check is invalid
  651. if (isonum_723 (h_pri->volume_set_size) != 1) {
  652. printf("Multi-volume disks not (yet) supported.\n");
  653. return -1;
  654. };
  655. #endif
  656. sb.s_nzones = isonum_733 (h_pri->volume_space_size);
  657. sb.s_log_zone_size =
  658. isonum_723 (h_pri->logical_block_size);
  659. sb.s_max_size = isonum_733(h_pri->volume_space_size);
  660. } else {
  661. rootp = (struct iso_directory_record *)
  662. pri->root_directory_record;
  663. #if 0
  664. //See http://www.y-adagio.com/public/standards/iso_cdromr/sect_1.htm
  665. //Section 4.16 and 4.17 for explanation why this check is invalid
  666. if (isonum_723 (pri->volume_set_size) != 1) {
  667. printf("Multi-volume disks not (yet) supported.\n");
  668. return -1;
  669. }
  670. #endif
  671. sb.s_nzones = isonum_733 (pri->volume_space_size);
  672. sb.s_log_zone_size = isonum_723 (pri->logical_block_size);
  673. sb.s_max_size = isonum_733(pri->volume_space_size);
  674. }
  675. sb.s_ninodes = 0; /* No way to figure this out easily */
  676. /* RDE: convert log zone size to bit shift */
  677. switch (sb.s_log_zone_size) {
  678. case 512: sb.s_log_zone_size = 9; break;
  679. case 1024: sb.s_log_zone_size = 10; break;
  680. case 2048: sb.s_log_zone_size = 11; break;
  681. default:
  682. printf("Bad logical zone size %ld\n", sb.s_log_zone_size);
  683. return -1;
  684. }
  685. /* RDE: data zone now byte offset! */
  686. sb.s_firstdatazone = (isonum_733( rootp->extent)
  687. << sb.s_log_zone_size);
  688. /*
  689. * The CDROM is read-only, has no nodes (devices) on it, and
  690. * since all of the files appear to be owned by root, we
  691. * really do not want to allow suid. (suid or devices will
  692. * not show up unless we have Rock Ridge extensions).
  693. */
  694. if (first_time) {
  695. first_time = 0;
  696. printf("iso: Max size:%ld Log zone size:%ld\n",
  697. sb.s_max_size, 1UL << sb.s_log_zone_size);
  698. printf("iso: First datazone:%ld Root inode number %d\n",
  699. sb.s_firstdatazone >> sb.s_log_zone_size,
  700. isonum_733 (rootp->extent) << sb.s_log_zone_size);
  701. if (high_sierra)
  702. printf("iso: Disc in High Sierra format.\n");
  703. }
  704. /* set up enough so that it can read an inode */
  705. sb.s_mapping = 'n';
  706. sb.s_rock = (rock == 'y' ? 1 : 0);
  707. sb.s_conversion = 'b';
  708. sb.s_cruft = 'n';
  709. sb.s_unhide = 'n';
  710. /*
  711. * It would be incredibly stupid to allow people to mark every file
  712. * on the disk as suid, so we merely allow them to set the default
  713. * permissions.
  714. */
  715. sb.s_mode = S_IRUGO & 0777;
  716. /* return successfully */
  717. root_inode = isonum_733 (rootp->extent) << sb.s_log_zone_size;
  718. /* HK: isonum_733 returns an "int" but root_inode is a long ? */
  719. return 0;
  720. }
  721. int
  722. iso_bread (int fd, long blkno, long nblks, char * buffer)
  723. {
  724. struct iso_inode *inode;
  725. /* find the inode for this file */
  726. inode = &inode_table[fd].inode;
  727. return iso_breadi(inode, blkno, nblks, buffer);
  728. }
  729. int
  730. iso_open (const char *filename)
  731. {
  732. struct iso_inode *inode, *oldinode;
  733. struct iso_inode *root;
  734. /* get the root directory */
  735. root = iso_iget(root_inode);
  736. /* HK: iso_iget expects an "int" but root_inode is "long" ?? */
  737. if (!root) {
  738. printf("iso9660: get root inode failed\n");
  739. return -1;
  740. }
  741. /* lookup the file */
  742. inode = iso_lookup(root, filename);
  743. #ifdef DEBUG_ISO
  744. if (inode && S_ISLNK(((struct inode_table_entry *)inode)->mode)) {
  745. printf("%s is a link (len %u)\n",filename,
  746. ((struct inode_table_entry *)inode)->size);
  747. } else {
  748. printf("%s is not a link\n",filename);
  749. }
  750. #endif
  751. while ((inode) && (S_ISLNK(((struct inode_table_entry *)inode)->mode))) {
  752. oldinode = inode;
  753. inode = iso_follow_link(oldinode, filename);
  754. iso_iput(oldinode);
  755. }
  756. if (inode == NULL)
  757. return -1;
  758. else {
  759. struct inode_table_entry * itp =
  760. (struct inode_table_entry *) inode;
  761. return (itp - inode_table);
  762. }
  763. }
  764. void
  765. iso_close (int fd)
  766. {
  767. iso_iput(&inode_table[fd].inode);
  768. }
  769. long
  770. iso_map (int fd, long block)
  771. {
  772. return iso_bmap(&inode_table[fd].inode, block) * sb.s_blocksize;
  773. }
  774. #include <linux/stat.h>
  775. int
  776. iso_fstat (int fd, struct stat * buf)
  777. {
  778. struct inode_table_entry * ip = inode_table + fd;
  779. if (fd >= MAX_OPEN_FILES)
  780. return -1;
  781. memset(buf, 0, sizeof(struct stat));
  782. /* fill in relevant fields */
  783. buf->st_ino = ip->inumber;
  784. buf->st_mode = ip->mode;
  785. buf->st_nlink = ip->nlink;
  786. buf->st_size = ip->size;
  787. return 0;
  788. }
  789. /*
  790. * NOTE: mixing calls to this and calls to any other function that reads from
  791. * the filesystem will clobber the buffers and cause much wailing and gnashing
  792. * of teeth.
  793. *
  794. * Sorry this function is so ugly. It was written as a way for me to
  795. * learn how the ISO filesystem stuff works.
  796. *
  797. * Will Woods, 2/2001
  798. *
  799. * Uses data_block
  800. */
  801. char *iso_readdir_i(int fd, int rewind) {
  802. struct inode_table_entry *itp = &(inode_table[fd]);
  803. struct iso_directory_record *dirent = 0;
  804. unsigned int fraglen = 0, block, dirent_len, name_len = 0, oldoffset;
  805. static unsigned int blockoffset = 0, diroffset = 0;
  806. if (!S_ISDIR(itp->mode)) {
  807. printf("Not a directory\n");
  808. return NULL;
  809. }
  810. /* Initial read to this directory, get the first block */
  811. if (rewind) {
  812. blockoffset = diroffset = 0;
  813. block = iso_bmap(&itp->inode,0);
  814. #ifdef DEBUG_ISO
  815. printf("fd #%d, inode %d, first_extent %d, block %u\n",
  816. fd,itp->inumber,itp->inode.i_first_extent,block);
  817. #endif
  818. if (!block) return NULL;
  819. if (iso_dev_read(data_block, block * sb.s_blocksize, sb.s_blocksize)
  820. != sb.s_blocksize) return NULL;
  821. }
  822. /* keep doing this until we get a filename or we fail */
  823. while (!name_len) {
  824. /* set up our dirent pointer into the block of data we've read */
  825. dirent = (struct iso_directory_record *) (data_block + blockoffset);
  826. dirent_len = isonum_711(dirent->length);
  827. #ifdef DEBUG_ISO
  828. printf("diroffset=%u, blockoffset=%u, length=%u\n",
  829. diroffset,blockoffset,dirent_len);
  830. #endif
  831. /* End of directory listing or end of sector */
  832. if (dirent_len == 0) {
  833. /* round diroffset up to the nearest blocksize */
  834. diroffset = ((diroffset & ~(ISOFS_BLOCK_SIZE - 1))
  835. + ISOFS_BLOCK_SIZE);
  836. #ifdef DEBUG_ISO
  837. printf("dirent_len == 0. diroffset=%u, itp->size=%u. ",
  838. diroffset,itp->size);
  839. #endif
  840. if (diroffset >= itp->size) {
  841. #ifdef DEBUG_ISO
  842. printf("End of directory.\n");
  843. #endif
  844. return NULL;
  845. } else {
  846. #ifdef DEBUG_ISO
  847. printf("End of sector. Need next block.\n");
  848. #endif
  849. /* Get the next block. */
  850. block = iso_bmap(&itp->inode, diroffset>>sb.s_blocksize_bits);
  851. if (!block) return NULL;
  852. if (iso_dev_read(data_block, block * sb.s_blocksize, sb.s_blocksize)
  853. != sb.s_blocksize) return NULL;
  854. /* set the offsets and the pointers properly */
  855. blockoffset = 0;
  856. dirent = (struct iso_directory_record *) data_block;
  857. dirent_len = isonum_711(dirent->length);
  858. #ifdef DEBUG_ISO
  859. printf("diroffset=%u, blockoffset=%u, length=%u\n",
  860. diroffset,blockoffset,dirent_len);
  861. #endif
  862. }
  863. }
  864. /* update the offsets for the next read */
  865. oldoffset = blockoffset;
  866. blockoffset += dirent_len;
  867. diroffset += dirent_len;
  868. /*
  869. * directory entry spans two blocks -
  870. * get next block and glue the two halves together
  871. */
  872. if (blockoffset >= sb.s_blocksize) {
  873. fraglen = sb.s_blocksize - oldoffset;
  874. #ifdef DEBUG_ISO
  875. printf("fragmented block: blockoffset = %u, fraglen = %u\n",
  876. blockoffset, fraglen);
  877. #endif
  878. /* copy the fragment at end of old block to front of new buffer */
  879. memcpy(big_data_block, data_block + oldoffset, fraglen);
  880. /* read the next block into the buffer after the old fragment */
  881. block = iso_bmap(&itp->inode, diroffset >> sb.s_blocksize_bits);
  882. if (!block) return NULL;
  883. if (iso_dev_read(big_data_block + fraglen, block * sb.s_blocksize, sb.s_blocksize)
  884. != sb.s_blocksize) return NULL;
  885. #ifdef DEBUG_ISO
  886. printf("read %u bytes from offset %u\n",
  887. sb.s_blocksize, block * sb.s_blocksize);
  888. #endif
  889. blockoffset = 0;
  890. dirent = (struct iso_directory_record *) big_data_block;
  891. }
  892. /*
  893. * Everything's cool, let's get the filename.
  894. * First we need to figure out the length.
  895. */
  896. name_len = isonum_711(dirent->name_len);
  897. #ifdef DEBUG_ISO
  898. if (name_len==0) printf("dirent->name_len = 0, skipping.\n");
  899. #endif
  900. /* skip '.' and '..' */
  901. if (name_len == 1) {
  902. if (dirent->name[0] == (char)0) name_len = 0;
  903. if (dirent->name[0] == (char)1) name_len = 0;
  904. }
  905. if (sb.s_unhide == 'n') {
  906. /* sb.s_high_sierra is the offset for the position of the flags.
  907. this adjusts for differences between iso9660 and high sierra.
  908. if bit 0 (exists) or bit 2 (associated) are set, we ignore
  909. this record. */
  910. if (dirent->flags[-sb.s_high_sierra] & 5) name_len = 0;
  911. }
  912. /* if we have a real filename here.. */
  913. if (name_len) {
  914. /* should be sufficient, since get_rock_ridge_filename truncates
  915. at 254 characters */
  916. char rrname[256];
  917. if ((name_len = get_rock_ridge_filename(dirent, rrname, &itp->inode))) {
  918. rrname[name_len] = '\0';
  919. /* it's okay if rrname is longer than dirent->name, because
  920. we're just overwriting parts of the now-useless dirent */
  921. strcpy(dirent->name, rrname);
  922. } else {
  923. int i;
  924. char c;
  925. if (sb.s_mapping == 'n') { /* downcase the name */
  926. for (i = 0; i < name_len; i++) {
  927. c = dirent->name[i];
  928. /* lower case */
  929. if ((c >= 'A') && (c <= 'Z')) c |= 0x20;
  930. /* Drop trailing '.;1' */
  931. if ((c == '.') && (i == name_len-3) &&
  932. (dirent->name[i+1] == ';') &&
  933. (dirent->name[i+2] == '1')) {
  934. name_len -= 3 ; break;
  935. }
  936. /* Drop trailing ';1' */
  937. if ((c == ';') && (i == name_len-2) &&
  938. (dirent->name[i+1] == '1')) {
  939. name_len -= 2; break;
  940. }
  941. /* convert ';' to '.' */
  942. if (c == ';')
  943. c = '.';
  944. dirent->name[i] = c;
  945. }
  946. dirent->name[name_len] = '\0';
  947. }
  948. }
  949. }
  950. /* now that we're done using it, and it's smaller than a full block,
  951. * copy big_data_block back into data_block */
  952. if (fraglen) {
  953. int len = sb.s_blocksize - dirent_len;
  954. memcpy(data_block, big_data_block + dirent_len, len);
  955. #ifdef DEBUG_ISO
  956. printf("copied %u bytes of data back to data_block\n", len);
  957. #endif
  958. blockoffset = 0;
  959. fraglen = 0;
  960. }
  961. }
  962. return dirent->name;
  963. }
  964. /**********************************************************************
  965. *
  966. * Rock Ridge functions and definitions, from the Linux kernel source.
  967. * linux/fs/isofs/rock.c, (c) 1992, 1993 Eric Youngdale.
  968. *
  969. **********************************************************************/
  970. #define SIG(A,B) ((A << 8) | B)
  971. /* This is a way of ensuring that we have something in the system
  972. use fields that is compatible with Rock Ridge */
  973. #define CHECK_SP(FAIL) \
  974. if(rr->u.SP.magic[0] != 0xbe) FAIL; \
  975. if(rr->u.SP.magic[1] != 0xef) FAIL;
  976. /* We define a series of macros because each function must do exactly the
  977. same thing in certain places. We use the macros to ensure that everything
  978. is done correctly */
  979. #define CONTINUE_DECLS \
  980. int cont_extent = 0, cont_offset = 0, cont_size = 0; \
  981. void * buffer = 0
  982. #define CHECK_CE \
  983. {cont_extent = isonum_733(rr->u.CE.extent); \
  984. cont_offset = isonum_733(rr->u.CE.offset); \
  985. cont_size = isonum_733(rr->u.CE.size);}
  986. #define SETUP_ROCK_RIDGE(DE,CHR,LEN) \
  987. {LEN= sizeof(struct iso_directory_record) + DE->name_len[0]; \
  988. if(LEN & 1) LEN++; \
  989. CHR = ((unsigned char *) DE) + LEN; \
  990. LEN = *((unsigned char *) DE) - LEN;}
  991. #define MAYBE_CONTINUE(LABEL) \
  992. {if (buffer) free(buffer); \
  993. if (cont_extent){ \
  994. buffer = malloc(cont_size); \
  995. if (!buffer) goto out; \
  996. if (iso_dev_read(buffer, cont_extent * ISOFS_BLOCK_SIZE + cont_offset, cont_size) \
  997. == cont_size) { \
  998. chr = (unsigned char *) buffer; \
  999. len = cont_size; \
  1000. cont_extent = cont_size = cont_offset = 0; \
  1001. goto LABEL; \
  1002. }; \
  1003. printf("Unable to read rock-ridge attributes\n"); \
  1004. }}
  1005. int get_rock_ridge_filename(struct iso_directory_record * de,
  1006. char * retname,
  1007. struct iso_inode * inode)
  1008. {
  1009. int len;
  1010. unsigned char * chr;
  1011. int retnamlen = 0, truncate=0;
  1012. int cont_extent = 0, cont_offset = 0, cont_size = 0;
  1013. void *buffer = 0;
  1014. /* No rock ridge? well then... */
  1015. if (!sb.s_rock) return 0;
  1016. *retname = '\0';
  1017. len = sizeof(struct iso_directory_record) + isonum_711(de->name_len);
  1018. if (len & 1) len++;
  1019. chr = ((unsigned char *) de) + len;
  1020. len = *((unsigned char *) de) - len;
  1021. {
  1022. struct rock_ridge * rr;
  1023. int sig;
  1024. repeat:
  1025. while (len > 1){ /* There may be one byte for padding somewhere */
  1026. rr = (struct rock_ridge *) chr;
  1027. if (rr->len == 0) break; /* Something got screwed up here */
  1028. sig = (chr[0] << 8) + chr[1];
  1029. chr += rr->len;
  1030. len -= rr->len;
  1031. switch(sig){
  1032. case SIG('R','R'):
  1033. if((rr->u.RR.flags[0] & RR_NM) == 0) goto out;
  1034. break;
  1035. case SIG('S','P'):
  1036. if (rr->u.SP.magic[0] != 0xbe ||
  1037. rr->u.SP.magic[1] != 0xef)
  1038. goto out;
  1039. break;
  1040. case SIG('C','E'):
  1041. cont_extent = isonum_733(rr->u.CE.extent);
  1042. cont_offset = isonum_733(rr->u.CE.offset);
  1043. cont_size = isonum_733(rr->u.CE.size);
  1044. break;
  1045. case SIG('N','M'):
  1046. if (truncate) break;
  1047. /*
  1048. * If the flags are 2 or 4, this indicates '.' or '..'.
  1049. * We don't want to do anything with this, because it
  1050. * screws up the code that calls us. We don't really
  1051. * care anyways, since we can just use the non-RR
  1052. * name.
  1053. */
  1054. if (rr->u.NM.flags & 6) {
  1055. break;
  1056. }
  1057. if (rr->u.NM.flags & ~1) {
  1058. printf("Unsupported NM flag settings (%d)\n",rr->u.NM.flags);
  1059. break;
  1060. };
  1061. if((strlen(retname) + rr->len - 5) >= 254) {
  1062. int i = 254-strlen(retname);
  1063. strncat(retname, rr->u.NM.name, i);
  1064. retnamlen += i;
  1065. truncate = 1;
  1066. break;
  1067. };
  1068. strncat(retname, rr->u.NM.name, rr->len - 5);
  1069. retnamlen += rr->len - 5;
  1070. break;
  1071. case SIG('R','E'):
  1072. goto out;
  1073. default:
  1074. break;
  1075. }
  1076. };
  1077. }
  1078. if (buffer) free(buffer);
  1079. if (cont_extent) { /* we had a continued record */
  1080. buffer = malloc(cont_size);
  1081. if (!buffer) goto out;
  1082. if (iso_dev_read(buffer, cont_extent * ISOFS_BLOCK_SIZE + cont_offset, cont_size)
  1083. != cont_size) goto out;
  1084. chr = buffer + cont_offset;
  1085. len = cont_size;
  1086. cont_extent = cont_size = cont_offset = 0;
  1087. goto repeat;
  1088. }
  1089. return retnamlen; /* If 0, this file did not have a NM field */
  1090. out:
  1091. if (buffer) free(buffer);
  1092. return 0;
  1093. }
  1094. static int parse_rock_ridge_inode(struct iso_directory_record * de,
  1095. struct iso_inode * inode){
  1096. int len;
  1097. unsigned char *chr;
  1098. int symlink_len = 0;
  1099. struct inode_table_entry *itp = (struct inode_table_entry *) inode;
  1100. CONTINUE_DECLS;
  1101. #ifdef DEBUG_ROCK
  1102. printf("parse_rock_ridge_inode(%u)\n",itp->inumber);
  1103. #endif
  1104. if (!sb.s_rock) return 0;
  1105. SETUP_ROCK_RIDGE(de, chr, len);
  1106. repeat:
  1107. {
  1108. int sig;
  1109. /* struct iso_inode * reloc; */
  1110. struct rock_ridge * rr;
  1111. int rootflag;
  1112. while (len > 1){ /* There may be one byte for padding somewhere */
  1113. rr = (struct rock_ridge *) chr;
  1114. if (rr->len == 0) goto out; /* Something got screwed up here */
  1115. sig = (chr[0] << 8) + chr[1];
  1116. chr += rr->len;
  1117. len -= rr->len;
  1118. switch(sig){
  1119. case SIG('R','R'):
  1120. #ifdef DEBUG_ROCK
  1121. printf("RR ");
  1122. #endif
  1123. if((rr->u.RR.flags[0] &
  1124. (RR_PX | RR_TF | RR_SL | RR_CL)) == 0) goto out;
  1125. break;
  1126. case SIG('S','P'):
  1127. #ifdef DEBUG_ROCK
  1128. printf("SP ");
  1129. #endif
  1130. CHECK_SP(goto out);
  1131. break;
  1132. case SIG('C','E'):
  1133. #ifdef DEBUG_ROCK
  1134. printf("CE ");
  1135. #endif
  1136. CHECK_CE;
  1137. break;
  1138. case SIG('E','R'):
  1139. #ifdef DEBUG_ROCK
  1140. printf("ISO 9660 Extensions: ");
  1141. { int p;
  1142. for(p=0;p<rr->u.ER.len_id;p++) printf("%c",rr->u.ER.data[p]);
  1143. };
  1144. printf("\n");
  1145. #endif
  1146. break;
  1147. case SIG('P','X'):
  1148. #ifdef DEBUG_ROCK
  1149. printf("PX ");
  1150. #endif
  1151. itp->mode = isonum_733(rr->u.PX.mode);
  1152. itp->nlink = isonum_733(rr->u.PX.n_links);
  1153. /* Ignore uid and gid. We're only a simple bootloader, after all. */
  1154. break;
  1155. case SIG('P','N'):
  1156. /* Ignore device files. */
  1157. break;
  1158. case SIG('T','F'):
  1159. /* create/modify/access times are uninteresting to us. */
  1160. break;
  1161. case SIG('S','L'):
  1162. #ifdef DEBUG_ROCK
  1163. printf("SL ");
  1164. #endif
  1165. {int slen;
  1166. struct SL_component * slp;
  1167. struct SL_component * oldslp;
  1168. slen = rr->len - 5;
  1169. slp = &rr->u.SL.link;
  1170. itp->size = symlink_len;
  1171. while (slen > 1){
  1172. rootflag = 0;
  1173. switch(slp->flags &~1){
  1174. case 0:
  1175. itp->size += slp->len;
  1176. break;
  1177. case 2:
  1178. itp->size += 1;
  1179. break;
  1180. case 4:
  1181. itp->size += 2;
  1182. break;
  1183. case 8:
  1184. rootflag = 1;
  1185. itp->size += 1;
  1186. break;
  1187. default:
  1188. printf("Symlink component flag not implemented\n");
  1189. };
  1190. slen -= slp->len + 2;
  1191. oldslp = slp;
  1192. slp = (struct SL_component *) (((char *) slp) + slp->len + 2);
  1193. if(slen < 2) {
  1194. if( ((rr->u.SL.flags & 1) != 0)
  1195. && ((oldslp->flags & 1) == 0) ) itp->size += 1;
  1196. break;
  1197. }
  1198. /*
  1199. * If this component record isn't continued, then append a '/'.
  1200. */
  1201. if( (!rootflag)
  1202. && ((oldslp->flags & 1) == 0) ) itp->size += 1;
  1203. }
  1204. }
  1205. symlink_len = itp->size;
  1206. break;
  1207. case SIG('R','E'):
  1208. printf("Attempt to read inode for relocated directory\n");
  1209. goto out;
  1210. case SIG('C','L'):
  1211. #ifdef DEBUG_ROCK
  1212. printf("CL(!) ");
  1213. #endif
  1214. /* I'm unsure as to the function of this signature.
  1215. We'll ignore it and hope that everything will be OK.
  1216. */
  1217. #if 0
  1218. #ifdef DEBUG
  1219. printf("RR CL (%x)\n",inode->i_ino);
  1220. #endif
  1221. inode->inode.first_extent = isonum_733(rr->u.CL.location);
  1222. reloc = iso_iget(inode->i_sb,
  1223. (inode->u.isofs_i.i_first_extent <<
  1224. inode -> i_sb -> u.isofs_sb.s_log_zone_size));
  1225. if (!reloc)
  1226. goto out;
  1227. inode->mode = reloc->mode;
  1228. inode->nlink = reloc->nlink;
  1229. inode->size = reloc->size;
  1230. iso_iput(reloc);
  1231. #endif /* 0 */
  1232. break;
  1233. default:
  1234. break;
  1235. }
  1236. };
  1237. }
  1238. MAYBE_CONTINUE(repeat);
  1239. #ifdef DEBUG_ROCK
  1240. printf("\nparse_rock_ridge_inode(): ok\n");
  1241. #endif
  1242. return 1;
  1243. out:
  1244. if(buffer) free(buffer);
  1245. #ifdef DEBUG_ROCK
  1246. printf("\nparse_rock_ridge_inode(): failed\n");
  1247. #endif
  1248. return 0;
  1249. }
  1250. /* Returns the name of the file that this inode is symlinked to. This is
  1251. in malloc memory, so we have to free it when we're done */
  1252. static char * get_rock_ridge_symlink(struct iso_inode *inode)
  1253. {
  1254. int blocksize = ISOFS_BLOCK_SIZE;
  1255. int blockbits = ISOFS_BLOCK_BITS;
  1256. char * rpnt = NULL;
  1257. unsigned char * pnt;
  1258. struct iso_directory_record * raw_inode;
  1259. struct inode_table_entry *itp = (struct inode_table_entry *)inode;
  1260. CONTINUE_DECLS;
  1261. int block, blockoffset;
  1262. int sig;
  1263. int rootflag;
  1264. int len;
  1265. unsigned char * chr, * buf = NULL;
  1266. struct rock_ridge * rr;
  1267. #ifdef DEBUG_ROCK
  1268. printf("get_rock_ridge_symlink(%u): link is %u bytes long\n",itp->inumber, itp->size);
  1269. #endif
  1270. if (!sb.s_rock) goto out;
  1271. block = itp->inumber >> blockbits;
  1272. blockoffset = itp->inumber & (blocksize - 1);
  1273. buf=malloc(blocksize);
  1274. if (iso_dev_read(buf, block << blockbits, blocksize) != blocksize)
  1275. goto out_noread;
  1276. pnt = ((unsigned char *) buf) + blockoffset;
  1277. raw_inode = ((struct iso_directory_record *) pnt);
  1278. /*
  1279. * If we go past the end of the buffer, there is some sort of error.
  1280. */
  1281. if (blockoffset + *pnt > blocksize)
  1282. goto out_bad_span;
  1283. /* Now test for possible Rock Ridge extensions which will override some of
  1284. these numbers in the inode structure. */
  1285. SETUP_ROCK_RIDGE(raw_inode, chr, len);
  1286. repeat:
  1287. while (len > 1){ /* There may be one byte for padding somewhere */
  1288. rr = (struct rock_ridge *) chr;
  1289. if (rr->len == 0) goto out; /* Something got screwed up here */
  1290. sig = (chr[0] << 8) + chr[1];
  1291. chr += rr->len;
  1292. len -= rr->len;
  1293. #ifdef DEBUG_ROCK
  1294. printf("%c%c ",chr[0],chr[1]);
  1295. #endif
  1296. switch(sig){
  1297. case SIG('R','R'):
  1298. if((rr->u.RR.flags[0] & RR_SL) == 0) goto out;
  1299. break;
  1300. case SIG('S','P'):
  1301. CHECK_SP(goto out);
  1302. break;
  1303. case SIG('S','L'):
  1304. {int slen;
  1305. struct SL_component * oldslp;
  1306. struct SL_component * slp;
  1307. slen = rr->len - 5;
  1308. slp = &rr->u.SL.link;
  1309. while (slen > 1){
  1310. if (!rpnt){
  1311. rpnt = (char *) malloc (itp->size +1);
  1312. if (!rpnt) goto out;
  1313. *rpnt = 0;
  1314. };
  1315. rootflag = 0;
  1316. switch(slp->flags &~1){
  1317. case 0:
  1318. strncat(rpnt,slp->text, slp->len);
  1319. break;
  1320. case 2:
  1321. strcat(rpnt,".");
  1322. break;
  1323. case 4:
  1324. strcat(rpnt,"..");
  1325. break;
  1326. case 8:
  1327. rootflag = 1;
  1328. strcat(rpnt,"/");
  1329. break;
  1330. default:
  1331. #ifdef DEBUG_ROCK
  1332. printf("Symlink component flag not implemented (%d)\n",slen);
  1333. #endif
  1334. break;
  1335. };
  1336. slen -= slp->len + 2;
  1337. oldslp = slp;
  1338. slp = (struct SL_component *) (((char *) slp) + slp->len + 2);
  1339. if(slen < 2) {
  1340. /*
  1341. * If there is another SL record, and this component record
  1342. * isn't continued, then add a slash.
  1343. */
  1344. if( ((rr->u.SL.flags & 1) != 0)
  1345. && ((oldslp->flags & 1) == 0) ) strcat(rpnt,"/");
  1346. break;
  1347. }
  1348. /*
  1349. * If this component record isn't continued, then append a '/'.
  1350. */
  1351. if( (!rootflag)
  1352. && ((oldslp->flags & 1) == 0) ) strcat(rpnt,"/");
  1353. };
  1354. break;
  1355. case SIG('C','E'):
  1356. CHECK_CE; /* This tells is if there is a continuation record */
  1357. break;
  1358. default:
  1359. break;
  1360. }
  1361. };
  1362. };
  1363. MAYBE_CONTINUE(repeat);
  1364. out_freebh:
  1365. #ifdef DEBUG_ROCK
  1366. printf("\nget_rock_ridge_symlink() exiting\n");
  1367. #endif
  1368. if (buf)
  1369. free(buf);
  1370. return rpnt;
  1371. /* error exit from macro */
  1372. out:
  1373. #ifdef DEBUG_ROCK
  1374. printf("abort");
  1375. #endif
  1376. if(buffer)
  1377. free(buffer);
  1378. if(rpnt)
  1379. free(rpnt);
  1380. rpnt = NULL;
  1381. goto out_freebh;
  1382. out_noread:
  1383. printf("unable to read block");
  1384. goto out_freebh;
  1385. out_bad_span:
  1386. printf("symlink spans iso9660 blocks\n");
  1387. goto out_freebh;
  1388. }