void memory_manager_default_on_oom(const memory_manager_t *self, size_t      size)
{
  static char         buf[4096];
  static const size_t buf_size = sizeof(buf) / sizeof(buf[0]);

  snprintf
    ( (char *) buf, (size_t) terminator_size(buf_size), ""
      "*** (EE) Error: memory_manager_default_on_oom: Out of memory!  Requested '%d' bytes.\n"

    , (int) size
    );

  buf[buf_size - 1] = 0;
  memory_manager_on_err(self, buf);
}
Exemple #2
0
static char *
convert_ccsid(LIBSSH2_SESSION *session, libssh2_string_cache **cache,
              unsigned short outccsid, unsigned short inccsid,
              const char *instring, ssize_t inlen, size_t *outlen)
{
    char *inp;
    char *outp;
    size_t olen;
    size_t ilen;
    size_t buflen;
    size_t curlen;
    ssize_t termsize;
    int i;
    char *dst;
    libssh2_string_cache *outstring;
    QtqCode_T incode;
    QtqCode_T outcode;
    iconv_t cd;

    if (!instring) {
        if (outlen)
            *outlen = 0;
        return NULL;
    }
    if (outlen)
        *outlen = -1;
    if (!session || !cache)
        return NULL;

    /* Get terminator size. */
    termsize = terminator_size(outccsid);
    if (termsize < 0)
        return NULL;
 
    /* Prepare conversion parameters. */
    memset((void *) &incode, 0, sizeof incode);
    memset((void *) &outcode, 0, sizeof outcode);
    incode.CCSID = inccsid;
    outcode.CCSID = outccsid;
    curlen = OFFSET_OF(libssh2_string_cache, string);
    inp = (char *) instring;
    ilen = inlen;
    buflen = inlen + curlen;
    if (inlen < 0) {
        incode.length_option = 1;
        buflen = STRING_GRANULE;
        ilen = 0;
    }

    /* Allocate output string buffer and open conversion descriptor. */
    dst = LIBSSH2_ALLOC(session, buflen + termsize);
    if (!dst)
        return NULL;
    cd = QtqIconvOpen(&outcode, &incode);
    if (cd.return_value == -1) {
        LIBSSH2_FREE(session, (char *) dst);
        return NULL;
    }

    /* Convert string. */
    for (;;) {
        outp = dst + curlen;
        olen = buflen - curlen;
        i = iconv(cd, &inp, &ilen, &outp, &olen);
        if (inlen < 0 && olen == buflen - curlen) {
            /* Special case: converted 0-length (sub)strings do not store the
               terminator. */
            if (termsize) {
                memset(outp, 0, termsize);
                olen -= termsize;
            }
        }
        curlen = buflen - olen;
        if (i >= 0 || errno != E2BIG)
            break;
        /* Must expand buffer. */
        buflen += STRING_GRANULE;
        outp = LIBSSH2_REALLOC(session, dst, buflen + termsize);
        if (!outp)
            break;
        dst = outp;
    }

    iconv_close(cd);

    /* Check for error. */
    if (i < 0 || !outp) {
        LIBSSH2_FREE(session, dst);
        return NULL;
    }

    /* Process terminator. */
    if (inlen < 0)
        curlen -= termsize;
    else if (termsize)
        memset(dst + curlen, 0, termsize);

    /* Shorten buffer if possible. */
    if (curlen < buflen)
        dst = LIBSSH2_REALLOC(session, dst, curlen + termsize);

    /* Link to cache. */
    outstring = (libssh2_string_cache *) dst;
    outstring->next = *cache;
    *cache = outstring;

    /* Return length if required. */
    if (outlen)
        *outlen = curlen - OFFSET_OF(libssh2_string_cache, string);

    return outstring->string;
}