} while (0)
#define LF3_DEBUG_B(x) LF3_DEBUG("%s = %s\n", #x, (x) ? "true" : "false")
+#define LF3_DEBUG_C(x) LF3_DEBUG("%s = %c\n", #x, (x))
#define LF3_DEBUG_D(x) LF3_DEBUG("%s = %"PRIdMAX"\n", #x, (intmax_t)(x))
+#define LF3_DEBUG_O(x) LF3_DEBUG("%s = %"PRIoMAX"\n", #x, (intmax_t)(x))
#define LF3_DEBUG_P(x) LF3_DEBUG("%s = %p\n", #x, x)
#define LF3_DEBUG_S(x) LF3_DEBUG("%s = '%s'\n", #x, x)
#define LF3_DEBUG_U(x) LF3_DEBUG("%s = %"PRIuMAX"\n", #x, (uintmax_t)(x))
return xsprintf("(%c (%s) %llu)", cmp, thunk, val);
}
+static int lf3_parse_perm1(const char *t, mode_t *mode)
+{
+ /* Parse [ugoa]+[+=-][rwx]+ */
+ mode_t ugo = 0, rwx = 0;
+ int opc = '\0';
+
+ LF3_DEBUG_S(t);
+
+ /* TODO Xst */
+
+ for (; *t != '\0' && opc == '\0'; t++) {
+ switch (*t) {
+ case 'u':
+ ugo |= S_IRWXU;
+ break;
+ case 'g':
+ ugo |= S_IRWXG;
+ break;
+ case 'o':
+ ugo |= S_IRWXO;
+ break;
+ case 'a':
+ ugo |= S_IRWXU | S_IRWXG | S_IRWXO;
+ break;
+ case '+':
+ case '-':
+ case '=':
+ opc = *t;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+
+ if (ugo == 0 || opc == '\0')
+ return -EINVAL;
+
+ LF3_DEBUG_S(t);
+
+ for (; *t != '\0'; t++) {
+ switch (*t) {
+ case 'r':
+ rwx |= S_IRUSR | S_IRGRP | S_IROTH;
+ break;
+ case 'w':
+ rwx |= S_IWUSR | S_IWGRP | S_IWOTH;
+ break;
+ case 'x':
+ rwx |= S_IXUSR | S_IXGRP | S_IXOTH;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+
+ LF3_DEBUG_O(ugo);
+ LF3_DEBUG_O(rwx);
+ LF3_DEBUG_C(opc);
+
+ switch (opc) {
+ case '+':
+ *mode |= (ugo & rwx);
+ break;
+ case '-':
+ *mode &= ~(ugo & rwx);
+ break;
+ case '=':
+ *mode &= ~ugo;
+ *mode |= (ugo & rwx);
+ break;
+ }
+
+ LF3_DEBUG_O(*mode);
+
+ return 0;
+}
+
+static int lf3_parse_perm(const char *str, mode_t *mode)
+{
+ /* Parse "0644" or "([ugoa][+=][rwx]+),(...),..." */
+
+ char *end = NULL;
+ char *str1 = NULL, *s, *t;
+ int rc;
+
+ if (isdigit(*str)) {
+ errno = 0;
+ *mode = strtoul(str, &end, 8);
+ rc = (errno == 0 && *end == '\0') ? 0 : -EINVAL;
+ goto out;
+ }
+
+ *mode = 0;
+
+ s = str1 = xstrdup(str);
+
+ while ((t = strsep(&s, ",")) != NULL) {
+ rc = lf3_parse_perm1(t, mode);
+ if (rc < 0)
+ goto out;
+ }
+
+ rc = 0;
+out:
+ free(str1);
+
+ return rc;
+}
+
+static char *lf3_perm_expr(int begin, int end)
+{
+ const char *mode_str = lf3_arg[begin + 1];
+ mode_t mode = 0;
+ enum {
+ PERM_MATCH_EQ,
+ PERM_MATCH_ALL,
+ PERM_MATCH_ANY,
+ } match;
+ int rc;
+
+ assert(begin + 2 == end);
+
+ /* -perm mode : File's permission bits are exactly mode (octal or symbolic)
+ * -perm -mode : All of the permission bits mode are set for the file
+ * -perm /mode : Any of the permission bits mode are set for the file */
+
+ switch (mode_str[0]) {
+ default:
+ match = PERM_MATCH_EQ;
+ break;
+ case '-':
+ match = PERM_MATCH_ALL;
+ mode_str++;
+ break;
+ case '/':
+ match = PERM_MATCH_ANY;
+ mode_str++;
+ break;
+ }
+
+ enum {
+ PERM_MASK = S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO,
+ };
+
+ rc = lf3_parse_perm(mode_str, &mode);
+ if (rc < 0)
+ LF3_FATAL_AT(begin + 1, "invalid mode '%s'\n", lf3_arg[begin + 1]);
+
+ switch (match) {
+ case PERM_MATCH_EQ:
+ return xsprintf("(= (logand (mode) %llu) %llu)", (__ull)PERM_MASK, (__ull)mode);
+ case PERM_MATCH_ALL:
+ return xsprintf("(= (logand (mode) %llu) %llu)", (__ull)mode, (__ull)mode);
+ case PERM_MATCH_ANY:
+ return xsprintf("(not (= (logand (mode) %llu) 0))", (__ull)mode);
+ default:
+ abort(); /* I <3 GCC! */
+ }
+}
+
static char *lf3_type_expr(int begin, int end)
{
const char *type_str = lf3_arg[begin + 1];
X1(size);
X1(type);
X1(exec);
- // X1(perm); TODO
+ X1(perm);
// X1(used); TODO
X1(print);
X1(print0);
declare -a MODES=(0 1 0111 0222 0444 0555 0666 0777)
test_101() {
- # TODO
- true
+ local facet=mds1
+ local device="$(facet_device $facet)"
+ local file=$MOUNT/$tfile
+ local fid
+
+ init_lipe_find3_env "$file"
+ fid=$($LFS path2fid "$file")
+ chmod 0666 "$file"
+
+ expect1 "$fid" lipe_find3_facet mds1 -perm 0666
+ expect1 "$fid" lipe_find3_facet mds1 -perm -0666
+ expect1 "$fid" lipe_find3_facet mds1 -perm -0600
+ expect1 "$fid" lipe_find3_facet mds1 -perm -0060
+ expect1 "$fid" lipe_find3_facet mds1 -perm -0400
+ expect1 "$fid" lipe_find3_facet mds1 -perm /0777
+ expect1 "$fid" lipe_find3_facet mds1 -perm /0477
+
+ expect_empty lipe_find3_facet mds1 -perm 0777
+ expect_empty lipe_find3_facet mds1 -perm 0667
+ expect_empty lipe_find3_facet mds1 -perm 0700
+ expect_empty lipe_find3_facet mds1 -perm /0100
+ expect_empty lipe_find3_facet mds1 -perm /0111
+
+ expect1 "$fid" lipe_find3_facet mds1 -perm ugo=rw
+ expect1 "$fid" lipe_find3_facet mds1 -perm -ugo=rw
+ expect1 "$fid" lipe_find3_facet mds1 -perm -ug=rw
+ expect1 "$fid" lipe_find3_facet mds1 -perm -u=rw
+ expect1 "$fid" lipe_find3_facet mds1 -perm -ugo=r
+ expect1 "$fid" lipe_find3_facet mds1 -perm -ugo=w
+
+ expect_empty lipe_find3_facet mds1 -perm ugo=rwx
+ expect_empty lipe_find3_facet mds1 -perm ug=wx,o=rwx
+ expect_empty lipe_find3_facet mds1 -perm u=rwx
+ expect_empty lipe_find3_facet mds1 -perm u=x
+ expect_empty lipe_find3_facet mds1 -perm ugo=rwx
+
+ chmod 0001 "$file"
+ expect1 "$fid" lipe_find3_facet mds1 -perm 0001
+ expect1 "$fid" lipe_find3_facet mds1 -perm o=x
+ expect1 "$fid" lipe_find3_facet mds1 -perm -o=x
+ expect1 "$fid" lipe_find3_facet mds1 -perm /a=x
+ expect_empty lipe_find3_facet mds1 -perm 0
+ expect_empty lipe_find3_facet mds1 -perm 0000
+ expect_empty lipe_find3_facet mds1 -perm u=x
+ expect_empty lipe_find3_facet mds1 -perm -u=x
+ expect_empty lipe_find3_facet mds1 -perm /u=x
+ expect_empty lipe_find3_facet mds1 -perm ugo=
+
+ chmod 0000 "$file"
+ expect1 "$fid" lipe_find3_facet mds1 -perm 0000
+ expect1 "$fid" lipe_find3_facet mds1 -perm ugo=
+ expect_empty lipe_find3_facet mds1 -perm -o=x
+ expect_empty lipe_find3_facet mds1 -perm /a=x
+
+ # ...
+ expect_error lipe_find3_facet mds1 -perm 0q
+ expect_error lipe_find3_facet mds1 -perm 9
+ expect_error lipe_find3_facet mds1 -perm k=rxw
+ expect_error lipe_find3_facet mds1 -perm u@rwx
+ expect_error lipe_find3_facet mds1 -perm u=rwq
+ expect_error lipe_find3_facet mds1 -perm u=q
+ expect_error lipe_find3_facet mds1 -perm ugk=r
+ expect_error lipe_find3_facet mds1 -perm =
+ expect_error lipe_find3_facet mds1 -perm =r
+ expect_error lipe_find3_facet mds1 -perm ''
+ expect_error lipe_find3_facet mds1 -perm
}
run_test 101 "lipe_find3 perm does the right thing"