libsmack: use common code for smack_accesses_apply() and smack_accesses_save().
authorRafal Krypa <r.krypa@samsung.com>
Thu, 2 Jan 2014 12:52:17 +0000 (13:52 +0100)
committerRafal Krypa <r.krypa@samsung.com>
Sun, 5 Jan 2014 23:09:48 +0000 (00:09 +0100)
Centralizing code that changes internal smack_accesses representation to
text. Internal function accesses_print() now generates output for applying
the rules to kernel and saving them to a file. This allows easier changes
to data structures used by libmskack and makes the code shorter.

Signed-off-by: Rafal Krypa <r.krypa@samsung.com>
libsmack/libsmack.c

index a03f6eb..2e23b79 100644 (file)
@@ -107,6 +107,8 @@ static int dict_create(struct label_dict **dict);
 static int dict_free(struct label_dict *dict);
 static const char *dict_get_label(const struct label_dict *dict, int id);
 static ssize_t dict_add_label(struct label_dict *dict, int *id, const char *src);
+static int accesses_print(struct smack_accesses *handle, int clear,
+                         int load_fd, int change_fd, int use_long, int add_lf);
 
 int smack_accesses_new(struct smack_accesses **accesses)
 {
@@ -142,50 +144,7 @@ void smack_accesses_free(struct smack_accesses *handle)
 
 int smack_accesses_save(struct smack_accesses *handle, int fd)
 {
-       struct smack_rule *rule = handle->first;
-       char allow_str[ACC_LEN + 1];
-       char deny_str[ACC_LEN + 1];
-       FILE *file;
-       int ret;
-       int newfd;
-
-       newfd = dup(fd);
-       if (newfd == -1)
-               return -1;
-
-       file = fdopen(newfd, "w");
-       if (file == NULL) {
-               close(newfd);
-               return -1;
-       }
-
-       while (rule) {
-               access_code_to_str(rule->allow_code, allow_str);
-
-               if (rule->deny_code != -1) /* modify? */ {
-                       access_code_to_str(rule->deny_code, deny_str);
-
-                       ret = fprintf(file, "%s %s %s %s\n",
-                                     dict_get_label(handle->dict, rule->subject_id),
-                                     dict_get_label(handle->dict, rule->object_id),
-                                     allow_str, deny_str);
-               } else {
-                       ret = fprintf(file, "%s %s %s\n",
-                                     dict_get_label(handle->dict, rule->subject_id),
-                                     dict_get_label(handle->dict, rule->object_id),
-                                     allow_str);
-               }
-
-               if (ret < 0) {
-                       fclose(file);
-                       return -1;
-               }
-
-               rule = rule->next;
-       }
-
-       fclose(file);
-       return 0;
+       return accesses_print(handle, 0, fd, fd, 1, 1);
 }
 
 int smack_accesses_apply(struct smack_accesses *handle)
@@ -639,12 +598,7 @@ int smack_revoke_subject(const char *subject)
 
 static int accesses_apply(struct smack_accesses *handle, int clear)
 {
-       char buf[LOAD_LEN + 1];
-       char allow_str[ACC_LEN + 1];
-       char deny_str[ACC_LEN + 1];
-       struct smack_rule *rule;
        int ret;
-       int fd;
        int load_fd;
        int change_fd;
        int load2 = 1;
@@ -671,13 +625,33 @@ static int accesses_apply(struct smack_accesses *handle, int clear)
                goto err_out;
        }
 
+       ret = accesses_print(handle, clear, load_fd, change_fd, load2, 0);
+
+err_out:
+       if (load_fd >= 0)
+               close(load_fd);
+       if (change_fd >= 0)
+               close(change_fd);
+       return ret;
+}
+
+static int accesses_print(struct smack_accesses *handle, int clear,
+                         int load_fd, int change_fd, int use_long, int add_lf)
+{
+       char buf[LOAD_LEN + 1];
+       char allow_str[ACC_LEN + 1];
+       char deny_str[ACC_LEN + 1];
+       struct smack_rule *rule;
+       int ret;
+       int fd;
+       int i;
+       int cnt;
+
        for (rule = handle->first; rule != NULL; rule = rule->next) {
                /* Fail immediately without doing any further processing
                   if modify rules are not supported. */
-               if (rule->deny_code >= 0 && change_fd < 0) {
-                       ret = -1;
-                       goto err_out;
-               }
+               if (rule->deny_code >= 0 && change_fd < 0)
+                       return -1;
 
                access_code_to_str(clear ? 0 : rule->allow_code, allow_str);
 
@@ -685,51 +659,47 @@ static int accesses_apply(struct smack_accesses *handle, int clear)
                        access_code_to_str(rule->deny_code, deny_str);
 
                        fd = change_fd;
-                       ret = snprintf(buf, LOAD_LEN + 1, KERNEL_MODIFY_FORMAT,
+                       cnt = snprintf(buf, LOAD_LEN + 1, KERNEL_MODIFY_FORMAT,
                                       dict_get_label(handle->dict, rule->subject_id),
                                       dict_get_label(handle->dict, rule->object_id),
                                       allow_str,
                                       deny_str);
                } else {
                        fd = load_fd;
-                       if (load2)
-                               ret = snprintf(buf, LOAD_LEN + 1, KERNEL_LONG_FORMAT,
+                       if (use_long)
+                               cnt = snprintf(buf, LOAD_LEN + 1, KERNEL_LONG_FORMAT,
                                               dict_get_label(handle->dict, rule->subject_id),
                                               dict_get_label(handle->dict, rule->object_id),
                                               allow_str);
                        else {
                                if (rule->subject_len > SHORT_LABEL_LEN ||
-                                   rule->object_len > SHORT_LABEL_LEN) {
-                                       ret = -1;
-                                       goto err_out;
-                               }
+                                   rule->object_len > SHORT_LABEL_LEN)
+                                       return -1;
 
-                               ret = snprintf(buf, LOAD_LEN + 1, KERNEL_SHORT_FORMAT,
+                               cnt = snprintf(buf, LOAD_LEN + 1, KERNEL_SHORT_FORMAT,
                                               dict_get_label(handle->dict, rule->subject_id),
                                               dict_get_label(handle->dict, rule->object_id),
                                               allow_str);
                        }
                }
 
-               if (ret < 0) {
-                       ret = -1;
-                       goto err_out;
-               }
-
-               ret = write(fd, buf, ret);
-               if (ret < 0) {
-                       ret = -1;
-                       goto err_out;
+               if (cnt < 0)
+                       return -1;
+               if (add_lf)
+                       buf[cnt++] = '\n';
+
+               for (i = 0; i < cnt; ) {
+                       ret = write(fd, buf + i, cnt - i);
+                       if (ret == -1) {
+                               if (errno == EINTR)
+                                       continue;
+                               return -1;
+                       }
+                       i += ret;
                }
        }
-       ret = 0;
 
-err_out:
-       if (load_fd >= 0)
-               close(load_fd);
-       if (change_fd >= 0)
-               close(change_fd);
-       return ret;
+       return 0;
 }
 
 static inline ssize_t get_label(char *dest, const char *src)