639 |
} |
} |
640 |
|
|
641 |
static bool ccs_print_name_union(struct ccs_io_buffer *head, |
static bool ccs_print_name_union(struct ccs_io_buffer *head, |
642 |
struct ccs_name_union *ptr) |
const struct ccs_name_union *ptr) |
643 |
{ |
{ |
644 |
const int pos = head->read_avail; |
int pos = head->read_avail; |
645 |
if (pos && head->read_buf[pos - 1] == ' ') |
if (pos && head->read_buf[pos - 1] == ' ') |
646 |
head->read_avail--; |
head->read_avail--; |
647 |
if (ptr->is_group) |
if (ptr->is_group) |
650 |
return ccs_io_printf(head, " %s", ptr->filename->name); |
return ccs_io_printf(head, " %s", ptr->filename->name); |
651 |
} |
} |
652 |
|
|
653 |
static bool ccs_print_number_union(struct ccs_io_buffer *head, |
static bool ccs_print_name_union_quoted(struct ccs_io_buffer *head, |
654 |
struct ccs_number_union *ptr) |
const struct ccs_name_union *ptr) |
655 |
|
{ |
656 |
|
if (ptr->is_group) |
657 |
|
return ccs_io_printf(head, "@%s", |
658 |
|
ptr->group->group_name->name); |
659 |
|
return ccs_io_printf(head, "\"%s\"", ptr->filename->name); |
660 |
|
} |
661 |
|
|
662 |
|
static bool ccs_print_number_union_common(struct ccs_io_buffer *head, |
663 |
|
const struct ccs_number_union *ptr, |
664 |
|
const bool need_space) |
665 |
{ |
{ |
666 |
unsigned long min; |
unsigned long min; |
667 |
unsigned long max; |
unsigned long max; |
668 |
u8 min_type; |
u8 min_type; |
669 |
u8 max_type; |
u8 max_type; |
670 |
|
if (need_space && !ccs_io_printf(head, " ")) |
671 |
|
return false; |
672 |
if (ptr->is_group) |
if (ptr->is_group) |
673 |
return ccs_io_printf(head, " @%s", |
return ccs_io_printf(head, "@%s", |
674 |
ptr->group->group_name->name); |
ptr->group->group_name->name); |
675 |
min_type = ptr->min_type; |
min_type = ptr->min_type; |
676 |
max_type = ptr->max_type; |
max_type = ptr->max_type; |
678 |
max = ptr->values[1]; |
max = ptr->values[1]; |
679 |
switch (min_type) { |
switch (min_type) { |
680 |
case CCS_VALUE_TYPE_HEXADECIMAL: |
case CCS_VALUE_TYPE_HEXADECIMAL: |
681 |
if (!ccs_io_printf(head, " 0x%lX", min)) |
if (!ccs_io_printf(head, "0x%lX", min)) |
682 |
return false; |
return false; |
683 |
break; |
break; |
684 |
case CCS_VALUE_TYPE_OCTAL: |
case CCS_VALUE_TYPE_OCTAL: |
685 |
if (!ccs_io_printf(head, " 0%lo", min)) |
if (!ccs_io_printf(head, "0%lo", min)) |
686 |
return false; |
return false; |
687 |
break; |
break; |
688 |
default: |
default: |
689 |
if (!ccs_io_printf(head, " %lu", min)) |
if (!ccs_io_printf(head, "%lu", min)) |
690 |
return false; |
return false; |
691 |
break; |
break; |
692 |
} |
} |
702 |
} |
} |
703 |
} |
} |
704 |
|
|
705 |
|
static bool ccs_print_number_union(struct ccs_io_buffer *head, |
706 |
|
const struct ccs_number_union *ptr) |
707 |
|
{ |
708 |
|
return ccs_print_number_union_common(head, ptr, true); |
709 |
|
} |
710 |
|
|
711 |
|
static bool ccs_print_number_union_nospace(struct ccs_io_buffer *head, |
712 |
|
const struct ccs_number_union *ptr) |
713 |
|
{ |
714 |
|
return ccs_print_number_union_common(head, ptr, false); |
715 |
|
} |
716 |
|
|
717 |
|
/** |
718 |
|
* ccs_print_condition - Print condition part. |
719 |
|
* |
720 |
|
* @head: Pointer to "struct ccs_io_buffer". |
721 |
|
* @cond: Pointer to "struct ccs_condition". May be NULL. |
722 |
|
* |
723 |
|
* Returns true on success, false otherwise. |
724 |
|
*/ |
725 |
|
static bool ccs_print_condition(struct ccs_io_buffer *head, |
726 |
|
const struct ccs_condition *cond) |
727 |
|
{ |
728 |
|
const struct ccs_condition_element *condp; |
729 |
|
const struct ccs_number_union *numbers_p; |
730 |
|
const struct ccs_name_union *names_p; |
731 |
|
const struct ccs_argv_entry *argv; |
732 |
|
const struct ccs_envp_entry *envp; |
733 |
|
u16 condc; |
734 |
|
u16 i; |
735 |
|
u16 j; |
736 |
|
char buffer[32]; |
737 |
|
if (!cond) |
738 |
|
goto no_condition; |
739 |
|
condc = cond->condc; |
740 |
|
condp = (const struct ccs_condition_element *) (cond + 1); |
741 |
|
numbers_p = (const struct ccs_number_union *) (condp + condc); |
742 |
|
names_p = (const struct ccs_name_union *) |
743 |
|
(numbers_p + cond->numbers_count); |
744 |
|
argv = (const struct ccs_argv_entry *) (names_p + cond->names_count); |
745 |
|
envp = (const struct ccs_envp_entry *) (argv + cond->argc); |
746 |
|
memset(buffer, 0, sizeof(buffer)); |
747 |
|
if (condc && !ccs_io_printf(head, "%s", " if")) |
748 |
|
goto out; |
749 |
|
for (i = 0; i < condc; i++) { |
750 |
|
const u8 match = condp->equals; |
751 |
|
const u8 left = condp->left; |
752 |
|
const u8 right = condp->right; |
753 |
|
condp++; |
754 |
|
switch (left) { |
755 |
|
case CCS_ARGV_ENTRY: |
756 |
|
if (!ccs_io_printf(head, " exec.argv[%u]%s\"%s\"", |
757 |
|
argv->index, argv->is_not ? |
758 |
|
"!=" : "=", argv->value->name)) |
759 |
|
goto out; |
760 |
|
argv++; |
761 |
|
continue; |
762 |
|
case CCS_ENVP_ENTRY: |
763 |
|
if (!ccs_io_printf(head, " exec.envp[\"%s\"]%s", |
764 |
|
envp->name->name, envp->is_not ? |
765 |
|
"!=" : "=")) |
766 |
|
goto out; |
767 |
|
if (envp->value) { |
768 |
|
if (!ccs_io_printf(head, "\"%s\"", |
769 |
|
envp->value->name)) |
770 |
|
goto out; |
771 |
|
} else { |
772 |
|
if (!ccs_io_printf(head, "NULL")) |
773 |
|
goto out; |
774 |
|
} |
775 |
|
envp++; |
776 |
|
continue; |
777 |
|
case CCS_NUMBER_UNION: |
778 |
|
if (!ccs_print_number_union(head, numbers_p++)) |
779 |
|
goto out; |
780 |
|
break; |
781 |
|
default: |
782 |
|
if (left >= CCS_MAX_CONDITION_KEYWORD) |
783 |
|
goto out; |
784 |
|
if (!ccs_io_printf(head, " %s", |
785 |
|
ccs_condition_keyword[left])) |
786 |
|
goto out; |
787 |
|
break; |
788 |
|
} |
789 |
|
if (!ccs_io_printf(head, "%s", match ? "=" : "!=")) |
790 |
|
goto out; |
791 |
|
switch (right) { |
792 |
|
case CCS_NAME_UNION: |
793 |
|
if (!ccs_print_name_union_quoted(head, names_p++)) |
794 |
|
goto out; |
795 |
|
break; |
796 |
|
case CCS_NUMBER_UNION: |
797 |
|
if (!ccs_print_number_union_nospace(head, numbers_p++)) |
798 |
|
goto out; |
799 |
|
break; |
800 |
|
default: |
801 |
|
if (right >= CCS_MAX_CONDITION_KEYWORD) |
802 |
|
goto out; |
803 |
|
if (!ccs_io_printf(head, "%s", |
804 |
|
ccs_condition_keyword[right])) |
805 |
|
goto out; |
806 |
|
break; |
807 |
|
} |
808 |
|
} |
809 |
|
i = cond->post_state[3]; |
810 |
|
if (!i) |
811 |
|
goto no_condition; |
812 |
|
if (!ccs_io_printf(head, " ; set")) |
813 |
|
goto out; |
814 |
|
for (j = 0; j < 3; j++) { |
815 |
|
if (!(i & (1 << j))) |
816 |
|
continue; |
817 |
|
if (!ccs_io_printf(head, " task.state[%u]=%u", j, |
818 |
|
cond->post_state[j])) |
819 |
|
goto out; |
820 |
|
} |
821 |
|
no_condition: |
822 |
|
if (ccs_io_printf(head, "\n")) |
823 |
|
return true; |
824 |
|
out: |
825 |
|
return false; |
826 |
|
} |
827 |
|
|
828 |
/** |
/** |
829 |
* ccs_print_single_path_acl - Print a single path ACL entry. |
* ccs_print_single_path_acl - Print a single path ACL entry. |
830 |
* |
* |