multiple: Fixed error string order
[mutos-utils.git] / chown.c
blob99a525940bae278708c9c30eb4259729958a6749
1 /*
2 Copyright © 2013 Alastair Stuart
4 This program is open source software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
15 #include <stdio.h>
16 #include <errno.h>
17 #include <string.h>
19 #include <pwd.h>
20 #include <grp.h>
21 #include <unistd.h>
23 #define VERSION "0.01"
25 int main(int argc, char* argv[])
27 if (argc == 1) {
28 fprintf(stderr, "%s: missing operand\n"
29 "Run '%s --help' for usage.\n",
30 argv[0], argv[0]);
31 return 1;
34 // flag parsing
35 int arg = 0;
36 for (arg = 1; arg < argc; arg++)
38 if (strcmp(argv[arg], "--help") == 0) {
39 printf("Usage: %s [owner][:group] [file ...]\n", argv[0]);
40 return 0;
41 } else if (strcmp(argv[arg], "--version") == 0) {
42 printf("chown (mutos) v"VERSION"\n");
43 return 0;
44 } else {
45 break;
49 int colon_index = -1;
50 for (size_t i = 0; i < strlen(argv[arg]); i++)
52 if (argv[arg][i] == ':') {
53 colon_index = i;
54 break;
58 struct passwd *user = NULL;
59 struct group *group = NULL;
61 char* username = NULL;
62 char* groupname = NULL;
64 if (colon_index == -1) {
65 user = getpwnam(argv[arg]);
66 username = argv[arg];
67 } else {
68 username = strndup(argv[arg], colon_index);
69 groupname = strndup(argv[arg] + colon_index + 1, strlen(argv[arg] - colon_index - 1));
71 user = getpwnam(username);
72 group = getgrnam(groupname);
75 if (!user) {
76 fprintf(stderr, "%s: invalid user: '%s'\n",
77 argv[0], username);
78 return 1;
81 if (!group && groupname) {
82 fprintf(stderr, "%s: invalid group: '%s'\n",
83 argv[0], groupname);
84 return 1;
87 arg++; // go to next arg
89 if (argc - arg < 1) {
90 fprintf(stderr, "%s: No file specified\n", argv[0]);
91 return 1;
94 for ( ; arg < argc; arg++)
96 int rc = chown(argv[arg], user->pw_uid, group ? group->gr_gid : (gid_t) -1);
97 if (rc == -1) {
98 fprintf(stderr, "%s: %s: %s\n", argv[0], strerror(errno), argv[arg]);
99 return 1;
103 return 0;