dirblock.c revision bfcd9a116ff3bcc6d94a616ab1444eb38d0d5434
1/* 2 * dirblock.c --- directory block routines. 3 * 4 * Copyright (C) 1995, 1996 Theodore Ts'o. 5 * 6 * %Begin-Header% 7 * This file may be redistributed under the terms of the GNU Public 8 * License. 9 * %End-Header% 10 */ 11 12#include <stdio.h> 13#if HAVE_UNISTD_H 14#include <unistd.h> 15#endif 16#include <string.h> 17#include <time.h> 18 19#if EXT2_FLAT_INCLUDES 20#include "ext2_fs.h" 21#else 22#include <linux/ext2_fs.h> 23#endif 24 25#include "ext2fs.h" 26 27errcode_t ext2fs_read_dir_block(ext2_filsys fs, blk_t block, 28 void *buf) 29{ 30 errcode_t retval; 31 char *p, *end; 32 struct ext2_dir_entry *dirent; 33 struct ext2_dir_entry_2 *dirent2; 34 unsigned int rec_len, do_swap; 35 36 retval = io_channel_read_blk(fs->io, block, 1, buf); 37 if (retval) 38 return retval; 39 do_swap = (fs->flags & (EXT2_FLAG_SWAP_BYTES| 40 EXT2_FLAG_SWAP_BYTES_READ)) != 0; 41 p = (char *) buf; 42 end = (char *) buf + fs->blocksize; 43 while (p < end-8) { 44 dirent = (struct ext2_dir_entry *) p; 45 if (do_swap) { 46 dirent->inode = ext2fs_swab32(dirent->inode); 47 dirent->rec_len = ext2fs_swab16(dirent->rec_len); 48 dirent->name_len = ext2fs_swab16(dirent->name_len); 49 } 50 rec_len = dirent->rec_len; 51 if ((rec_len < 8) || (rec_len % 4)) { 52 rec_len = 8; 53 retval = EXT2_ET_DIR_CORRUPTED; 54 } 55 dirent2 = (struct ext2_dir_entry_2 *) dirent; 56 if ((dirent2->name_len +8) > dirent2->rec_len) 57 retval = EXT2_ET_DIR_CORRUPTED; 58 p += rec_len; 59 } 60 return retval; 61} 62 63errcode_t ext2fs_write_dir_block(ext2_filsys fs, blk_t block, 64 void *inbuf) 65{ 66 errcode_t retval; 67 char *p, *end, *write_buf; 68 char *buf = 0; 69 struct ext2_dir_entry *dirent; 70 71 if ((fs->flags & EXT2_FLAG_SWAP_BYTES) || 72 (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)) { 73 retval = ext2fs_get_mem(fs->blocksize, (void **) &buf); 74 if (retval) 75 return retval; 76 write_buf = buf; 77 memcpy(buf, inbuf, fs->blocksize); 78 p = buf; 79 end = buf + fs->blocksize; 80 while (p < end) { 81 dirent = (struct ext2_dir_entry *) p; 82 if ((dirent->rec_len < 8) || 83 (dirent->rec_len % 4)) { 84 retval = EXT2_ET_DIR_CORRUPTED; 85 goto errout; 86 } 87 p += dirent->rec_len; 88 dirent->inode = ext2fs_swab32(dirent->inode); 89 dirent->rec_len = ext2fs_swab16(dirent->rec_len); 90 dirent->name_len = ext2fs_swab16(dirent->name_len); 91 } 92 } else 93 write_buf = (char *) inbuf; 94 retval = io_channel_write_blk(fs->io, block, 1, write_buf); 95errout: 96 if (buf) 97 ext2fs_free_mem((void **) &buf); 98 return retval; 99} 100 101 102