xref: /haiku/src/bin/rmattr.cpp (revision 58481f0f6ef1a61ba07283f012cafbc2ed874ead)
1 /*
2  * Copyright 2001-2006, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Jérôme Duval, jerome.duval@free.fr
7  *		Axel Dörfler, axeld@pinc-software.de
8  */
9 
10 /*! Remove an attribute from a file */
11 
12 #include <fs_attr.h>
13 
14 #include <errno.h>
15 #include <fcntl.h>
16 #include <glob.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <unistd.h>
21 
22 
23 extern const char *__progname;
24 const char *kProgramName = __progname;
25 
26 int gCurrentFile;
27 
28 
29 void
30 usage()
31 {
32 	printf("usage: %s [-p] attr filename1 [filename2...]\n"
33 		"\t'attr' is the name of an attribute of the file\n"
34 		"\tIf '-p' is specified, 'attr' is regarded as a pattern.\n", kProgramName);
35 
36 	exit(1);
37 }
38 
39 
40 void *
41 open_attr_dir(const char* /*path*/)
42 {
43 	return fs_fopen_attr_dir(gCurrentFile);
44 }
45 
46 
47 int
48 stat_attr(const char* /*attribute*/, struct stat* stat)
49 {
50 	memset(stat, 0, sizeof(struct stat));
51 	stat->st_mode = S_IFREG;
52 	return 0;
53 }
54 
55 
56 int
57 remove_attribute(int fd, const char* attribute, bool isPattern)
58 {
59 	if (!isPattern)
60 		return fs_remove_attr(fd, attribute);
61 
62 	glob_t glob;
63 	memset(&glob, 0, sizeof(glob_t));
64 
65 	glob.gl_closedir = (void (*)(void *))fs_close_attr_dir;
66 	glob.gl_readdir = (dirent* (*)(void*))fs_read_attr_dir;
67 	glob.gl_opendir = open_attr_dir;
68 	glob.gl_lstat = stat_attr;
69 	glob.gl_stat = stat_attr;
70 
71 	// for open_attr_dir():
72 	gCurrentFile = fd;
73 
74 	int result = ::glob(attribute, GLOB_ALTDIRFUNC, NULL, &glob);
75 	if (result < 0) {
76 		errno = B_BAD_VALUE;
77 		return -1;
78 	}
79 
80 	bool error = false;
81 
82 	for (int i = 0; i < glob.gl_pathc; i++) {
83 		if (fs_remove_attr(fd, glob.gl_pathv[i]) != 0)
84 			error = true;
85 	}
86 
87 	return error ? -1 : 0;
88 }
89 
90 
91 int
92 main(int argc, const char **argv)
93 {
94 	// Make sure we have the minimum number of arguments.
95 	if (argc < 3)
96 		usage();
97 
98 	bool isPattern = false;
99 	int attr = 1;
100 	if (!strcmp(argv[attr], "-p")) {
101 		isPattern = true;
102 		attr++;
103 
104 		if (argc < 4)
105 			usage();
106 	}
107 
108 	for (int32 i = attr + 1; i < argc; i++) {
109 		int fd = open(argv[i], O_WRONLY);
110 		if (fd < 0) {
111 			fprintf(stderr, "%s: can\'t open file %s to remove attribute: %s\n",
112 				kProgramName, argv[i], strerror(errno));
113 			return 1;
114 		}
115 
116 		if (remove_attribute(fd, argv[attr], isPattern) != B_OK) {
117 			fprintf(stderr, "%s: error removing attribute %s from %s: %s\n",
118 				kProgramName, argv[attr], argv[i], strerror(errno));
119 		}
120 
121 		close(fd);
122 	}
123 
124 	return 0;
125 }
126