Module Name: othersrc
Committed By: agc
Date: Sat Mar 10 21:15:27 UTC 2012
Modified Files:
othersrc/crypto/external/bsd/ssss/dist/src/libssss: secsplit.c
Log Message:
restore correct operation for odd-sized files
To generate a diff of this commit:
cvs rdiff -u -r1.8 -r1.9 \
othersrc/crypto/external/bsd/ssss/dist/src/libssss/secsplit.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: othersrc/crypto/external/bsd/ssss/dist/src/libssss/secsplit.c
diff -u othersrc/crypto/external/bsd/ssss/dist/src/libssss/secsplit.c:1.8 othersrc/crypto/external/bsd/ssss/dist/src/libssss/secsplit.c:1.9
--- othersrc/crypto/external/bsd/ssss/dist/src/libssss/secsplit.c:1.8 Fri Mar 9 06:37:23 2012
+++ othersrc/crypto/external/bsd/ssss/dist/src/libssss/secsplit.c Sat Mar 10 21:15:27 2012
@@ -15,26 +15,74 @@
* pieces give NO information about the original file (except its
* length).
*
+ * It has been written for and tested on DOS and Unix systems.
+ *
+ * To split up a file, use the command; secsplit n k file where n is
+ * the number of pieces to split it up to, and k is the number of
+ * pieces needed to reconstruct it. k should be <= n and > 1. If you
+ * get n and k backwards the program will swap them for you so don't
+ * worry too much about remembering the order.
+ *
+ * The program will output to file.001, file.002, .... If the file has
+ * an extension (e.g. "file.c") the extension will be stripped off
+ * before the ".001", etc., are added (so "file.c" will also output to
+ * "file.001", etc.).
+ *
+ * To reconstruct a file, use the command:
+ * secsplit k file.*
+ * or
+ * secsplit k file file1 file2...
+ *
* k should be >= the k used when the file was split; the minimum
* number of pieces needed to reconstruct the file. If you have too
* few pieces then the program won't give an error, but you'll get the
* wrong answer.
*
+ * The first command form is for DOS or other systems which won't
+ * expand the ".*" for you; the program scans for file.000, file.001,
+ * etc., and uses the first k of them that it finds. In the second
+ * form, the number of files given should be at least k, and again the
+ * first k of them will be used.
+ *
+ * The output in the first form will be file.out; in the second form
+ * it will be the first file on the command line, stripped of its
+ * extension, and with ".out" added, so generally it will be file.out
+ * too.
+ *
* Shamir's algorithm relies on cryptographically strong, unguessable,
* random numbers. This version of the program uses the arc4random(3)
* interface.
*
- * The files consist of a series of 16-bit values (high byte first),
- * which are the result of applying Shamir's splitting algorithm to
- * the input file taken in 16-bit chunks. The prime used is slightly
- * less than 2^16.
+ * Revision history:
+ * Version 1.0 October 23, 1993
+ *
+ * Version 1.1 October 24, 1993
+ * Added IDEA-based random-number-generator, initialized by MD5
+ * of input file, plus the time of day.
+ *
+ * Version 1.2 March 31, 2000 Damien Miller <[email protected]>
+ * Removed IDEA-based random-number generator in favour of
+ * /dev/random. Removed MSDOSisms. Rearranged source code and
+ * formatting according to OpenBSD style(9)
+ *
+ *
+ * The file formats used for output are as follows. Each file starts
+ * with one byte which is the index, from 1 through n, of that file.
+ * This is the x value used for the polynomial evaluation in Shamir's
+ * algorithm. The files then consist of a series of 16-bit values
+ * (high byte first), which are the result of applying Shamir's
+ * splitting algorithm to the input file taken in 16-bit chunks. The
+ * prime used is slightly less than 2^16, meaning that input data
+ * values close to 2^16 get turned into a pair of values (see below
+ * for more information on this expansion).
*
* If the input file is of even length, the output files will each by
* of that length+1 (because of the 1 byte at the beginning). If the
* input file is of odd length, the input is padded with a random byte
* and processed normally to get a pair of output bytes, then each
* output file is padded with an extra random byte to indicate this
- * fact. So all output files should have an even number of bytes.
+ * fact. So output files which have an odd length correspond to input
+ * files with an even length, and vice versa.
*
* The output files could have encoded k and n information, but this
* could be helpful to an attacker (he would know when he was close to
@@ -44,12 +92,34 @@
* The file formats are system-independent so files split on one kind
* of machine should be able to be reassembled on another kind of
* machine.
- */
-/*
- * This source code has been cruelly munged around, and very little
- * (if any) is left of the original sources. I have left the original
- * leading comment in these sources (insofar as it pertains to this
- * version of the code) for information.
+ *
+ * One complication exists with this code. The algorithm must work
+ * mod a prime which is bigger than all the data. We want the data to
+ * be about 16 bits therefore, so that we can multiply two numbers and
+ * have them fit in a 32-bit int. This means that the prime has to be
+ * less than 2^16 in order for them to fit. The largest such prime is
+ * 65521. This means that any data value > 65521 can't be processed
+ * directly; instead, I split it into two values, a 65520, followed by
+ * value-65520. Also, 65520 itself is split as 65520 followed by 0.
+ * This complication is pretty well limited to the input routine on
+ * splitting and the output routine on assembly.
+ *
+ * The purpose of the "magic" is to xor the incoming value with a
+ * different number each time. This is purely intended to deal with
+ * the problem that values of d >= limit-1 must be stored as four
+ * bytes rather than two. I was worried that some file might have a
+ * lot of 0xff's which would balloon in size. So I wanted to xor with
+ * a rather random number. Then, I change the random number each time
+ * in order to make it less likely that some other file would happen
+ * to have a lot of ballooning values. This way it would be very rare
+ * that a file managed to track my magic number in such a way that
+ * many d's were over the size threshold.
+ *
+ * (The "magic" is not intended to increase the security or the
+ * cryptographic strength of the algorithm in any way; it is purely to
+ * keep the size of the output files from being much bigger than the
+ * input.)
+ *
*/
#include <sys/types.h>
#include <sys/stat.h>
@@ -67,17 +137,19 @@
#define LARGEST_PRIME 65521
+#define S4_IMAGIC 0x8a31
+#define S4_DMAGIC 0x1347
+
#define S4_SMALLEST_INPUT 5
-#define S4_FILE_MAGIC "s4"
+#define S4_FILE_MAGIC "s4"
enum {
SSSS_MEM_IO = 0,
SSSS_MAPPED_IO = 1,
SSSS_FILE_IO = 2,
- SSSS_EXTMEM_IO = 3,
- SSSS_MAGIC_LENGTH = 4
+ SSSS_MAGIC_LENGTH = 4
};
#ifndef USE_ARG
@@ -88,14 +160,10 @@ enum {
#define __arraycount(__x) (sizeof(__x) / sizeof(__x[0]))
#endif
-#if LARGEST_PRIME > 65536
-#define S4_IO_SPACE(x) (((x) * 3) / 2)
-#else
-#define S4_IO_SPACE(x) (x)
-#endif
+#define S4_IO_SPACE(x) (((x) * 2001) / 2000)
-/* Multiplicative inverses mod LARGEST_PRIME */
-static const unsigned invtab[] = {
+/* Multiplicative inverses of 1-48 mod LARGEST_PRIME */
+static const int invtab[] = {
1, 32761, 43681, 49141, 52417, 54601, 56161, 57331, /* 8 */
58241, 58969, 11913, 60061, 60481, 60841, 61153, 61426, /* 16 */
42396, 61881, 6897, 62245, 62401, 38717, 11395, 62791, /* 24 */
@@ -130,19 +198,22 @@ static const unsigned invtab[] = {
59732, 31188, 6526, 65261, 54644, 59588, 42139, 61170 /* 256 */
};
+
typedef struct s4_t {
+ unsigned extra; /* extra from last call */
+ unsigned magic; /* magic number */
+ int padded; /* escaped 16-bit entity input */
int oddsizefile; /* last return included a pad */
int peek[SSSS_MAX_SHARES]; /* for two byte lookahead */
unsigned sharesc; /* # of shares */
- unsigned init[SSSS_MAX_SHARES]; /* initialised header */
} s4_t;
/* threshold header written to output file when splitting */
typedef struct s4_head_t {
- char magic[SSSS_MAGIC_LENGTH]; /* magic string */
- uint8_t coeff; /* coefficient of this share */
- uint8_t pad[3]; /* padding character */
- uint64_t size; /* size of original file */
+ char magic[SSSS_MAGIC_LENGTH]; /* magic string */
+ uint8_t coeff; /* coefficient of this share */
+ uint8_t pad[3]; /* padding character */
+ uint64_t size; /* size of original file */
} s4_head_t;
/* io stuff */
@@ -248,7 +319,6 @@ ssss_getch(ssss_str_t *str, uint64_t las
switch(str->iotype) {
case SSSS_MEM_IO:
case SSSS_MAPPED_IO:
- case SSSS_EXTMEM_IO:
return (str->c == last) ? SSSS_EOF : (int)(str->io.base[str->c++]);
case SSSS_FILE_IO:
return ((ch = fgetc(str->fp)) == EOF) ? SSSS_EOF : ch;
@@ -259,35 +329,53 @@ ssss_getch(ssss_str_t *str, uint64_t las
}
/*
- * Return a 16-bit value from input
+ * Return a 16-bit value from input, but limit it to be less than
+ * LARGEST_PRIME. Anything >= LARGEST_PRIME-1 gets returned as two
+ * consecutive values (on 2 calls). Return -1 on EOF, or -2 if the
+ * previous return value had been padded because the file had an odd #
+ * bytes.
*/
static int
-get_limited_16(s4_t *s4, ssss_str_t *str, unsigned *d)
+get_limited_16(s4_t *s4, ssss_str_t *str, int *d)
{
- uint8_t c[2];
- int ch;
+ int c[2];
+ /* First check for leftover from last time */
+ if (s4->padded) {
+ s4->padded = 0;
+ *d = s4->extra;
+ return 1;
+ }
/* Check if last return included a pad */
if (s4->oddsizefile) {
return SSSS_ODD_SIZED_FILE;
}
/* Read data (bigendian), do the magic */
- if ((ch = ssss_getch(str, str->io.size)) == SSSS_EOF) {
+ if ((c[0] = ssss_getch(str, str->io.size)) == SSSS_EOF) {
return SSSS_EOF;
}
- c[0] = (uint8_t)ch;
- if ((ch = ssss_getch(str, str->io.size)) == SSSS_EOF) {
- ch = CRANDOM(0x100);
+ if ((c[1] = ssss_getch(str, str->io.size)) == SSSS_EOF) {
+ c[1] = CRANDOM(0x100);
s4->oddsizefile = 1;
}
- c[1] = (uint8_t)ch;
- *d = (((uint8_t)c[0] & 0xff) << 8) | ((uint8_t)c[1] & 0xff);
+ *d = (((uint8_t)c[0] & 0xff) << 8) + ((uint8_t)c[1] & 0xff);
+ *d ^= s4->magic;
+ s4->magic = (s4->magic + S4_DMAGIC) & 0xffff;
+ /*
+ * If over the LARGEST_PRIME, return LARGEST_PRIME-1 as a code
+ * for that, and remember to return the rest next time.
+ */
+ if (*d >= (LARGEST_PRIME - 1)) {
+ s4->padded = 1;
+ s4->extra = *d - (LARGEST_PRIME - 1);
+ *d = LARGEST_PRIME - 1;
+ }
return 1;
}
/*
- * Given a 24-bit value d, split it into sharesc files such that any k
- * of them can reconstruct it.
+ * Given a 16-bit value d, less than LARGEST_PRIME, split it into
+ * sharesc files such that any k of them can reconstruct it.
*/
static void
split_out(uint32_t d, unsigned sharesc, unsigned k, ssss_str_t *shares)
@@ -303,10 +391,6 @@ split_out(uint32_t d, unsigned sharesc,
}
for (i = 0; i < sharesc; i++) {
di = eval(poly, k, i + 1);
- if (/*CONSTCOND*/LARGEST_PRIME > 65536) {
- di |= ((CRANDOM(0x100) & 0xfe) << 16);
- shares[i].io.base[shares[i].c++] = (di >> 16) & 0xff;
- }
shares[i].io.base[shares[i].c++] = (di >> 8) & 0xff;
shares[i].io.base[shares[i].c++] = (di & 0xff);
}
@@ -314,32 +398,39 @@ split_out(uint32_t d, unsigned sharesc,
/*
* Split the specified input file into sharesc output files, such that
- * any k of them are sufficient to reconstruct the input. This is the
- * main routine for the splitting case.
+ * any k of them are sufficient to reconstruct the input. mod is the
+ * largest prime < 2^16. This is the main routine for the splitting case.
*
- * k = Threshhold for re-assembly
+ * f_in = Input file handle
+ * f_out[] = Output file handles
+ * sharesc = Number of output files
+ * k = Threshhold for re-assembl
*/
static void
-split(s4_t *s4, ssss_str_t *str, unsigned sharesc, unsigned k, ssss_str_t *shares, unsigned doheader)
+split(s4_t *s4, ssss_str_t *str, unsigned sharesc, unsigned k, ssss_str_t *shares)
{
s4_head_t head;
unsigned i;
- unsigned d;
+ int d;
+ int ret;
- if (doheader) {
- fmt_header(&head, S4_FILE_MAGIC, str->io.size);
- }
+ fmt_header(&head, S4_FILE_MAGIC, str->io.size);
for (i = 0; i < sharesc; i++) {
/* Prefix each file with "x" coordinate, 1 byte */
head.coeff = i + 1;
- if (doheader) {
- /* add header */
- (void) memcpy(&shares[i].io.base[shares[i].c], &head, sizeof(head));
- shares[i].c = sizeof(head);
+ /* add header */
+ (void) memcpy(&shares[i].io.base[shares[i].c], &head, sizeof(head));
+ shares[i].c = sizeof(head);
+ }
+ while ((ret = get_limited_16(s4, str, &d)) != SSSS_EOF) {
+ if (ret == SSSS_ODD_SIZED_FILE) {
+ /* Odd flag - pad output files with a random byte to remember */
+ for (i = 0; i < sharesc; i++) {
+ shares[i].io.base[shares[i].c++] = CRANDOM(0x100);
+ }
+ break;
}
- }
- while (get_limited_16(s4, str, &d) != SSSS_EOF) {
- split_out(d, sharesc, k, shares);
+ split_out((unsigned)d, sharesc, k, shares);
}
}
@@ -419,35 +510,29 @@ interpolate(int *x, uint32_t *y, unsigne
* two bytes ahead to know this.
*/
static int
-get_assemble_16(s4_t *s4, ssss_str_t *inputs, unsigned coeff)
+get_assemble_16(s4_t *s4, ssss_str_t *inputs, unsigned i)
{
- unsigned j;
- int charsize;
- int ret;
- int ch;
+ int ch;
+ int c[2];
- charsize = (/*CONSTCOND*/ LARGEST_PRIME > 65536) ? 3 : 2;
- if (!s4->init[coeff]) {
- s4->init[coeff] = 1;
- s4->peek[coeff] = 0;
- for (j = 0 ; j < (unsigned)charsize ; j++) {
- ch = ssss_getch(&inputs[coeff], inputs[coeff].io.size + charsize);
- s4->peek[coeff] = (s4->peek[coeff] << 8) | (ch & 0xff);
- }
- }
- ret = s4->peek[coeff];
- s4->peek[coeff] = 0;
- for (j = 0 ; j < (unsigned)charsize ; j++) {
- if ((ch = ssss_getch(&inputs[coeff], inputs[coeff].io.size + charsize)) == SSSS_EOF) {
- s4->peek[coeff] = SSSS_EOF;
- if (j > 0) {
- s4->oddsizefile = 1;
- }
- break;
+ if (inputs[i].c == sizeof(s4_head_t)) {
+ /* Get ahead the first time */
+ c[0] = ssss_getch(&inputs[i], inputs[i].io.size + 2);
+ c[1] = ssss_getch(&inputs[i], inputs[i].io.size + 2);
+ s4->peek[i] = ((c[0] & 0xff) << 8) + (c[1] & 0xff);
+ }
+ ch = s4->peek[i];
+ if ((c[0] = ssss_getch(&inputs[i], inputs[i].io.size + 2)) == SSSS_EOF) {
+ s4->peek[i] = SSSS_EOF;
+ } else {
+ if ((c[1] = ssss_getch(&inputs[i], inputs[i].io.size + 2)) == SSSS_EOF) {
+ s4->oddsizefile = 1;
+ s4->peek[i] = SSSS_EOF;
+ } else {
+ s4->peek[i] = ((c[0] & 0xff) << 8) + (c[1] & 0xff);
}
- s4->peek[coeff] = (s4->peek[coeff] << 8) | ((unsigned)ch & 0xff);
}
- return ret;
+ return ch;
}
/*
@@ -456,7 +541,7 @@ get_assemble_16(s4_t *s4, ssss_str_t *in
* only the high 8 bits of this interpolated value are valid.
*/
static int
-get_assemble(s4_t *s4, unsigned nin, ssss_str_t *inputs, int *coeffs, unsigned *ret)
+get_assemble(s4_t *s4, unsigned nin, ssss_str_t *inputs, int *x, int *ret)
{
unsigned i;
int y[SSSS_MAX_SHARES];
@@ -466,7 +551,7 @@ get_assemble(s4_t *s4, unsigned nin, sss
return 0;
}
}
- *ret = interpolate(coeffs, (unsigned *)y, nin);
+ *ret = interpolate(x, (unsigned *)y, nin);
return 1;
}
@@ -475,28 +560,32 @@ get_assemble(s4_t *s4, unsigned nin, sss
* original file. This is the main routine for the assembly case.
*/
static int
-assemble(s4_t *s4, ssss_str_t *inputs, unsigned nin, ssss_str_t *output, unsigned doheader)
+assemble(s4_t *s4, ssss_str_t *inputs, unsigned nin, ssss_str_t *output)
{
s4_head_t heads[SSSS_MAX_SHARES];
- unsigned ch;
+ uint32_t magic;
unsigned i;
- int coeffs[SSSS_MAX_SHARES];
+ int x[SSSS_MAX_SHARES];
+ int ch;
+ magic = S4_IMAGIC;
for (i = 0; i < nin; i++) {
- if (doheader) {
- get_header(&heads[i], inputs[i].io.base);
- if (!sane_header(&heads[i], &heads[0])) {
- warn("insane ssss header %u", i);
- return 0;
- }
- inputs[i].c += sizeof(heads[i]);
- coeffs[i] = heads[i].coeff;
- } else {
- coeffs[i] = i + 1;
+ get_header(&heads[i], inputs[i].io.base);
+ if (!sane_header(&heads[i], &heads[0])) {
+ warn("insane ssss header %u", i);
+ return 0;
}
+ inputs[i].c += sizeof(heads[i]);
+ x[i] = heads[i].coeff;
}
- while (get_assemble(s4, nin, inputs, coeffs, &ch)) {
- output->io.base[output->c++] = (ch >> 8) & 0xff;
+ while (get_assemble(s4, nin, inputs, x, &ch)) {
+ if (ch == (int)(LARGEST_PRIME - 1)) {
+ (void) get_assemble(s4, nin, inputs, x, &ch);
+ ch += LARGEST_PRIME - 1;
+ }
+ ch ^= magic;
+ magic = (magic + S4_DMAGIC) & 0xffff;
+ output->io.base[output->c++] = ((unsigned)ch >> 8) & 0xff;
if (s4->oddsizefile) {
break;
}
@@ -526,11 +615,10 @@ check_values(unsigned threshold, unsigne
/* split the secret file into shares */
static int
-split_memory(ssss_t *ssss, const void *secret, size_t memsize, unsigned threshold, unsigned sharesc, unsigned doheader)
+split_memory(ssss_t *ssss, const void *secret, size_t memsize, unsigned threshold, unsigned sharesc)
{
ssss_str_t mem;
unsigned i;
- size_t size;
char small[8];
s4_t *s4;
@@ -549,9 +637,8 @@ split_memory(ssss_t *ssss, const void *s
/* allocate space for outputs */
ssss->sharesc = (unsigned)sharesc;
for (i = 0 ; i < sharesc ; i++) {
- /* possibly need space to grow for padded chars */
- size = (doheader) ? memsize + sizeof(s4_head_t) + 2 : memsize + 2;
- ssss->shares[i].io.size = S4_IO_SPACE(size);
+ /* need space to grow for padded chars */
+ ssss->shares[i].io.size = S4_IO_SPACE(memsize + sizeof(s4_head_t) + 2);
ssss->shares[i].c = 0;
if (ssss->shares[i].io.base == NULL &&
(ssss->shares[i].io.base = calloc(1, ssss->shares[i].io.size)) == NULL) {
@@ -560,27 +647,25 @@ split_memory(ssss_t *ssss, const void *s
}
}
/* Do the work */
- split(s4, &mem, sharesc, threshold, ssss->shares, doheader);
+ split(s4, &mem, sharesc, threshold, ssss->shares);
return 1;
}
/* reconstruct the shares from memory */
static int
-join_memory(ssss_t *ssss, ssss_str_t *input, size_t bytes, unsigned filec, ssss_str_t *str, unsigned doheader)
+join_memory(ssss_t *ssss, ssss_str_t *input, size_t bytes, unsigned filec, ssss_str_t *str)
{
s4_t *s4;
s4 = ssss->handle;
- if (doheader) {
- (void) memset(str, 0x0, sizeof(*str));
- }
+ (void) memset(str, 0x0, sizeof(*str));
if (str->io.base == NULL &&
(str->io.base = calloc(1, str->io.size = bytes - sizeof(s4_head_t))) == NULL) {
warn("Bad alloc %zu bytes", bytes);
return 0;
}
/* Do the work */
- return assemble(s4, input, filec, str, doheader);
+ return assemble(s4, input, filec, str);
}
/**************************************************************************/
@@ -599,6 +684,7 @@ ssss_init(ssss_t *ssss, unsigned thresho
warn("Unable to allocate ssss structure");
return 0;
}
+ s4->magic = S4_IMAGIC;
s4->sharesc = SSSS_MAX_SHARES; /* guess for just now */
ssss->handle = s4;
return 1;
@@ -658,25 +744,7 @@ ssss_split(ssss_t *ssss)
ssss_str_t *mem;
mem = &ssss->shares[SSSS_MAX_SHARES];
- return split_memory(ssss, mem->io.base, mem->io.size, ssss->threshold, ssss->sharesc, 1);
-}
-
-/* split vector via iovec interface */
-int
-ssss_split_vec(ssss_t *ssss, const char *buf, size_t size, struct iovec *iov, int iovc)
-{
- const unsigned noheader = 0;
- int ret;
- int i;
-
- ssss->shares[SSSS_SPLIT_SOURCE].io.base = __UNCONST(buf);
- ssss->shares[SSSS_SPLIT_SOURCE].io.size = size;
- ssss->shares[SSSS_SPLIT_SOURCE].iotype = SSSS_EXTMEM_IO;
- ret = split_memory(ssss, buf, size, ssss->threshold, ssss->sharesc, noheader);
- for (i = 0 ; ret && i < iovc ; i++) {
- ssss_get_share(ssss, (unsigned)i, &iov[i].iov_base, &iov[i].iov_len);
- }
- return ret;
+ return split_memory(ssss, mem->io.base, mem->io.size, ssss->threshold, ssss->sharesc);
}
/* combine/join/decode into one */
@@ -694,11 +762,12 @@ ssss_combine(ssss_t *ssss)
warn("Unable to allocate ssss structure");
return -1;
}
+ s4->magic = S4_IMAGIC;
s4->sharesc = SSSS_MAX_SHARES; /* guess for just now */
ssss->handle = s4;
if (!join_memory(ssss, ssss->shares,
ssss->shares[0].io.size - 2, ssss->availc,
- &ssss->shares[SSSS_JOIN_DEST], 1)) {
+ &ssss->shares[SSSS_JOIN_DEST])) {
return -1;
}
free(s4);
@@ -706,37 +775,6 @@ ssss_combine(ssss_t *ssss)
return (int)ssss->shares[SSSS_MAX_SHARES].c;
}
-/* combine a split vector via iovec interface */
-int
-ssss_combine_vec(ssss_t *ssss, struct iovec *iov, int iovc, char *buf, size_t size)
-{
- s4_t *s4;
- int i;
-
- for (i = 0 ; i < iovc ; i++) {
- ssss->shares[i].io.base = iov[i].iov_base;
- ssss->shares[i].io.size = iov[i].iov_len;
- ssss->shares[i].iotype = SSSS_EXTMEM_IO;
- }
- ssss->availc = iovc;
- if ((s4 = calloc(1, sizeof(*s4))) == NULL) {
- warn("Unable to allocate ssss structure");
- return -1;
- }
- s4->sharesc = SSSS_MAX_SHARES; /* guess for just now */
- ssss->handle = s4;
- if (!join_memory(ssss, ssss->shares,
- ssss->shares[0].io.size - 2, ssss->availc,
- &ssss->shares[SSSS_JOIN_DEST], 0)) {
- return -1;
- }
- (void) memcpy(buf, ssss->shares[SSSS_JOIN_DEST].io.base, size);
- ssss->shares[SSSS_JOIN_DEST].iotype = SSSS_EXTMEM_IO;
- free(s4);
- ssss->handle = NULL;
- return (int)ssss->shares[SSSS_JOIN_DEST].c;
-}
-
/* write a share to a file */
int
ssss_write_share(ssss_t *ssss, unsigned n, const char *f)
@@ -812,7 +850,6 @@ ssss_end(ssss_t *ssss)
case SSSS_FILE_IO:
(void)fclose(ssss->shares[i].fp);
break;
- case SSSS_EXTMEM_IO:
default:
break;
}