- if (ops_to_mask & (*mode_string == '=' ? MODE_MASK_EQUALS
- : *mode_string == '+' ? MODE_MASK_PLUS
- : MODE_MASK_MINUS))
- affected_masked &= ~umask_value;
- change->affected = affected_masked;
- change->value = 0;
- change->flags = 0;
-
- /* Add the element to the tail of the list, so the operations
- are performed in the correct order. */
- mode_append_entry (&head, &tail, change);
-
- /* Set `value' according to the bits set in `affected_masked'. */
- for (++mode_string;; ++mode_string)
- switch (*mode_string)
- {
- case 'r':
- change->value |= 00444 & affected_masked;
- break;
- case 'w':
- change->value |= 00222 & affected_masked;
- break;
- case 'X':
- change->flags |= MODE_X_IF_ANY_X;
- /* Fall through. */
- case 'x':
- change->value |= 00111 & affected_masked;
- break;
- case 's':
- /* Set the setuid/gid bits if `u' or `g' is selected. */
- change->value |= 06000 & affected_masked;
- break;
- case 't':
- /* Set the "save text image" bit if `o' is selected. */
- change->value |= 01000 & affected_masked;
- break;
- case 'u':
- /* Set the affected bits to the value of the `u' bits
- on the same file. */
- if (change->value)
- goto invalid;
- change->value = 00700;
- change->flags |= MODE_COPY_EXISTING;
- break;
- case 'g':
- /* Set the affected bits to the value of the `g' bits
- on the same file. */
- if (change->value)
- goto invalid;
- change->value = 00070;
- change->flags |= MODE_COPY_EXISTING;
- break;
- case 'o':
- /* Set the affected bits to the value of the `o' bits
- on the same file. */
- if (change->value)
- goto invalid;
- change->value = 00007;
- change->flags |= MODE_COPY_EXISTING;
- break;
- default:
- goto no_more_values;
- }
- no_more_values:;
- }
- } while (*mode_string == ',');