inoptr srch_dir(inoptr wd, char *compname) { int curentry; blkno_t curblock; struct direct *buf; int nblocks; uint16_t inum; nblocks = (wd->c_node.i_size + BLKMASK) >> BLKSHIFT; for(curblock=0; curblock < nblocks; ++curblock) { buf = (struct direct *)bread(wd->c_dev, bmap(wd, curblock, 1), 0); for(curentry = 0; curentry < (512/DIR_LEN); ++curentry) { if(namecomp(compname, buf[curentry].d_name)) { inum = buf[curentry & 0x1f].d_ino; brelse(buf); return i_open(wd->c_dev, inum); } } brelse(buf); } return NULLINODE; }
static int GetDirectoryEntry(int drive, int copyFlag, char *pathname, Bit32u buffer) { char searchName[256]; int error, dirSize; unsigned char defBuffer[CD_FRAMESIZE]; unsigned dirEntrySector, entryLength, index; char *searchPos = searchName; size_t searchlen; /* skip initial \ */ MEMCPY_2UNIX(searchName, pathname + 1, 255); searchName[255] = '\0'; strupperDOS(searchName); //strip of tailing . (XCOM APOCALIPSE) searchlen = strlen(searchName); if (searchlen > 1 && strcmp(searchName, "..")) if (searchName[searchlen - 1] == '.') searchName[searchlen - 1] = 0; C_printf("MSCDEX: Get DirEntry : Find : %s\n", searchName); // read vtoc error = ReadSectors(drive, 16, 1, defBuffer); if (error) return error; // TODO: has to be iso 9660 if (memcmp("CD001", defBuffer + 1, 5) != 0) return MSCDEX_ERROR_BAD_FORMAT; // get directory position dirEntrySector = *(unsigned *)(defBuffer + 156 + 2); dirSize = *(int *)(defBuffer + 156 + 10); do { // Get string part char *useName = searchPos; size_t useNameLength; searchPos = strchr(searchPos, '\\'); if (searchPos) { useNameLength = searchPos - useName; searchPos++; } else useNameLength = strlen(useName); while (1) { error = ReadSectors(drive, dirEntrySector, 1, defBuffer); if (error) return error; index = 0; do { char *entryName, *longername; unsigned nameLength; entryLength = defBuffer[index]; C_printf("MSCDEX: entryLength=%u, index=%d\n", entryLength, index); if (entryLength == 0) break; nameLength = defBuffer[index + 32]; entryName = defBuffer + index + 33; if (namecomp (entryName, nameLength, useName, useNameLength)) break; /* Xcom Apocalipse searches for MUSIC. * and expects to find MUSIC;1 * All Files on the CDROM are of the kind * blah;1 */ longername = memchr(entryName, ';', nameLength); if (longername && namecomp(entryName, longername - entryName, useName, useNameLength)) break; index += entryLength; } while (index + 33 <= CD_FRAMESIZE); if (index + 33 <= CD_FRAMESIZE) break; // continue search in next sector dirSize -= 2048; if (dirSize <= 0) return 2; // file not found dirEntrySector++; } // directory wechseln dirEntrySector = *(unsigned *)(defBuffer + index + 2); dirSize = *(unsigned *)(defBuffer + index + 10); } while (searchPos); return fill_buffer(copyFlag, buffer, defBuffer + index, entryLength); };
bool ch_link(inoptr wd, char *oldname, char *newname, inoptr nindex) { struct direct curentry; int i; if(!(getperm(wd) & OTH_WR)) { udata.u_error = EPERM; return false; } /* Inserting a new blank entry ? */ if (!*newname && nindex != NULLINODE) { udata.u_error = EEXIST; return false; } /* Search the directory for the desired slot. */ udata.u_offset = 0; for(;;) { udata.u_count = DIR_LEN; udata.u_base =(char *)&curentry; udata.u_sysio = true; readi(wd, 0); /* Read until EOF or name is found. readi() advances udata.u_offset */ if(udata.u_count == 0 || namecomp(oldname, curentry.d_name)) break; } if(udata.u_count == 0 && *oldname) return false; /* Entry not found */ memcpy(curentry.d_name, newname, FILENAME_LEN); // pad name with NULLs for(i = 0; i < FILENAME_LEN; ++i) if(curentry.d_name[i] == '\0') break; for(; i < FILENAME_LEN; ++i) curentry.d_name[i] = '\0'; if(nindex) curentry.d_ino = nindex->c_num; else curentry.d_ino = 0; /* If an existing slot is being used, we must back up the file offset */ if(udata.u_count){ udata.u_offset -= DIR_LEN; } udata.u_count = DIR_LEN; udata.u_base = (char*)&curentry; udata.u_sysio = true; writei(wd, 0); if(udata.u_error) return false; setftime(wd, A_TIME|M_TIME|C_TIME); /* Sets c_dirty */ /* Update file length to next block */ if(wd->c_node.i_size & BLKMASK) wd->c_node.i_size += BLKSIZE - (wd->c_node.i_size & BLKMASK); return true; // success }