Extended the capabilities of iso_node_set_attrs() and

mentioned the new error codes in the error text generator
This commit is contained in:
Thomas Schmitt 2009-02-06 11:41:24 +01:00
parent f66e3b8e2f
commit c974365b16
4 changed files with 216 additions and 43 deletions

View File

@ -45,8 +45,12 @@ The reader shall be prepared to detect and handle oversized data.
One or more AA entries form the Attribute List of a file object with
an even number of components. Each two consequtive components form a pair of
Name and Value. The empty name is reserved for a compact representation of
ALCs. The meaning of any other name is not specified by this document.
Name and Value.
Names which do not contain a perisod character "." are reserved for
registration at libburnia.org. The meaning of any other names is not
specified by this document.
For now only one name is registered:
The empty name indicates that the value is a compact representation of ALCs.
All AA entries except the last one shall have the CONTINUE flag set. An AA
entry with CONTINUE set to 0 indicates the end of the Attribute List.

View File

@ -4205,7 +4205,8 @@ void iso_stream_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id,
/* ts A90121 */
/** AAIP info is present in ISO image but will be ignored (NOTE, HIGH, -336) */
/** AAIP info with ACL or xattr in ISO image will be ignored
(NOTE, HIGH, -336) */
#define ISO_AAIP_IGNORED 0xB030FEB0
/* ts A90130 */
@ -4217,11 +4218,12 @@ void iso_stream_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id,
#define ISO_AAIP_BAD_ACL_TEXT 0xE830FEAE
/* ts A90130 */
/** No AAIP processing enabled at compile time (FAILURE, HIGH, -339) */
/** AAIP processing for ACL and xattr not enabled at compile time
(FAILURE, HIGH, -339) */
#define ISO_AAIP_NOT_ENABLED 0xE830FEAD
/* ts A90130 */
/** Error with decoding attribute list AAIP info (FAILURE, HIGH, -340) */
/** Error with decoding AAIP info for ACL or xattr (FAILURE, HIGH, -340) */
#define ISO_AAIP_BAD_AASTRING 0xE830FEAC
/* ts A90131 */
@ -4232,6 +4234,10 @@ void iso_stream_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id,
/** Error with attaching ACL or xattr to local file (FAILURE, HIGH, -342) */
#define ISO_AAIP_NO_SET_LOCAL 0xE830FEAA
/* ts A90206 */
/** Unallowed attempt to set an xattr with non-user name
(FAILURE, HIGH, -343) */
#define ISO_AAIP_NON_USER_NAME 0xE830FEA9
/* --------------------------------- AAIP --------------------------------- */
@ -4407,6 +4413,12 @@ int iso_node_get_attrs(IsoNode *node, size_t *num_attrs,
* Bitfield for control purposes
* bit0= Do not maintain eventual existing ACL of the node.
* Set eventual new ACL from value of empty name.
* bit1= Do not clear the existing attribute list but merge it with
* the list given by this call
* bit2= Delete the attributes with the given names
* bit3= Allow non-user attribute.
* I.e. those with a non-empty name which does not begin by "user."
* (The empty name is always allowed and governed by bit0.)
* @return
* 1 = ok
* < 0 = error

View File

@ -211,9 +211,21 @@ const char *iso_error_to_msg(int errcode)
case ISO_DATA_SOURCE_FATAL:
return "Read error occured with IsoDataSource";
case ISO_AAIP_IGNORED:
return "AAIP info is present in ISO image but will be ignored";
return "AAIP info with ACL or xattr in ISO image will be ignored";
case ISO_AAIP_BAD_ACL:
return "Error with decoding ACL from AAIP info";
case ISO_AAIP_BAD_ACL_TEXT:
return "Error with encoding ACL for AAIP";
case ISO_AAIP_NOT_ENABLED:
return "AAIP processing for ACL and xattr not enabled at compile time";
case ISO_AAIP_BAD_AASTRING:
return "Error with decoding AAIP info for ACL or xattr";
case ISO_AAIP_NO_GET_LOCAL:
return "Error with reading ACL or xattr from local file";
case ISO_AAIP_NO_SET_LOCAL:
return "Error with attaching ACL or xattr to local file";
case ISO_AAIP_NON_USER_NAME:
return "Unallowed attempt to set an xattr with non-user name";
default:
return "Unknown error";
}

View File

