2 * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
19 #include <RegistrarDefs.h>
20 #include <user_group.h>
21 #include <util/KMessage.h>
23 #include "multiuser_utils.h"
26 extern const char *__progname
;
29 static const char* kUsage
=
30 "Usage: %s [ <options> ] <group name>\n"
31 "Creates a new group <group name>.\n"
34 " -A, --add-user <user>\n"
35 " Add the user <user> to the group.\n"
37 " Print usage info.\n"
38 " -R, --remove-user <user>\n"
39 " Remove the user <user> from the group.\n"
43 print_usage_and_exit(bool error
)
45 fprintf(error
? stderr
: stdout
, kUsage
, __progname
);
51 main(int argc
, const char* const* argv
)
53 typedef std::set
<std::string
> StringSet
;
56 StringSet usersToRemove
;
59 static struct option sLongOptions
[] = {
60 { "add-user", required_argument
, 0, 'A' },
61 { "help", no_argument
, 0, 'h' },
62 { "remove-user", required_argument
, 0, 'A' },
66 opterr
= 0; // don't print errors
67 int c
= getopt_long(argc
, (char**)argv
, "A:hR:", sLongOptions
, NULL
);
74 usersToAdd
.insert(optarg
);
78 print_usage_and_exit(false);
82 usersToRemove
.insert(optarg
);
86 print_usage_and_exit(true);
91 if (optind
!= argc
- 1)
92 print_usage_and_exit(true);
94 const char* group
= argv
[optind
];
97 fprintf(stderr
, "Error: Only root may modify groups.\n");
102 struct group
* groupInfo
= getgrnam(group
);
103 if (groupInfo
== NULL
) {
104 fprintf(stderr
, "Error: Group \"%s\" doesn't exist.\n", group
);
108 // check, if anything needs to be done
109 if (usersToAdd
.empty() && usersToRemove
.empty()) {
110 fprintf(stderr
, "Error: No modification specified.\n");
114 // prepare request for the registrar
115 KMessage
message(BPrivate::B_REG_UPDATE_GROUP
);
116 if (message
.AddInt32("gid", groupInfo
->gr_gid
) != B_OK
117 || message
.AddString("name", group
) != B_OK
118 || message
.AddString("password", groupInfo
->gr_passwd
) != B_OK
119 || message
.AddBool("add group", false) != B_OK
) {
120 fprintf(stderr
, "Error: Out of memory!\n");
124 for (int32 i
= 0; const char* user
= groupInfo
->gr_mem
[i
]; i
++) {
125 if (usersToRemove
.erase(user
) > 0)
128 usersToAdd
.insert(user
);
131 if (!usersToRemove
.empty()) {
132 fprintf(stderr
, "Error: \"%s\" is not a member of group \"%s\"\n",
133 usersToRemove
.begin()->c_str(), group
);
137 // If the group doesn't have any more members, insert an empty string as an
138 // indicator for the registrar to remove all members.
139 if (usersToAdd
.empty())
140 usersToAdd
.insert("");
142 for (StringSet::const_iterator it
= usersToAdd
.begin();
143 it
!= usersToAdd
.end(); ++it
) {
144 if (message
.AddString("members", it
->c_str()) != B_OK
) {
145 fprintf(stderr
, "Error: Out of memory!\n");
152 status_t error
= send_authentication_request_to_registrar(message
, reply
);
154 fprintf(stderr
, "Error: Failed to create group: %s\n", strerror(error
));