Rizin
unix-like reverse engineering framework and cli tools
chmod.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2011-2019 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_util.h>
5 #include <stdbool.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <sys/stat.h>
9 
10 #if __UNIX__
11 static bool chmodr(const char *, int recursive);
12 static bool parsemode(const char *);
13 static void recurse(const char *path, int rec, bool (*fn)(const char *, int));
14 
15 static char oper = '=';
16 static mode_t mode = 0;
17 #endif
18 
19 RZ_API bool rz_file_chmod(const char *file, const char *mod, int recursive) {
20 #if __UNIX__
21  oper = '=';
22  mode = 0;
23  if (!parsemode(mod)) {
24  return false;
25  }
26  return chmodr(file, recursive);
27 #else
28  return false;
29 #endif
30 }
31 
32 #if __UNIX__
33 /* copied from sbase/chmod.c (suckless.org) */
34 static bool chmodr(const char *path, int rflag) {
35  struct stat st;
36 
37  if (stat(path, &st) == -1) {
38  return false;
39  }
40 
41  switch (oper) {
42  case '+':
43  st.st_mode |= mode;
44  break;
45  case '-':
46  st.st_mode &= ~mode;
47  break;
48  case '=':
49  st.st_mode = mode;
50  break;
51  }
52  if (chmod(path, st.st_mode) == -1) {
53  eprintf("chmod %s:", path);
54  return false;
55  }
56  if (rflag) {
57  recurse(path, rflag, chmodr);
58  }
59  return true;
60 }
61 
62 static bool parsemode(const char *str) {
63  char *end;
64  const char *p;
65  int octal;
66  mode_t mask = 0;
67 
68  octal = strtol(str, &end, 8);
69  if (*end == '\0') {
70  if (octal & 04000) {
71  mode |= S_ISUID;
72  }
73  if (octal & 02000) {
74  mode |= S_ISGID;
75  }
76  if (octal & 00400) {
77  mode |= S_IRUSR;
78  }
79  if (octal & 00200) {
80  mode |= S_IWUSR;
81  }
82  if (octal & 00100) {
83  mode |= S_IXUSR;
84  }
85  if (octal & 00040) {
86  mode |= S_IRGRP;
87  }
88  if (octal & 00020) {
89  mode |= S_IWGRP;
90  }
91  if (octal & 00010) {
92  mode |= S_IXGRP;
93  }
94  if (octal & 00004) {
95  mode |= S_IROTH;
96  }
97  if (octal & 00002) {
98  mode |= S_IWOTH;
99  }
100  if (octal & 00001) {
101  mode |= S_IXOTH;
102  }
103  return true;
104  }
105  for (p = str; *p; p++) {
106  switch (*p) {
107  /* masks */
108  case 'u':
109  mask |= S_IRWXU;
110  break;
111  case 'g':
112  mask |= S_IRWXG;
113  break;
114  case 'o':
115  mask |= S_IRWXO;
116  break;
117  case 'a':
118  mask |= S_IRWXU | S_IRWXG | S_IRWXO;
119  break;
120  /* opers */
121  case '+':
122  case '-':
123  case '=':
124  oper = *p;
125  break;
126  /* modes */
127  case 'r':
128  mode |= S_IRUSR | S_IRGRP | S_IROTH;
129  break;
130  case 'w':
131  mode |= S_IWUSR | S_IWGRP | S_IWOTH;
132  break;
133  case 'x':
134  mode |= S_IXUSR | S_IXGRP | S_IXOTH;
135  break;
136  case 's':
137  mode |= S_ISUID | S_ISGID;
138  break;
139  /* error */
140  default:
141  eprintf("%s: invalid mode\n", str);
142  return false;
143  }
144  }
145  if (mask) {
146  mode &= mask;
147  }
148  return true;
149 }
150 
151 static char *agetcwd(void) {
152  char *buf = malloc(4096);
153  if (!buf) {
154  return NULL;
155  }
156  if (!getcwd(buf, 4096)) {
157  eprintf("getcwd:");
158  }
159  return buf;
160 }
161 
162 static void recurse(const char *path, int rec, bool (*fn)(const char *, int)) {
163  char *cwd;
164  struct dirent *d;
165  struct stat st;
166  DIR *dp;
167 
168  if (lstat(path, &st) == -1 || !S_ISDIR(st.st_mode)) {
169  return;
170  } else if (!(dp = opendir(path))) {
171  eprintf("opendir %s:", path);
172  return;
173  }
174  cwd = agetcwd();
175  if (chdir(path) == -1) {
176  eprintf("chdir %s:", path);
177  closedir(dp);
178  free(cwd);
179  return;
180  }
181  while ((d = readdir(dp))) {
182  if (strcmp(d->d_name, ".") && strcmp(d->d_name, "..")) {
183  fn(d->d_name, 1);
184  }
185  }
186 
187  closedir(dp);
188  if (chdir(cwd) == -1) {
189  eprintf("chdir %s:", cwd);
190  }
191  free(cwd);
192 }
193 #endif
#define mask()
static RzList * recurse(RzCore *core, RzAnalysisBlock *from, RzAnalysisBlock *dest)
Definition: canalysis.c:2683
RZ_API bool rz_file_chmod(const char *file, const char *mod, int recursive)
Definition: chmod.c:19
#define S_ISDIR(mode)
Definition: compat.h:187
#define RZ_API
#define NULL
Definition: cris-opc.c:27
int mod(int a, int b)
Definition: crypto_rot.c:8
static static fork const void static count static fd const char const char static newpath const char static path const char path
Definition: sflib.h:35
static static fork const void static count static fd const char const char static newpath chdir
Definition: sflib.h:33
static static fork const void static count static fd const char const char static newpath const char static path chmod
Definition: sflib.h:35
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
const char int mode
Definition: ioapi.h:137
voidpf void * buf
Definition: ioapi.h:138
void * p
Definition: libc.cpp:67
void * malloc(size_t size)
Definition: malloc.c:123
static stat
Definition: sflib.h:131
static const char struct stat static buf struct stat static buf static idle const char static path static fd const char static len const void static prot const char struct module static image struct kernel_sym static table unsigned char static buf static fsuid unsigned struct dirent unsigned static count const struct iovec static count static pid const void static len static flags const struct sched_param static p static pid static policy struct timespec static tp static suid unsigned fn
Definition: sflib.h:186
static static fork const void static count static fd const char static mode const char static pathname const char static path const char static dev const char static group static getpid static getuid void void static data static pause const char static mode static sync const char const char static newpath const char static pathname unsigned long static filedes void static end_data_segment static handler static getegid char static len static pgid const char static path static newfd static getpgrp static euid const sigset_t static mask const char static len const gid_t static list const char const char static newpath const char static library readdir
Definition: sflib.h:120
#define eprintf(x, y...)
Definition: rlcc.c:7
int mode_t
Definition: sftypes.h:42
#define d(i)
Definition: sha256.c:44
Definition: sftypes.h:48
Definition: gzappend.c:170
Definition: sftypes.h:80