@ -1462,6 +1462,138 @@ int iso_node_get_attrs(IsoNode *node, size_t *num_attrs,
}
/* ts A90205 */
/* Enlarge attribute list */
static
int attr_enlarge_list(char ***names, size_t **value_lengths, char ***values,
size_t new_num, int flag)
{
void *newpt;
newpt = realloc(*names, new_num * sizeof(char *));
if (newpt == NULL)
return ISO_OUT_OF_MEM;
*names = (char **) newpt;
newpt = realloc(*values, new_num * sizeof(char *));
if (newpt == NULL)
return ISO_OUT_OF_MEM;
*values = (char **) newpt;
newpt = realloc(*value_lengths, new_num * sizeof(size_t));
if (newpt == NULL)
return ISO_OUT_OF_MEM;
*value_lengths = (size_t *) newpt;
return 1;
}
/* ts A90205 */
/* Merge attribute list of node and given new attribute list into
attribute list returned by m_* parameters.
The m_* paramters have finally to be freed by a call with bit15 set.
@param flag Bitfield for control purposes
bit2= delete rather than overwrite
bit15= release memory and return 1
*/
static
int iso_node_merge_xattr(IsoNode *node, size_t num_attrs, char **names,
size_t *value_lengths, char **values,
size_t *m_num_attrs, char ***m_names,
size_t **m_value_lengths, char ***m_values, int flag)
{
int ret;
size_t new_names = 0, deleted = 0, i, j, w;
if (flag & (1 << 15)) {
iso_node_get_attrs(node, m_num_attrs, m_names, m_value_lengths,
m_values, 1 << 15);
return 1;
}
ret = iso_node_get_attrs(node, m_num_attrs, m_names, m_value_lengths,
m_values, 0);
if (ret < 0)
return ret;
/* Handle existing names, count non-existing names */
for (i = 0; i < num_attrs; i++) {
for (j = 0; j < *m_num_attrs; j++) {
if (names[i] == NULL || (*m_names)[j] == NULL)
continue;
if (strcmp(names[i], (*m_names)[j]) == 0) {
if ((*m_values)[j] != NULL)
free((*m_values)[j]);
(*m_values)[j] = NULL;
(*m_value_lengths)[j] = 0;
if (flag & 4) {
/* Delete pair */
free((*m_names)[j]);
(*m_names)[j] = NULL;
deleted++;
} else {
(*m_values)[j] = calloc(value_lengths[i] + 1, 1);
if ((*m_values)[j] == NULL)
return ISO_OUT_OF_MEM;
memcpy((*m_values)[j], values[i], value_lengths[i]);
(*m_values)[j][value_lengths[i]] = 0;
(*m_value_lengths)[j] = value_lengths[i];
}
break;
}
}
if (j >= *m_num_attrs)
new_names++;
}
if (new_names > 0 && (flag & 4)) {
/* >>> warn of non-existing name on delete ? */;
} else if (new_names > 0) {
ret = attr_enlarge_list(m_names, m_value_lengths, m_values,
*m_num_attrs + new_names, 0);
if (ret < 0)
return ret;
/* Set new pairs */;
w = *m_num_attrs;
for (i = 0; i < num_attrs; i++) {
for (j = 0; j < *m_num_attrs; j++) {
if (names[i] == NULL || (*m_names)[j] == NULL)
continue;
if (strcmp(names[i], (*m_names)[j]) == 0)
continue;
}
if (j < *m_num_attrs) /* Name is not new */
continue;
(*m_names)[w] = strdup(names[i]);
if ((*m_names)[w] == NULL)
return ISO_OUT_OF_MEM;
(*m_values)[w] = calloc(value_lengths[i] + 1, 1);
if ((*m_values)[w] == NULL)
return ISO_OUT_OF_MEM;
memcpy((*m_values)[w], values[i], value_lengths[i]);
(*m_values)[w][value_lengths[i]] = 0;
(*m_value_lengths)[w] = value_lengths[i];
w++;
}
*m_num_attrs = w;
}
if (deleted > 0) {
/* Garbage collection */
w = 0;
for (j = 0; j < *m_num_attrs; j++) {
if ((*m_names)[j] == NULL)
continue;
(*m_names)[w] = (*m_names)[j];
(*m_values)[w] = (*m_values)[j];
(*m_value_lengths)[w] = (*m_value_lengths)[j];
w++;
}
*m_num_attrs = w;
}
return 1;
}
/* ts A90121 */
int iso_node_set_attrs(IsoNode *node, size_t num_attrs, char **names,
size_t *value_lengths, char **values, int flag)
@ -1470,47 +1602,74 @@ int iso_node_set_attrs(IsoNode *node, size_t num_attrs, char **names,
#ifdef Libisofs_with_aaiP
int ret;
size_t sret, result_len;
size_t sret, result_len, m_num = 0, *m_value_lengths = NULL, i;
unsigned char *result;
char *a_acl= NULL, *d_acl= NULL;
char *a_acl = NULL, *d_acl = NULL, **m_names = NULL, **m_values = NULL;
if (!(flag & 8))
for (i = 0; i < num_attrs; i++)
if (strncmp(names[i], "user.", 5) != 0 && names[i][0] != 0)
return ISO_AAIP_NON_USER_NAME;
if (!(flag & 1))
iso_node_get_acl_text(node, &a_acl, &d_acl, 16);
if (flag & (2 | 4)) {
/* Merge old and new lists */
ret = iso_node_merge_xattr(
node, num_attrs, names, value_lengths, values,
&m_num, &m_names, &m_value_lengths, &m_values, flag & 4);
if (ret < 0)
goto ex;
num_attrs = m_num;
names = m_names;
value_lengths = m_value_lengths;
values = m_values;
}
if (num_attrs == 0) {
ret = iso_node_remove_xinfo(node, aaip_xinfo_func);
if (ret < 0)
return ret;
goto ex;
if (!(flag & 1)) {
ret = iso_node_set_acl_text(node, a_acl, d_acl, 0);
if (ret < 0)
return ret;
goto ex;
}
return 1;
ret = 1;
goto ex;
}
sret = aaip_encode(num_attrs, names, value_lengths, values,
&result_len, &result, 0);
if (sret == 0)
return ISO_OUT_OF_MEM;
if (sret == 0) {
ret = ISO_OUT_OF_MEM;
goto ex;
}
ret = iso_node_remove_xinfo(node, aaip_xinfo_func);
if (ret < 0)
return ret;
goto ex;
ret = iso_node_add_xinfo(node, aaip_xinfo_func, result);
if (ret < 0)
return ret;
goto ex;
if (ret == 0) {
/* >>> something is messed up with xinfo */;
return ISO_ERROR;
ret = ISO_ERROR;
goto ex;
}
if (!(flag & 1)) {
ret = iso_node_set_acl_text(node, a_acl, d_acl, 0);
if (ret < 0)
return ret;
goto ex;
}
return 1;
ret = 1;
ex:;
/* Dispose eventual merged list */
iso_node_merge_xattr(node, num_attrs, names, value_lengths, values,
&m_num, &m_names, &m_value_lengths, &m_values, 1 << 15);
return ret;
#else /* Libisofs_with_aaiP */
@ -1579,7 +1738,7 @@ int iso_node_get_acl_text(IsoNode *node,
*access_text = *default_text = NULL;
ret = iso_node_get_attrs(node, &num_attrs, &names,
&value_lengths, &values, 0);
&value_lengths, &values, 1);
if (ret < 0)
return ret;
@ -1650,8 +1809,7 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text,
size_t a_text_fill = 0, d_text_fill = 0;
size_t v_len, acl_len= 0;
char **names = NULL, **values = NULL, *a_text = NULL, *d_text = NULL;
char **new_names, **new_values;
size_t *new_value_lengths;
unsigned char *v_data, *acl= NULL;
int ret;
mode_t st_mode;
@ -1664,7 +1822,7 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text,
}
ret = iso_node_get_attrs(node, &num_attrs, &names,
&value_lengths, &values, 0);
&value_lengths, &values, 1);
if (ret < 0)
return ret;
@ -1721,6 +1879,9 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text,
if (values[i] != NULL)
free(values[i]);
if(acl == NULL) { /* delete whole ACL attribute */
/* >>> update S_IRWXG by eventual group:: ACL entry */;
for (j = i + 1; j < num_attrs; j++) {
names[j - 1] = names[j];
value_lengths[j - 1] = value_lengths[j];
@ -1735,7 +1896,7 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text,
/* Encode attributes and attach to node */
ret = iso_node_set_attrs(node, num_attrs, names, value_lengths, values,
0);
1 | 8);
if (ret <= 0)
goto ex;
goto update_perms;
@ -1754,26 +1915,9 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text,
goto ex;
}
/* Enlarge attribute list */
new_names = realloc(names, (num_attrs + 1) * sizeof(char *));
if (new_names == NULL) {
ret = ISO_OUT_OF_MEM;
ret = attr_enlarge_list(&names, &value_lengths, &values, num_attrs + 1, 0);
if (ret < 0)
goto ex;
}
names = new_names;
new_values = realloc(values, (num_attrs + 1) * sizeof(char *));
if (new_values == NULL) {
ret = ISO_OUT_OF_MEM;
goto ex;
}
values = new_values;
new_value_lengths = realloc(value_lengths,
(num_attrs + 1) * sizeof(size_t));
if (new_value_lengths == NULL) {
ret = ISO_OUT_OF_MEM;
goto ex;
}
value_lengths = new_value_lengths;
/* Set new ACL attribute */
names[num_attrs] = strdup("");
@ -1787,7 +1931,8 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text,
num_attrs++;
/* Encode attributes and attach to node */
ret = iso_node_set_attrs(node, num_attrs, names, value_lengths, values, 0);
ret = iso_node_set_attrs(node, num_attrs, names, value_lengths, values,
1 | 8);
if (ret < 0)
goto ex;