• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/src/router/busybox-1.x/e2fsprogs/old_e2fsprogs/ext2fs/
1/* vi: set sw=4 ts=4: */
2/*
3 * dirblock.c --- directory block routines.
4 *
5 * Copyright (C) 1995, 1996 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#if HAVE_UNISTD_H
15#include <unistd.h>
16#endif
17#include <string.h>
18#include <time.h>
19
20#include "ext2_fs.h"
21#include "ext2fs.h"
22
23errcode_t ext2fs_read_dir_block2(ext2_filsys fs, blk_t block,
24				 void *buf, int flags EXT2FS_ATTR((unused)))
25{
26	errcode_t	retval;
27	char		*p, *end;
28	struct ext2_dir_entry *dirent;
29	unsigned int	name_len, rec_len;
30#if BB_BIG_ENDIAN
31	unsigned int do_swap;
32#endif
33
34	retval = io_channel_read_blk(fs->io, block, 1, buf);
35	if (retval)
36		return retval;
37#if BB_BIG_ENDIAN
38	do_swap = (fs->flags & (EXT2_FLAG_SWAP_BYTES|
39				EXT2_FLAG_SWAP_BYTES_READ)) != 0;
40#endif
41	p = (char *) buf;
42	end = (char *) buf + fs->blocksize;
43	while (p < end-8) {
44		dirent = (struct ext2_dir_entry *) p;
45#if BB_BIG_ENDIAN
46		if (do_swap) {
47			dirent->inode = ext2fs_swab32(dirent->inode);
48			dirent->rec_len = ext2fs_swab16(dirent->rec_len);
49			dirent->name_len = ext2fs_swab16(dirent->name_len);
50		}
51#endif
52		name_len = dirent->name_len;
53#ifdef WORDS_BIGENDIAN
54		if (flags & EXT2_DIRBLOCK_V2_STRUCT)
55			dirent->name_len = ext2fs_swab16(dirent->name_len);
56#endif
57		rec_len = dirent->rec_len;
58		if ((rec_len < 8) || (rec_len % 4)) {
59			rec_len = 8;
60			retval = EXT2_ET_DIR_CORRUPTED;
61		}
62		if (((name_len & 0xFF) + 8) > dirent->rec_len)
63			retval = EXT2_ET_DIR_CORRUPTED;
64		p += rec_len;
65	}
66	return retval;
67}
68
69errcode_t ext2fs_read_dir_block(ext2_filsys fs, blk_t block,
70				 void *buf)
71{
72	return ext2fs_read_dir_block2(fs, block, buf, 0);
73}
74
75
76errcode_t ext2fs_write_dir_block2(ext2_filsys fs, blk_t block,
77				  void *inbuf, int flags EXT2FS_ATTR((unused)))
78{
79#if BB_BIG_ENDIAN
80	int		do_swap = 0;
81	errcode_t	retval;
82	char		*p, *end;
83	char		*buf = 0;
84	struct ext2_dir_entry *dirent;
85
86	if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
87	    (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE))
88		do_swap = 1;
89
90#ifndef WORDS_BIGENDIAN
91	if (!do_swap)
92		return io_channel_write_blk(fs->io, block, 1, (char *) inbuf);
93#endif
94
95	retval = ext2fs_get_mem(fs->blocksize, &buf);
96	if (retval)
97		return retval;
98	memcpy(buf, inbuf, fs->blocksize);
99	p = buf;
100	end = buf + fs->blocksize;
101	while (p < end) {
102		dirent = (struct ext2_dir_entry *) p;
103		if ((dirent->rec_len < 8) ||
104		    (dirent->rec_len % 4)) {
105			ext2fs_free_mem(&buf);
106			return EXT2_ET_DIR_CORRUPTED;
107		}
108		p += dirent->rec_len;
109		if (do_swap) {
110			dirent->inode = ext2fs_swab32(dirent->inode);
111			dirent->rec_len = ext2fs_swab16(dirent->rec_len);
112			dirent->name_len = ext2fs_swab16(dirent->name_len);
113		}
114#ifdef WORDS_BIGENDIAN
115		if (flags & EXT2_DIRBLOCK_V2_STRUCT)
116			dirent->name_len = ext2fs_swab16(dirent->name_len);
117#endif
118	}
119	retval = io_channel_write_blk(fs->io, block, 1, buf);
120	ext2fs_free_mem(&buf);
121	return retval;
122#else
123	return io_channel_write_blk(fs->io, block, 1, (char *) inbuf);
124#endif
125}
126
127
128errcode_t ext2fs_write_dir_block(ext2_filsys fs, blk_t block,
129				 void *inbuf)
130{
131	return ext2fs_write_dir_block2(fs, block, inbuf, 0);
132}
133