|
|
|
@ -7,6 +7,8 @@
|
|
|
|
|
* published by the Free Software Foundation. See COPYING file for details. |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
#define Libisofs_new_nm_sl_cE yes |
|
|
|
|
|
|
|
|
|
/* ts A90116 : libisofs.h eventually defines Libisofs_with_aaiP */ |
|
|
|
|
#include "libisofs.h" |
|
|
|
|
|
|
|
|
@ -16,7 +18,10 @@
|
|
|
|
|
#include "writer.h" |
|
|
|
|
#include "messages.h" |
|
|
|
|
#include "image.h" |
|
|
|
|
|
|
|
|
|
#ifdef Libisofs_with_aaiP |
|
|
|
|
#include "aaip_0_2.h" |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#include <string.h> |
|
|
|
|
|
|
|
|
@ -700,6 +705,212 @@ int aaip_xinfo_func(void *data, int flag)
|
|
|
|
|
#endif /* Libisofs_with_aaiP */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ts A90117 */ |
|
|
|
|
/**
|
|
|
|
|
* Compute SUA lentgth and eventual Continuation Area length of field NM and |
|
|
|
|
* eventually fields SL and AA. Because CA usage makes necessary the use of |
|
|
|
|
* a CE entry of 28 bytes in SUA, this computation fails if not the 28 bytes |
|
|
|
|
* are taken into account at start. In this case the caller should retry with |
|
|
|
|
* bit0 set.
|
|
|
|
|
*
|
|
|
|
|
* @param flag bit0= assume CA usage (else return 0 on SUA overflow) |
|
|
|
|
* @return 1= ok, computation of *su_size and *ce is valid |
|
|
|
|
* 0= not ok, CA usage is necessary but bit0 was not set |
|
|
|
|
* (*su_size and *ce stay unaltered in this case) |
|
|
|
|
* <0= error: |
|
|
|
|
* -1= not enough SUA space for 28 bytes of CE entry |
|
|
|
|
*/ |
|
|
|
|
static |
|
|
|
|
int susp_calc_nm_sl_aa(Ecma119Image *t, Ecma119Node *n, size_t space, |
|
|
|
|
size_t *su_size, size_t *ce, int flag) |
|
|
|
|
{ |
|
|
|
|
char *name; |
|
|
|
|
size_t namelen, su_mem, ce_mem; |
|
|
|
|
|
|
|
|
|
#ifdef Libisofs_with_aaiP |
|
|
|
|
/* ts A90112 */ |
|
|
|
|
void *xipt; |
|
|
|
|
size_t num_aapt = 0, sua_free = 0; |
|
|
|
|
int ret; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
su_mem = *su_size; |
|
|
|
|
ce_mem = *ce; |
|
|
|
|
if (*ce > 0 && !(flag & 1)) |
|
|
|
|
goto unannounced_ca; |
|
|
|
|
|
|
|
|
|
name = get_rr_fname(t, n->node->name); |
|
|
|
|
namelen = strlen(name); |
|
|
|
|
free(name); |
|
|
|
|
|
|
|
|
|
if (flag & 1) { |
|
|
|
|
/* Account for 28 bytes of CE field */ |
|
|
|
|
if (*su_size + 28 > space) |
|
|
|
|
return -1; |
|
|
|
|
*su_size += 28; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* NM entry */ |
|
|
|
|
if (*su_size + 5 + namelen <= space) { |
|
|
|
|
/* ok, it fits in System Use Area */ |
|
|
|
|
*su_size += 5 + namelen; |
|
|
|
|
} else { |
|
|
|
|
/* the NM will be divided in a CA */ |
|
|
|
|
if (!(flag & 1)) |
|
|
|
|
goto unannounced_ca; |
|
|
|
|
namelen = namelen - (space - *su_size - 5); |
|
|
|
|
*ce = 5 + namelen; |
|
|
|
|
*su_size = space; |
|
|
|
|
} |
|
|
|
|
if (n->type == ECMA119_SYMLINK) { |
|
|
|
|
/*
|
|
|
|
|
* for symlinks, we also need to write the SL |
|
|
|
|
*/ |
|
|
|
|
char *dest, *cur, *prev; |
|
|
|
|
size_t sl_len = 5; |
|
|
|
|
int cew = (*ce != 0); /* are we writing to CA ? */ |
|
|
|
|
|
|
|
|
|
dest = get_rr_fname(t, ((IsoSymlink*)n->node)->dest); |
|
|
|
|
prev = dest; |
|
|
|
|
cur = strchr(prev, '/'); |
|
|
|
|
while (1) { |
|
|
|
|
size_t clen; |
|
|
|
|
if (cur) { |
|
|
|
|
clen = cur - prev; |
|
|
|
|
} else { |
|
|
|
|
/* last component */ |
|
|
|
|
clen = strlen(prev); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (clen == 1 && prev[0] == '.') { |
|
|
|
|
clen = 0; |
|
|
|
|
} else if (clen == 2 && prev[0] == '.' && prev[1] == '.') { |
|
|
|
|
clen = 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* flags and len for each component record (RRIP, 4.1.3.1) */ |
|
|
|
|
clen += 2; |
|
|
|
|
|
|
|
|
|
if (!cew) { |
|
|
|
|
/* we are still writing to the SUA */ |
|
|
|
|
if (*su_size + sl_len + clen > space) { |
|
|
|
|
/*
|
|
|
|
|
* ok, we need a Continuation Area anyway |
|
|
|
|
* TODO this can be handled better, but for now SL |
|
|
|
|
* will be completelly moved into the CA |
|
|
|
|
*/ |
|
|
|
|
if (!(flag & 1)) |
|
|
|
|
goto unannounced_ca; |
|
|
|
|
cew = 1; |
|
|
|
|
} else { |
|
|
|
|
sl_len += clen; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (cew) { |
|
|
|
|
if (sl_len + clen > 255) { |
|
|
|
|
/* we need an additional SL entry */ |
|
|
|
|
if (clen > 250) { |
|
|
|
|
/*
|
|
|
|
|
* case 1, component too large to fit in a
|
|
|
|
|
* single SL entry. Thus, the component need |
|
|
|
|
* to be divided anyway. |
|
|
|
|
* Note than clen can be up to 255 + 2 = 257. |
|
|
|
|
*
|
|
|
|
|
* First, we check how many bytes fit in current |
|
|
|
|
* SL field
|
|
|
|
|
*/ |
|
|
|
|
int fit = 255 - sl_len - 2; |
|
|
|
|
if (clen - 250 <= fit) { |
|
|
|
|
/*
|
|
|
|
|
* the component can be divided between this |
|
|
|
|
* and another SL entry |
|
|
|
|
*/ |
|
|
|
|
*ce += 255; /* this SL, full */ |
|
|
|
|
sl_len = 5 + (clen - fit); |
|
|
|
|
} else { |
|
|
|
|
/*
|
|
|
|
|
* the component will need a 2rd SL entry in |
|
|
|
|
* any case, so we prefer to don't write
|
|
|
|
|
* anything in this SL |
|
|
|
|
*/ |
|
|
|
|
*ce += sl_len + 255; |
|
|
|
|
sl_len = 5 + (clen - 250) + 2; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
/* case 2, create a new SL entry */ |
|
|
|
|
*ce += sl_len; |
|
|
|
|
sl_len = 5 + clen; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
sl_len += clen; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!cur || cur[1] == '\0') { |
|
|
|
|
/* cur[1] can be \0 if dest ends with '/' */ |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
prev = cur + 1; |
|
|
|
|
cur = strchr(prev, '/'); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
free(dest); |
|
|
|
|
|
|
|
|
|
/* and finally write the pending SL field */ |
|
|
|
|
if (!cew) { |
|
|
|
|
/* the whole SL fits into the SUA */ |
|
|
|
|
*su_size += sl_len; |
|
|
|
|
} else { |
|
|
|
|
*ce += sl_len; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifdef Libisofs_with_aaiP |
|
|
|
|
/* ts A90112 */ |
|
|
|
|
xipt = NULL; |
|
|
|
|
|
|
|
|
|
#ifdef Libisofs_with_aaip_dummY |
|
|
|
|
|
|
|
|
|
num_aapt = 28; |
|
|
|
|
aaip_xinfo_func(NULL, 0); /* to avoid compiler warning */ |
|
|
|
|
|
|
|
|
|
#else /* Libisofs_with_aaip_dummY */ |
|
|
|
|
|
|
|
|
|
/* obtain num_aapt from node */ |
|
|
|
|
num_aapt = 0; |
|
|
|
|
|
|
|
|
|
/* >>> if AAIP is enabled */ |
|
|
|
|
if (1) { |
|
|
|
|
|
|
|
|
|
ret = iso_node_get_xinfo(n->node, aaip_xinfo_func, &xipt); |
|
|
|
|
if (ret == 1) { |
|
|
|
|
num_aapt = aaip_count_bytes((unsigned char *) xipt, 0); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endif /* ! Libisofs_with_aaip_dummY */ |
|
|
|
|
|
|
|
|
|
/* let the expert decide where to add num_aapt */ |
|
|
|
|
if (num_aapt > 0) { |
|
|
|
|
sua_free = space - *su_size; |
|
|
|
|
aaip_add_AA(NULL, NULL, NULL, num_aapt, &sua_free, ce, 1); |
|
|
|
|
*su_size = space - sua_free; |
|
|
|
|
if (*ce > 0 && !(flag & 1)) |
|
|
|
|
goto unannounced_ca; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endif /* Libisofs_with_aaiP */ |
|
|
|
|
|
|
|
|
|
return 1; |
|
|
|
|
|
|
|
|
|
unannounced_ca:; |
|
|
|
|
*su_size = su_mem; |
|
|
|
|
*ce = ce_mem; |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Compute the length needed for write all RR and SUSP entries for a given |
|
|
|
|
* node. |
|
|
|
@ -721,10 +932,16 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space,
|
|
|
|
|
|
|
|
|
|
#ifdef Libisofs_with_aaiP |
|
|
|
|
/* ts A90112 */ |
|
|
|
|
#ifndef Libisofs_new_nm_sl_cE |
|
|
|
|
void *xipt; |
|
|
|
|
size_t num_aapt = 0, sua_free = 0; |
|
|
|
|
#endif /* Libisofs_new_nm_sl_cE */ |
|
|
|
|
int ret; |
|
|
|
|
#else /* Libisofs_with_aaiP */ |
|
|
|
|
#ifdef Libisofs_new_nm_sl_cE |
|
|
|
|
int ret; |
|
|
|
|
#endif |
|
|
|
|
#endif /* ! Libisofs_with_aaiP */ |
|
|
|
|
|
|
|
|
|
/* space min is 255 - 33 - 37 = 185
|
|
|
|
|
* At the same time, it is always an odd number, but we need to pad it |
|
|
|
@ -763,6 +980,16 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space,
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (type == 0) { |
|
|
|
|
|
|
|
|
|
#ifdef Libisofs_new_nm_sl_cE |
|
|
|
|
|
|
|
|
|
/* Try without CE */ |
|
|
|
|
ret = susp_calc_nm_sl_aa(t, n, space, &su_size, ce, 0); |
|
|
|
|
if (ret == 0) /* Retry with CE */ |
|
|
|
|
susp_calc_nm_sl_aa(t, n, space, &su_size, ce, 1); |
|
|
|
|
|
|
|
|
|
#else /* Libisofs_new_nm_sl_cE */ |
|
|
|
|
|
|
|
|
|
char *name = get_rr_fname(t, n->node->name); |
|
|
|
|
size_t namelen = strlen(name); |
|
|
|
|
free(name); |
|
|
|
@ -921,6 +1148,8 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space,
|
|
|
|
|
|
|
|
|
|
#endif /* Libisofs_with_aaiP */ |
|
|
|
|
|
|
|
|
|
#endif /* ! Libisofs_new_nm_sl_cE */ |
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
|
|
/* "." or ".." entry */ |
|
|
|
@ -1017,6 +1246,11 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|
|
|
|
#endif |
|
|
|
|
size_t aaip_er_len= 0; |
|
|
|
|
|
|
|
|
|
#ifdef Libisofs_new_nm_sl_cE |
|
|
|
|
size_t su_size_pd, ce_len_pd; /* predicted sizes of SUA and CA */ |
|
|
|
|
int ce_is_predicted = 0; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
if (t == NULL || n == NULL || info == NULL) { |
|
|
|
|
return ISO_NULL_POINTER; |
|
|
|
|
} |
|
|
|
@ -1110,6 +1344,20 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|
|
|
|
|
|
|
|
|
sua_free = space - info->suf_len; |
|
|
|
|
|
|
|
|
|
#ifdef Libisofs_new_nm_sl_cE |
|
|
|
|
/* ts A90117 */ |
|
|
|
|
/* Try whether NM, SL, AA will fit into SUA */ |
|
|
|
|
su_size_pd = info->suf_len; |
|
|
|
|
ce_len_pd = ce_len; |
|
|
|
|
ret = susp_calc_nm_sl_aa(t, n, space, &su_size_pd, &ce_len_pd, 0); |
|
|
|
|
if (ret == 0) { /* Have to use CA. 28 bytes of CE are necessary */ |
|
|
|
|
susp_calc_nm_sl_aa(t, n, space, &su_size_pd, &ce_len_pd, 1); |
|
|
|
|
sua_free -= 28; |
|
|
|
|
ce_is_predicted = 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endif /* ! Libisofs_new_nm_sl_cE */ |
|
|
|
|
|
|
|
|
|
/* NM entry */ |
|
|
|
|
if (5 + namelen <= sua_free) { |
|
|
|
|
/* ok, it fits in System Use Area */ |
|
|
|
@ -1118,7 +1366,13 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|
|
|
|
} else { |
|
|
|
|
/* the NM will be divided in a CE */ |
|
|
|
|
nm_type = 1; |
|
|
|
|
|
|
|
|
|
#ifdef Libisofs_new_nm_sl_cE |
|
|
|
|
namelen = namelen - (sua_free - 5); |
|
|
|
|
#else |
|
|
|
|
namelen = namelen - (sua_free - 5 - 28); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
ce_len = 5 + namelen; |
|
|
|
|
sua_free = 0; |
|
|
|
|
} |
|
|
|
@ -1166,6 +1420,15 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|
|
|
|
* TODO this can be handled better, but for now SL |
|
|
|
|
* will be completelly moved into the CA |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
#ifdef Libisofs_new_nm_sl_cE |
|
|
|
|
|
|
|
|
|
/* ts A90117 */ |
|
|
|
|
/* sua_free, ce_len, nm_type already account for CE */ |
|
|
|
|
cew = 1; |
|
|
|
|
|
|
|
|
|
#else /* Libisofs_new_nm_sl_cE */ |
|
|
|
|
|
|
|
|
|
if (28 <= sua_free) { |
|
|
|
|
/* the CE entry fills without reducing NM */ |
|
|
|
|
sua_free -= 28; |
|
|
|
@ -1177,6 +1440,9 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|
|
|
|
sua_free = 0; |
|
|
|
|
cew = 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endif /* ! Libisofs_new_nm_sl_cE */ |
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
/* add the component */ |
|
|
|
|
ret = rrip_SL_append_comp(&n_comp, &comps, prev,
|
|
|
|
@ -1293,16 +1559,33 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|
|
|
|
* Write the NM part that fits in SUA... Note that CE |
|
|
|
|
* entry and NM in the continuation area is added below
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
#ifdef Libisofs_new_nm_sl_cE |
|
|
|
|
namelen = space - info->suf_len - 28 * (!!ce_is_predicted) - 5; |
|
|
|
|
#else |
|
|
|
|
namelen = space - info->suf_len - 28 - 5; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
ret = rrip_add_NM(t, info, name, namelen, 1, 0); |
|
|
|
|
if (ret < 0) { |
|
|
|
|
goto add_susp_cleanup; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifdef Libisofs_new_nm_sl_cE |
|
|
|
|
|
|
|
|
|
if (ce_is_predicted) { |
|
|
|
|
/* Add the CE entry */ |
|
|
|
|
ret = susp_add_CE(t, ce_len_pd, info); |
|
|
|
|
|
|
|
|
|
#else /* Libisofs_new_nm_sl_cE */ |
|
|
|
|
|
|
|
|
|
if (ce_len > 0) { |
|
|
|
|
/* Add the CE entry */ |
|
|
|
|
ret = susp_add_CE(t, ce_len, info); |
|
|
|
|
|
|
|
|
|
#endif /* ! Libisofs_new_nm_sl_cE */ |
|
|
|
|
|
|
|
|
|
if (ret < 0) { |
|
|
|
|
goto add_susp_cleanup; |
|
|
|
|
} |
|
|
|
|