119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * chattr.c		- Change file attributes on an ext2 file system
319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *
419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Copyright (C) 1993, 1994  Remy Card <card@masi.ibp.fr>
519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *                           Laboratoire MASI, Institut Blaise Pascal
619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *                           Universite Pierre et Marie Curie (Paris VI)
719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *
819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This file can be redistributed under the terms of the GNU General
919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Public License
1019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
1119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
1219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
1319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * History:
1419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 93/10/30	- Creation
1519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 93/11/13	- Replace stat() calls by lstat() to avoid loops
1619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 94/02/27	- Integrated in Ted's distribution
1719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 98/12/29	- Ignore symlinks when working recursively (G M Sipe)
1819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 98/12/29	- Display version info only when -V specified (G M Sipe)
1919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
2019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
2119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define _LARGEFILE64_SOURCE
2219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
2319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <sys/types.h>
2419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <dirent.h>
2519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <fcntl.h>
2619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdio.h>
2719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdlib.h>
2819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <unistd.h>
2919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <string.h>
3019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_ERRNO_H
3119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <errno.h>
3219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
3319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <sys/param.h>
3419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <sys/stat.h>
3519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "ext2fs/ext2_fs.h"
3619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
3719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef __GNUC__
3819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define EXT2FS_ATTR(x) __attribute__(x)
3919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#else
4019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define EXT2FS_ATTR(x)
4119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
4219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
4319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifndef S_ISLNK			/* So we can compile even with gcc-warn */
4419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project# ifdef __S_IFLNK
4519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#  define S_ISLNK(mode)	 __S_ISTYPE((mode), __S_IFLNK)
4619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project# else
4719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#  define S_ISLNK(mode)  0
4819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project# endif
4919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
5019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
5119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "et/com_err.h"
5219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "e2p/e2p.h"
5319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
5419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "../version.h"
5519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "nls-enable.h"
5619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
5719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic const char * program_name = "chattr";
5819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
5919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int add;
6019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int rem;
6119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int set;
6219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int set_version;
6319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
6419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic unsigned long version;
6519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
6619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int recursive;
6719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int verbose;
6819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
6919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic unsigned long af;
7019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic unsigned long rf;
7119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic unsigned long sf;
7219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
7319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef _LFS64_LARGEFILE
7419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define LSTAT		lstat64
7519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define STRUCT_STAT	struct stat64
7619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#else
7719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define LSTAT		lstat
7819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define STRUCT_STAT	struct stat
7919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
8019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
8119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void usage(void)
8219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
8319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	fprintf(stderr,
8419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		_("Usage: %s [-RV] [-+=AacDdijsSu] [-v version] files...\n"),
8519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		program_name);
8619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	exit(1);
8719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
8819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
8919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstruct flags_char {
9019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	unsigned long	flag;
9119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char 		optchar;
9219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project};
9319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
9419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic const struct flags_char flags_array[] = {
9519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{ EXT2_NOATIME_FL, 'A' },
9619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{ EXT2_SYNC_FL, 'S' },
9719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{ EXT2_DIRSYNC_FL, 'D' },
9819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{ EXT2_APPEND_FL, 'a' },
9919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{ EXT2_COMPR_FL, 'c' },
10019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{ EXT2_NODUMP_FL, 'd' },
10119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{ EXT2_IMMUTABLE_FL, 'i' },
10219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{ EXT3_JOURNAL_DATA_FL, 'j' },
10319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{ EXT2_SECRM_FL, 's' },
10419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{ EXT2_UNRM_FL, 'u' },
10519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{ EXT2_NOTAIL_FL, 't' },
10619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{ EXT2_TOPDIR_FL, 'T' },
10719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{ 0, 0 }
10819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project};
10919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
11019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic unsigned long get_flag(char c)
11119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
11219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	const struct flags_char *fp;
11319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
11419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	for (fp = flags_array; fp->flag != 0; fp++) {
11519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (fp->optchar == c)
11619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			return fp->flag;
11719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
11819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
11919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
12019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
12119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
12219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int decode_arg (int * i, int argc, char ** argv)
12319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
12419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char * p;
12519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char * tmp;
12619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	unsigned long fl;
12719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
12819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	switch (argv[*i][0])
12919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	{
13019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	case '-':
13119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		for (p = &argv[*i][1]; *p; p++) {
13219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (*p == 'R') {
13319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				recursive = 1;
13419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				continue;
13519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			}
13619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (*p == 'V') {
13719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				verbose = 1;
13819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				continue;
13919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			}
14019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (*p == 'v') {
14119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				(*i)++;
14219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				if (*i >= argc)
14319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project					usage ();
14419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				version = strtol (argv[*i], &tmp, 0);
14519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				if (*tmp) {
14619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project					com_err (program_name, 0,
14719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project						 _("bad version - %s\n"),
14819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project						 argv[*i]);
14919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project					usage ();
15019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				}
15119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				set_version = 1;
15219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				continue;
15319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			}
15419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if ((fl = get_flag(*p)) == 0)
15519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				usage();
15619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			rf |= fl;
15719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			rem = 1;
15819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
15919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		break;
16019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	case '+':
16119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		add = 1;
16219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		for (p = &argv[*i][1]; *p; p++) {
16319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if ((fl = get_flag(*p)) == 0)
16419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				usage();
16519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			af |= fl;
16619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
16719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		break;
16819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	case '=':
16919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		set = 1;
17019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		for (p = &argv[*i][1]; *p; p++) {
17119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if ((fl = get_flag(*p)) == 0)
17219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				usage();
17319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			sf |= fl;
17419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
17519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		break;
17619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	default:
17719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return EOF;
17819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		break;
17919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
18019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 1;
18119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
18219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
18319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int chattr_dir_proc (const char *, struct dirent *, void *);
18419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
18519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void change_attributes (const char * name)
18619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
18719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	unsigned long flags;
18819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	STRUCT_STAT	st;
18919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
19019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (LSTAT (name, &st) == -1) {
19119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		com_err (program_name, errno, _("while trying to stat %s"),
19219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			 name);
19319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return;
19419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
19519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (S_ISLNK(st.st_mode) && recursive)
19619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return;
19719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
19819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* Don't try to open device files, fifos etc.  We probably
19919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project           ought to display an error if the file was explicitly given
20019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project           on the command line (whether or not recursive was
20119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project           requested).  */
20219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode) &&
20319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    !S_ISDIR(st.st_mode))
20419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return;
20519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
20619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (set) {
20719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (verbose) {
20819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			printf (_("Flags of %s set as "), name);
20919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			print_flags (stdout, sf, 0);
21019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			printf ("\n");
21119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
21219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (fsetflags (name, sf) == -1)
21319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			perror (name);
21419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	} else {
21519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (fgetflags (name, &flags) == -1)
21619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			com_err (program_name, errno,
21719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			         _("while reading flags on %s"), name);
21819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		else {
21919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (rem)
22019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				flags &= ~rf;
22119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (add)
22219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				flags |= af;
22319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (verbose) {
22419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				printf (_("Flags of %s set as "), name);
22519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				print_flags (stdout, flags, 0);
22619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				printf ("\n");
22719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			}
22819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (!S_ISDIR(st.st_mode))
22919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				flags &= ~EXT2_DIRSYNC_FL;
23019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (fsetflags (name, flags) == -1)
23119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				com_err (program_name, errno,
23219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				         _("while setting flags on %s"), name);
23319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
23419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
23519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (set_version) {
23619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (verbose)
23719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			printf (_("Version of %s set as %lu\n"), name, version);
23819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (fsetversion (name, version) == -1)
23919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			com_err (program_name, errno,
24019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			         _("while setting version on %s"), name);
24119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
24219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (S_ISDIR(st.st_mode) && recursive)
24319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		iterate_on_dir (name, chattr_dir_proc, NULL);
24419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
24519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
24619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int chattr_dir_proc (const char * dir_name, struct dirent * de,
24719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			    void * private EXT2FS_ATTR((unused)))
24819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
24919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (strcmp (de->d_name, ".") && strcmp (de->d_name, "..")) {
25019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	        char *path;
25119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
25219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		path = malloc(strlen (dir_name) + 1 + strlen (de->d_name) + 1);
25319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (!path) {
25419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			fprintf(stderr, _("Couldn't allocate path variable "
25519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project					  "in chattr_dir_proc"));
25619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			exit(1);
25719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
25819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		sprintf (path, "%s/%s", dir_name, de->d_name);
25919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		change_attributes (path);
26019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		free(path);
26119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
26219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
26319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
26419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
26519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint main (int argc, char ** argv)
26619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
26719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int i, j;
26819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int end_arg = 0;
26919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
27019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef ENABLE_NLS
27119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	setlocale(LC_MESSAGES, "");
27219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	setlocale(LC_CTYPE, "");
27319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
27419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	textdomain(NLS_CAT_NAME);
27519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
27619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (argc && *argv)
27719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		program_name = *argv;
27819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	i = 1;
27919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	while (i < argc && !end_arg) {
28019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		/* '--' arg should end option processing */
28119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (strcmp(argv[i], "--") == 0) {
28219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			i++;
28319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			end_arg = 1;
28419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		} else if (decode_arg (&i, argc, argv) == EOF)
28519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			end_arg = 1;
28619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		else
28719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			i++;
28819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
28919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (i >= argc)
29019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		usage ();
29119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (set && (add || rem)) {
29219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fputs(_("= is incompatible with - and +\n"), stderr);
29319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		exit (1);
29419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
29519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if ((rf & af) != 0) {
29619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fputs("Can't both set and unset same flag.\n", stderr);
29719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		exit (1);
29819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
29919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!(add || rem || set || set_version)) {
30019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fputs(_("Must use '-v', =, - or +\n"), stderr);
30119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		exit (1);
30219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
30319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (verbose)
30419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fprintf (stderr, "chattr %s (%s)\n",
30519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			 E2FSPROGS_VERSION, E2FSPROGS_DATE);
30619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	for (j = i; j < argc; j++)
30719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		change_attributes (argv[j]);
30819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	exit(0);
30919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
310