xref: /haiku/src/bin/rmattr.cpp (revision 3db68fb0bb9efd3f5cd16cee6462f0e42766cd36)
179b25dd7SAxel Dörfler /*
2*3db68fb0SJérôme Duval  * Copyright 2001-2009, Haiku, Inc. All Rights Reserved.
379b25dd7SAxel Dörfler  * Distributed under the terms of the MIT License.
479b25dd7SAxel Dörfler  *
579b25dd7SAxel Dörfler  * Authors:
679b25dd7SAxel Dörfler  *		Jérôme Duval, jerome.duval@free.fr
779b25dd7SAxel Dörfler  *		Axel Dörfler, axeld@pinc-software.de
879b25dd7SAxel Dörfler  */
917049c45SAxel Dörfler 
1079b25dd7SAxel Dörfler /*! Remove an attribute from a file */
1179b25dd7SAxel Dörfler 
1279b25dd7SAxel Dörfler #include <fs_attr.h>
1379b25dd7SAxel Dörfler 
1479b25dd7SAxel Dörfler #include <errno.h>
1579b25dd7SAxel Dörfler #include <fcntl.h>
1679b25dd7SAxel Dörfler #include <glob.h>
1717049c45SAxel Dörfler #include <stdio.h>
18338b8dc3SIngo Weinhold #include <stdlib.h>
1979b25dd7SAxel Dörfler #include <string.h>
2079b25dd7SAxel Dörfler #include <unistd.h>
2117049c45SAxel Dörfler 
2279b25dd7SAxel Dörfler 
2379b25dd7SAxel Dörfler extern const char *__progname;
2479b25dd7SAxel Dörfler const char *kProgramName = __progname;
2579b25dd7SAxel Dörfler 
2679b25dd7SAxel Dörfler int gCurrentFile;
2779b25dd7SAxel Dörfler 
2879b25dd7SAxel Dörfler 
2979b25dd7SAxel Dörfler void
usage()3079b25dd7SAxel Dörfler usage()
3179b25dd7SAxel Dörfler {
32*3db68fb0SJérôme Duval 	printf("usage: %s [-P] [-p] attr filename1 [filename2...]\n"
3379b25dd7SAxel Dörfler 		"\t'attr' is the name of an attribute of the file\n"
34*3db68fb0SJérôme Duval 		"\t-P : Don't resolve links\n"
3579b25dd7SAxel Dörfler 		"\tIf '-p' is specified, 'attr' is regarded as a pattern.\n", kProgramName);
3679b25dd7SAxel Dörfler 
37383b5f43SJérôme Duval 	exit(1);
3879b25dd7SAxel Dörfler }
3979b25dd7SAxel Dörfler 
4079b25dd7SAxel Dörfler 
4179b25dd7SAxel Dörfler void *
open_attr_dir(const char *)4279b25dd7SAxel Dörfler open_attr_dir(const char* /*path*/)
4379b25dd7SAxel Dörfler {
4479b25dd7SAxel Dörfler 	return fs_fopen_attr_dir(gCurrentFile);
4579b25dd7SAxel Dörfler }
4679b25dd7SAxel Dörfler 
4779b25dd7SAxel Dörfler 
4879b25dd7SAxel Dörfler int
stat_attr(const char *,struct stat * stat)4979b25dd7SAxel Dörfler stat_attr(const char* /*attribute*/, struct stat* stat)
5079b25dd7SAxel Dörfler {
5179b25dd7SAxel Dörfler 	memset(stat, 0, sizeof(struct stat));
5279b25dd7SAxel Dörfler 	stat->st_mode = S_IFREG;
5379b25dd7SAxel Dörfler 	return 0;
5479b25dd7SAxel Dörfler }
5579b25dd7SAxel Dörfler 
5679b25dd7SAxel Dörfler 
5779b25dd7SAxel Dörfler int
remove_attribute(int fd,const char * attribute,bool isPattern)5879b25dd7SAxel Dörfler remove_attribute(int fd, const char* attribute, bool isPattern)
5979b25dd7SAxel Dörfler {
6079b25dd7SAxel Dörfler 	if (!isPattern)
6179b25dd7SAxel Dörfler 		return fs_remove_attr(fd, attribute);
6279b25dd7SAxel Dörfler 
6379b25dd7SAxel Dörfler 	glob_t glob;
6479b25dd7SAxel Dörfler 	memset(&glob, 0, sizeof(glob_t));
6579b25dd7SAxel Dörfler 
6679b25dd7SAxel Dörfler 	glob.gl_closedir = (void (*)(void *))fs_close_attr_dir;
676c05095cSIthamar R. Adema 	glob.gl_readdir = (dirent* (*)(void*))fs_read_attr_dir;
6879b25dd7SAxel Dörfler 	glob.gl_opendir = open_attr_dir;
6979b25dd7SAxel Dörfler 	glob.gl_lstat = stat_attr;
7079b25dd7SAxel Dörfler 	glob.gl_stat = stat_attr;
7179b25dd7SAxel Dörfler 
7279b25dd7SAxel Dörfler 	// for open_attr_dir():
7379b25dd7SAxel Dörfler 	gCurrentFile = fd;
7479b25dd7SAxel Dörfler 
7579b25dd7SAxel Dörfler 	int result = ::glob(attribute, GLOB_ALTDIRFUNC, NULL, &glob);
7679b25dd7SAxel Dörfler 	if (result < 0) {
7779b25dd7SAxel Dörfler 		errno = B_BAD_VALUE;
7879b25dd7SAxel Dörfler 		return -1;
7979b25dd7SAxel Dörfler 	}
8079b25dd7SAxel Dörfler 
8179b25dd7SAxel Dörfler 	bool error = false;
8279b25dd7SAxel Dörfler 
8379b25dd7SAxel Dörfler 	for (int i = 0; i < glob.gl_pathc; i++) {
8479b25dd7SAxel Dörfler 		if (fs_remove_attr(fd, glob.gl_pathv[i]) != 0)
8579b25dd7SAxel Dörfler 			error = true;
8679b25dd7SAxel Dörfler 	}
8779b25dd7SAxel Dörfler 
8879b25dd7SAxel Dörfler 	return error ? -1 : 0;
8979b25dd7SAxel Dörfler }
9079b25dd7SAxel Dörfler 
9179b25dd7SAxel Dörfler 
9279b25dd7SAxel Dörfler int
main(int argc,const char ** argv)9306447030SMichael Lotz main(int argc, const char **argv)
9417049c45SAxel Dörfler {
9579b25dd7SAxel Dörfler 	bool isPattern = false;
96*3db68fb0SJérôme Duval 	bool resolveLinks = true;
9779b25dd7SAxel Dörfler 
98*3db68fb0SJérôme Duval 	/* get all options */
99*3db68fb0SJérôme Duval 
100*3db68fb0SJérôme Duval 	while (*++argv) {
101*3db68fb0SJérôme Duval 		const char *arg = *argv;
102*3db68fb0SJérôme Duval 		argc--;
103*3db68fb0SJérôme Duval 		if (*arg != '-')
104*3db68fb0SJérôme Duval 			break;
105*3db68fb0SJérôme Duval 		if (!strcmp(arg, "-P"))
106*3db68fb0SJérôme Duval 			resolveLinks = false;
107*3db68fb0SJérôme Duval 		else if (!strcmp(arg, "-p"))
108*3db68fb0SJérôme Duval 			isPattern = true;
10917049c45SAxel Dörfler 	}
11017049c45SAxel Dörfler 
111*3db68fb0SJérôme Duval 	// Make sure we have the minimum number of arguments.
112*3db68fb0SJérôme Duval 	if (argc < 2)
113*3db68fb0SJérôme Duval 		usage();
114*3db68fb0SJérôme Duval 
115*3db68fb0SJérôme Duval 	for (int32 i = 1; i < argc; i++) {
116*3db68fb0SJérôme Duval 		int fd = open(argv[i], O_RDONLY | (resolveLinks ? 0 : O_NOTRAVERSE));
11717049c45SAxel Dörfler 		if (fd < 0) {
11879b25dd7SAxel Dörfler 			fprintf(stderr, "%s: can\'t open file %s to remove attribute: %s\n",
11979b25dd7SAxel Dörfler 				kProgramName, argv[i], strerror(errno));
120383b5f43SJérôme Duval 			return 1;
12117049c45SAxel Dörfler 		}
12217049c45SAxel Dörfler 
123*3db68fb0SJérôme Duval 		if (remove_attribute(fd, argv[0], isPattern) != B_OK) {
12479b25dd7SAxel Dörfler 			fprintf(stderr, "%s: error removing attribute %s from %s: %s\n",
125*3db68fb0SJérôme Duval 				kProgramName, argv[0], argv[i], strerror(errno));
12617049c45SAxel Dörfler 		}
12717049c45SAxel Dörfler 
12879b25dd7SAxel Dörfler 		close(fd);
12979b25dd7SAxel Dörfler 	}
13079b25dd7SAxel Dörfler 
13179b25dd7SAxel Dörfler 	return 0;
13217049c45SAxel Dörfler }
133