Example #1
0
/* Process a buffer of PCL XL commands. */
int
px_process(px_parser_state_t * st, px_state_t * pxs, stream_cursor_read * pr)
{
    const byte *orig_p = pr->ptr;
    const byte *next_p = orig_p;        /* start of data not copied to saved */
    const byte *p;
    const byte *rlimit;
    px_value_t *sp = &st->stack[st->stack_count];

#define stack_limit &st->stack[max_stack - 1]
    gs_memory_t *memory = st->memory;
    int code = 0;
    uint left;
    uint min_left;
    px_tag_t tag;
    const px_tag_syntax_t *syntax = 0;

    st->args.parser = st;
    st->parent_operator_count = 0;      /* in case of error */
    /* Check for leftover data from the previous call. */
  parse:if (st->saved_count) { /* Fill up the saved buffer so we can make progress. */
        int move = min(sizeof(st->saved) - st->saved_count,
                       pr->limit - next_p);

        memcpy(&st->saved[st->saved_count], next_p + 1, move);
        next_p += move;
        p = st->saved - 1;
        rlimit = p + st->saved_count + move;
    } else {                    /* No leftover data, just read from the input. */
        p = next_p;
        rlimit = pr->limit;
    }
  top:if (st->data_left) {     /* We're in the middle of reading an array or data block. */
        if (st->data_proc) {    /* This is a data block. */
            uint avail = min(rlimit - p, st->data_left);
            uint used;

            st->args.source.available = avail;
            st->args.source.data = p + 1;
            code = (*st->data_proc) (&st->args, pxs);
            /* If we get a 'remap_color' error, it means we are dealing with a
             * pattern, and the device supports high level patterns. So we must
             * use our high level pattern implementation.
             */
            if (code == gs_error_Remap_Color) {
                code = px_high_level_pattern(pxs->pgs);
                code = (*st->data_proc) (&st->args, pxs);
            }
            used = st->args.source.data - (p + 1);
#ifdef DEBUG
            if (gs_debug_c('I')) {
                px_value_t data_array;

                data_array.type = pxd_ubyte;
                data_array.value.array.data = p + 1;
                data_array.value.array.size = used;
                trace_array_data(pxs->memory, "data:", &data_array);
            }
#endif
            p = st->args.source.data - 1;
            st->data_left -= used;
            if (code < 0) {
                st->args.source.position = 0;
                goto x;
            } else if ((code == pxNeedData)
                       || (code == pxPassThrough && st->data_left != 0)) {
                code = 0;       /* exit for more data */
                goto x;
            } else {
                st->args.source.position = 0;
                st->data_proc = 0;
                if (st->data_left != 0) {
                    code = gs_note_error(errorExtraData);
                    goto x;
                }
                clear_stack();
            }
        } else {                /* This is an array. */
            uint size = sp->value.array.size;
            uint scale = value_size(sp);
            uint nbytes = size * scale;
            byte *dest =
                (byte *) sp->value.array.data + nbytes - st->data_left;

            left = rlimit - p;
            if (left < st->data_left) { /* We still don't have enough data to fill the array. */
                memcpy(dest, p + 1, left);
                st->data_left -= left;
                p = rlimit;
                code = 0;
                goto x;
            }
            /* Complete the array and continue parsing. */
            memcpy(dest, p + 1, st->data_left);
            trace_array(memory, sp);
            p += st->data_left;
        }
        st->data_left = 0;
    } else if (st->data_proc) { /* An operator is awaiting data. */
        /* Skip white space until we find some. */
        code = 0;               /* in case we exit */
        /* special case - VendorUnique has a length attribute which
           we've already parsed and error checked */
        if (st->data_proc == pxVendorUnique) {
            st->data_left =
                st->stack[st->attribute_indices[pxaVUDataLength]].value.i;
            goto top;
        } else {
            while ((left = rlimit - p) != 0) {
                switch ((tag = p[1])) {
                case pxtNull:
                case pxtHT:
                case pxtLF:
                case pxtVT:
                case pxtFF:
                case pxtCR:
                    ++p;
                    continue;
                case pxt_dataLength:
                    if (left < 5)
                        goto x; /* can't look ahead */
                    st->data_left = get_uint32(st, p + 2);
                    if_debug2m('i', memory, "tag=  0x%2x  data, length %u\n",
                               p[1], st->data_left);
                    p += 5;
                    goto top;
                case pxt_dataLengthByte:
                    if (left < 2)
                        goto x; /* can't look ahead */
                    st->data_left = p[2];
                    if_debug2m('i', memory, "tag=  0x%2x  data, length %u\n",
                               p[1], st->data_left);
                    p += 2;
                    goto top;
                default:
                    {
                        code = gs_note_error(errorMissingData);
                        goto x;
                    }
                }
            }
        }
    }
    st->args.source.position = 0;
    st->args.source.available = 0;
    while ((left = rlimit - p) != 0 &&
           left >= (min_left = (syntax = &tag_syntax[tag = p[1]])->min_input)
        ) {
        int count;

#ifdef DEBUG
        if (gs_debug_c('i')) {
            dmprintf1(memory, "tag=  0x%02x  ", tag);
            if (tag == pxt_attr_ubyte || tag == pxt_attr_uint16) {
                px_attribute_t attr =
                    (tag == pxt_attr_ubyte ? p[2] : get_uint16(st, p + 2));
                const char *aname = px_attribute_names[attr];

                if (aname)
                    dmprintf1(memory, "   @%s\n", aname);
                else
                    dmprintf1(memory, "   attribute %u ???\n", attr);
            } else {
                const char *format;
                const char *tname;
                bool operator = false;

                if (tag < 0x40)
                    format = "%s\n", tname = px_tag_0_names[tag];
                else if (tag < 0xc0)
                    format = "%s", tname = px_operator_names[tag - 0x40],
                        operator = true;
                else {
                    tname = px_tag_c0_names[tag - 0xc0];
                    if (tag < 0xf0)
                        format = "      %s";    /* data values follow */
                    else
                        format = "%s\n";
                }
                if (tname) {
                    dmprintf1(memory, format, tname);
                    if (operator)
                        dmprintf1(memory, " (%ld)\n", st->operator_count + 1);
                } else
                    dmputs(memory, "???\n");
            }
        }
#endif
        if ((st->macro_state & syntax->state_mask) != syntax->state_value) {
            /*
             * We should probably distinguish here between
             * out-of-context operators and illegal tags, but it's too
             * much trouble.
             */
            code = gs_note_error(errorIllegalOperatorSequence);
            if (tag >= 0x40 && tag < 0xc0)
                st->last_operator = tag;
            goto x;
        }
        st->macro_state ^= syntax->state_transition;
        switch (tag >> 3) {
            case 0:
                switch (tag) {
                    case pxtNull:
                        ++p;
                        continue;
                    default:
                        break;
                }
                break;
            case 1:
                switch (tag) {
                    case pxtHT:
                    case pxtLF:
                    case pxtVT:
                    case pxtFF:
                    case pxtCR:
                        ++p;
                        continue;
                    default:
                        break;
                }
                break;
            case 3:
                if (tag == pxt1b) {     /* ESC *//* Check for UEL */
                    if (memcmp(p + 1, "\033%-12345X", min(left, 9)))
                        break;  /* not UEL, error */
                    if (left < 9)
                        goto x; /* need more data */
                    p += 9;
                    code = e_ExitLanguage;
                    goto x;
                }
                break;
            case 4:
                switch (tag) {
                    case pxtSpace:
                        /* break; will error, compatible with lj */
                        /* ++p;continue; silently ignores the space */
                        ++p;
                        continue;
                    default:
                        break;
                }
                break;
            case 8:
            case 9:
            case 10:
            case 11:
            case 12:
            case 13:
            case 14:
            case 15:
            case 16:
            case 17:
            case 18:
            case 19:
            case 20:
            case 21:
            case 22:
            case 23:
                /* Operators */
                /* Make sure that we have all the required attributes, */
                /* and no attributes that are neither required nor */
                /* optional.  (It's up to the operator to make any */
                /* more precise checks than this. */
                st->operator_count++;
                /* if this is a passthrough operator we have to tell
                   the passthrough module if this operator was
                   preceded by another passthrough operator or a
                   different xl operator */
                if (tag == pxtPassThrough) {
                    pxpcl_passthroughcontiguous(st->last_operator == tag);
                } else if (st->last_operator == pxtPassThrough) {
                    pxpcl_endpassthroughcontiguous(pxs);
                }

                st->last_operator = tag;
                {
                    const px_operator_definition_t *pod =
                        &px_operator_definitions[tag - 0x40];
                    int left = sp - st->stack;
                    const byte /*px_attribute_t */  * pal = pod->attrs;
                    px_value_t **ppv = st->args.pv;
                    bool required = true;
                    code = 0;
                    /*
                     * Scan the attributes.  Illegal attributes take priority
                     * over missing attributes, which in turn take priority
                     * over illegal data types.
                     */
                    for (;; ++pal, ++ppv) {
                        px_attribute_t attr = *pal;
                        uint index;

                        if (!attr) {    /*
                                         * We've reached the end of either the required or
                                         * the optional attribute list.
                                         */
                            if (!required)
                                break;
                            required = false;
                            --ppv;      /* cancel incrementing */
                            continue;
                        }
                        if ((index = st->attribute_indices[attr]) == 0) {
                            if (required)
                                code = gs_note_error(errorMissingAttribute);
                            else
                                *ppv = 0;
                        } else {        /* Check the attribute data type and value. */
                            px_value_t *pv = *ppv = &st->stack[index];
                            const px_attr_value_type_t *pavt =
                                &px_attr_value_types[attr];
                            int acode;

                            if ((~pavt->mask & pv->type &
                                 (pxd_structure | pxd_representation)) ||
                                (pavt->mask == (pxd_scalar | pxd_ubyte) &&
                                 (pv->value.i < 0
                                  || pv->value.i > pavt->limit))
                                ) {
                                if (code >= 0)
                                    code =
                                        gs_note_error
                                        (errorIllegalAttributeDataType);
                            }
                            if (pavt->proc != 0
                                && (acode = (*pavt->proc) (pv)) < 0) {
                                if (code >= 0)
                                    code = acode;
                            }
                            --left;
                        }
                    }

                    /* Make sure there are no attributes left over. */
                    if (left)
                        code = gs_note_error(errorIllegalAttribute);
                    if (code >= 0) {
                        st->args.source.phase = 0;
                        code = (*pod->proc) (&st->args, pxs);
                        /* If we get a 'remap_color' error, it means we are dealing with a
                         * pattern, and the device supports high level patterns. So we must
                         * use our high level pattern implementation.
                         */
                        if (code == gs_error_Remap_Color) {
                            code = px_high_level_pattern(pxs->pgs);
                            if (code < 0)
                                goto x;
                            code = (*pod->proc) (&st->args, pxs);
                        }
                    }
                    if (code < 0)
                        goto x;
                    /* Check whether the operator wanted source data. */
                    if (code == pxNeedData) {
                        if (!pxs->data_source_open) {
                            code = gs_note_error(errorDataSourceNotOpen);
                            goto x;
                        }
                        st->data_proc = pod->proc;
                        ++p;
                        goto top;
                    }
                }
                clear_stack();
                ++p;
                continue;
            case 24:
                sp[1].type = pxd_scalar;
                count = 1;
                goto data;
            case 26:
                sp[1].type = pxd_xy;
                count = 2;
                goto data;
            case 28:
                sp[1].type = pxd_box;
                count = 4;
                goto data;
                /* Scalar, point, and box data */
              data:{
                    int i;

                    if (sp == stack_limit) {
                        code = gs_note_error(errorInternalOverflow);
                        goto x;
                    }
                    ++sp;
                    sp->attribute = 0;
                    p += 2;
#ifdef DEBUG
#  define trace_scalar(mem, format, cast, alt)\
                  if ( gs_debug_c('i') )\
                    trace_data(mem, format, cast, sp->value.alt, count)
#else
#  define trace_scalar(mem, format, cast, alt) DO_NOTHING
#endif
                    switch (tag & 7) {
                        case pxt_ubyte & 7:
                            sp->type |= pxd_ubyte;
                            for (i = 0; i < count; ++p, ++i)
                                sp->value.ia[i] = *p;
                          dux:trace_scalar(pxs->memory, " %lu", ulong,
                                         ia);
                            --p;
                            continue;
                        case pxt_uint16 & 7:
                            sp->type |= pxd_uint16;
                            for (i = 0; i < count; p += 2, ++i)
                                sp->value.ia[i] = get_uint16(st, p);
                            goto dux;
                        case pxt_uint32 & 7:
                            sp->type |= pxd_uint32;
                            for (i = 0; i < count; p += 4, ++i)
                                sp->value.ia[i] = get_uint32(st, p);
                            goto dux;
                        case pxt_sint16 & 7:
                            sp->type |= pxd_sint16;
                            for (i = 0; i < count; p += 2, ++i)
                                sp->value.ia[i] = get_sint16(st, p);
                          dsx:trace_scalar(pxs->memory, " %ld", long,
                                         ia);
                            --p;
                            continue;
                        case pxt_sint32 & 7:
                            sp->type |= pxd_sint32;
                            for (i = 0; i < count; p += 4, ++i)
                                sp->value.ia[i] = get_sint32(st, p);
                            goto dsx;
                        case pxt_real32 & 7:
                            sp->type |= pxd_real32;
                            for (i = 0; i < count; p += 4, ++i)
                                sp->value.ra[i] = get_real32(st, p);
                            trace_scalar(pxs->memory, " %g", double, ra);

                            --p;
                            continue;
                        default:
                            break;
                    }
                }
                break;
            case 25:
                /* Array data */
                {
                    const byte *dp;
                    uint nbytes;

                    if (sp == stack_limit) {
                        code = gs_note_error(errorInternalOverflow);
                        goto x;
                    }
                    switch (p[2]) {
                        case pxt_ubyte:
                            sp[1].value.array.size = p[3];
                            dp = p + 4;
                            break;
                        case pxt_uint16:
                            if (left < 4) {
                                if_debug0m('i', memory, "...\n");
                                /* Undo the state transition. */
                                st->macro_state ^= syntax->state_transition;
                                goto x;
                            }
                            sp[1].value.array.size = get_uint16(st, p + 3);
                            dp = p + 5;
                            break;
                        default:
                            st->last_operator = tag;    /* for error message */
                            code = gs_note_error(errorIllegalTag);
                            goto x;
                    }
                    nbytes = sp[1].value.array.size;
                    if_debug1m('i', memory, "[%u]\n", sp[1].value.array.size);
                    switch (tag) {
                        case pxt_ubyte_array:
                            sp[1].type = pxd_array | pxd_ubyte;
                          array:++sp;
                            if (st->big_endian)
                                sp->type |= pxd_big_endian;
                            sp->value.array.data = dp;
                            sp->attribute = 0;
                            /* Check whether we have enough data for the entire */
                            /* array. */
                            if (rlimit + 1 - dp < nbytes) {     /* Exit now, continue reading when we return. */
                                uint avail = rlimit + 1 - dp;

                                code = px_save_array(sp, pxs, "partial array",
                                                     avail);
                                if (code < 0)
                                    goto x;
                                sp->type |= pxd_on_heap;
                                st->data_left = nbytes - avail;
                                st->data_proc = 0;
                                p = rlimit;
                                goto x;
                            }
                            p = dp + nbytes - 1;
                            trace_array(memory, sp);
                            continue;
                        case pxt_uint16_array:
                            sp[1].type = pxd_array | pxd_uint16;
                          a16:nbytes <<= 1;
                            goto array;
                        case pxt_uint32_array:
                            sp[1].type = pxd_array | pxd_uint32;
                          a32:nbytes <<= 2;
                            goto array;
                        case pxt_sint16_array:
                            sp[1].type = pxd_array | pxd_sint16;
                            goto a16;
                        case pxt_sint32_array:
                            sp[1].type = pxd_array | pxd_sint32;
                            goto a32;
                        case pxt_real32_array:
                            sp[1].type = pxd_array | pxd_real32;
                            goto a32;
                        default:
                            break;
                    }
                    break;
                }
                break;
            case 31:
                {
                    px_attribute_t attr;
                    const byte *pnext;

                    switch (tag) {
                        case pxt_attr_ubyte:
                            attr = p[2];
                            pnext = p + 2;
                            goto a;
                        case pxt_attr_uint16:
                            attr = get_uint16(st, p + 2);
                            pnext = p + 3;
                          a:if (attr >=
                                px_attribute_next)
                                break;
                            /*
                             * We could check the attribute value type here, but
                             * in order to match the behavior of the H-P printers,
                             * we don't do it until we see the operator.
                             *
                             * It is legal to specify the same attribute more than
                             * once; the last value has priority.  If this happens,
                             * since the order of attributes doesn't matter, we can
                             * just replace the former value on the stack.
                             */
                            sp->attribute = attr;
                            if (st->attribute_indices[attr] != 0) {
                                px_value_t *old_sp =
                                    &st->stack[st->attribute_indices[attr]];
                                /* If the old value is on the heap, free it. */
                                if (old_sp->type & pxd_on_heap)
                                    gs_free_object(memory,
                                                   (void *)old_sp->value.
                                                   array.data,
                                                   "old value for duplicate attribute");
                                *old_sp = *sp--;
                            } else
                                st->attribute_indices[attr] = sp - st->stack;
                            p = pnext;
                            continue;
                        case pxt_dataLength:
                            /*
                             * Unexpected data length operators are normally not
                             * allowed, but there might be a zero-length data
                             * block immediately following a zero-size image,
                             * which doesn't ask for any data.
                             */
                            if (uint32at(p + 2, true /*arbitrary */ ) == 0) {
                                p += 5;
                                continue;
                            }
                            break;
                        case pxt_dataLengthByte:
                            /* See the comment under pxt_dataLength above. */
                            if (p[2] == 0) {
                                p += 2;
                                continue;
                            }
                            break;
                        default:
                            break;
                    }
                }
                break;
            default:
                break;
        }
        /* Unknown tag value.  Report an error. */
        st->last_operator = tag;        /* for error message */
        code = gs_note_error(errorIllegalTag);
        break;
    }
  x:                           /* Save any leftover input. */
    left = rlimit - p;
    if (rlimit != pr->limit) {  /* We were reading saved input. */
        if (left <= next_p - orig_p) {  /* We finished reading the previously saved input. */
            /* Continue reading current input, unless we got an error. */
            p = next_p -= left;
            rlimit = pr->limit;
            st->saved_count = 0;
            if (code >= 0)
                goto parse;
        } else {                /* There's still some previously saved input left over. */
            memmove(st->saved, p + 1, st->saved_count = left);
            p = next_p;
            rlimit = pr->limit;
            left = rlimit - p;
        }
    }
    /* Except in case of error, save any remaining input. */
    if (code >= 0) {
        if (left + st->saved_count > sizeof(st->saved)) {       /* Fatal error -- shouldn't happen! */
            code = gs_note_error(errorInternalOverflow);
            st->saved_count = 0;
        } else {
            memcpy(&st->saved[st->saved_count], p + 1, left);
            st->saved_count += left;
            p = rlimit;
        }
    }
    pr->ptr = p;
    st->stack_count = sp - st->stack;
    /* Move to the heap any arrays whose data was being referenced */
    /* directly in the input buffer. */
    for (; sp > st->stack; --sp)
        if ((sp->type & (pxd_array | pxd_on_heap)) == pxd_array) {
            int code = px_save_array(sp, pxs, "px stack array to heap",
                                     sp->value.array.size * value_size(sp));

            if (code < 0)
                break;
            sp->type |= pxd_on_heap;
        }
    if (code < 0 && syntax != 0) {      /* Undo the state transition. */
        st->macro_state ^= syntax->state_transition;
    }
    return code;
}
Example #2
0
/** Based on our interval and our estimated bandwidth, choose a
 * deterministic (but random-ish) time to wake up. */
static void
accounting_set_wakeup_time(void)
{
  char buf[ISO_TIME_LEN+1];
  char digest[DIGEST_LEN];
  crypto_digest_env_t *d_env;
  int time_in_interval;
  uint64_t time_to_exhaust_bw;
  int time_to_consider;

  if (! identity_key_is_set()) {
    if (init_keys() < 0) {
      log_err(LD_BUG, "Error initializing keys");
      tor_assert(0);
    }
  }

  format_iso_time(buf, interval_start_time);
  crypto_pk_get_digest(get_identity_key(), digest);

  d_env = crypto_new_digest_env();
  crypto_digest_add_bytes(d_env, buf, ISO_TIME_LEN);
  crypto_digest_add_bytes(d_env, digest, DIGEST_LEN);
  crypto_digest_get_digest(d_env, digest, DIGEST_LEN);
  crypto_free_digest_env(d_env);

  if (!expected_bandwidth_usage) {
    char buf1[ISO_TIME_LEN+1];
    char buf2[ISO_TIME_LEN+1];
    format_local_iso_time(buf1, interval_start_time);
    format_local_iso_time(buf2, interval_end_time);
    time_to_exhaust_bw = GUESS_TIME_TO_USE_BANDWIDTH;
    interval_wakeup_time = interval_start_time;

    log_notice(LD_ACCT,
           "Configured hibernation.  This interval begins at %s "
           "and ends at %s.  We have no prior estimate for bandwidth, so "
           "we will start out awake and hibernate when we exhaust our quota.",
           buf1, buf2);
    return;
  }

  time_in_interval = (int)(interval_end_time - interval_start_time);

  time_to_exhaust_bw =
    (get_options()->AccountingMax/expected_bandwidth_usage)*60;
  if (time_to_exhaust_bw > TIME_MAX) {
    time_to_exhaust_bw = TIME_MAX;
    time_to_consider = 0;
  } else {
    time_to_consider = time_in_interval - (int)time_to_exhaust_bw;
  }

  if (time_to_consider<=0) {
    interval_wakeup_time = interval_start_time;
  } else {
    /* XXX can we simplify this just by picking a random (non-deterministic)
     * time to be up? If we go down and come up, then we pick a new one. Is
     * that good enough? -RD */

    /* This is not a perfectly unbiased conversion, but it is good enough:
     * in the worst case, the first half of the day is 0.06 percent likelier
     * to be chosen than the last half. */
    interval_wakeup_time = interval_start_time +
      (get_uint32(digest) % time_to_consider);

    format_iso_time(buf, interval_wakeup_time);
  }

  {
    char buf1[ISO_TIME_LEN+1];
    char buf2[ISO_TIME_LEN+1];
    char buf3[ISO_TIME_LEN+1];
    char buf4[ISO_TIME_LEN+1];
    time_t down_time;
    if (interval_wakeup_time+time_to_exhaust_bw > TIME_MAX)
      down_time = TIME_MAX;
    else
      down_time = (time_t)(interval_wakeup_time+time_to_exhaust_bw);
    if (down_time>interval_end_time)
      down_time = interval_end_time;
    format_local_iso_time(buf1, interval_start_time);
    format_local_iso_time(buf2, interval_wakeup_time);
    format_local_iso_time(buf3, down_time);
    format_local_iso_time(buf4, interval_end_time);

    log_notice(LD_ACCT,
           "Configured hibernation.  This interval began at %s; "
           "the scheduled wake-up time %s %s; "
           "we expect%s to exhaust our quota for this interval around %s; "
           "the next interval begins at %s (all times local)",
           buf1,
           time(NULL)<interval_wakeup_time?"is":"was", buf2,
           time(NULL)<down_time?"":"ed", buf3,
           buf4);
  }
}
static int get_int32(void)
{
  return (int)get_uint32();
}
Example #4
0
/** Unpack <b>tag</b> into addr, port, and circ_id.
 */
static void
tag_unpack(const uint8_t *tag, uint64_t *chan_id, circid_t *circ_id)
{
  *chan_id = get_uint64(tag);
  *circ_id = get_uint32(tag+8);
}
Example #5
0
gchar* DictBase::GetWordData(guint32 idxitem_offset, guint32 idxitem_size)
{
	for (int i=0; i<WORDDATA_CACHE_NUM; i++)
		if (cache[i].data && cache[i].offset == idxitem_offset)
			return cache[i].data;

	if (dictfile)
		fseek(dictfile, idxitem_offset, SEEK_SET);

	gchar *data;
	if (!sametypesequence.empty()) {
		gchar *origin_data = (gchar *)g_malloc(idxitem_size);

		if (dictfile)
			fread(origin_data, idxitem_size, 1, dictfile);
		else
			dictdzfile->read(origin_data, idxitem_offset, idxitem_size);

		guint32 data_size;
		gint sametypesequence_len = sametypesequence.length();
		//there have sametypesequence_len char being omitted.
		data_size = idxitem_size + sametypesequence_len; //Here is a bug fix of 2.4.8, which don't add sizeof(guint32) anymore.

		//if the last item's size is determined by the end up '\0',then +=sizeof(gchar);
		//if the last item's size is determined by the head guint32 type data,then +=sizeof(guint32);
		switch (sametypesequence[sametypesequence_len-1]) {
		case 'm':
		case 't':
		case 'y':
		case 'l':
		case 'g':
		case 'x':
		case 'k':
		case 'w':
			data_size += sizeof(gchar);
			break;
		case 'W':
		case 'P':
			data_size += sizeof(guint32);
			break;
		default:
			if (g_ascii_isupper(sametypesequence[sametypesequence_len-1]))
				data_size += sizeof(guint32);
			else
				data_size += sizeof(gchar);
			break;
		}
		data = (gchar *)g_malloc(data_size + sizeof(guint32));
		gchar *p1,*p2;
		p1 = data + sizeof(guint32);
		p2 = origin_data;
		guint32 sec_size;
		//copy the head items.
		for (int i=0; i<sametypesequence_len-1; i++) {
			*p1=sametypesequence[i];
			p1+=sizeof(gchar);
			switch (sametypesequence[i]) {
			case 'm':
			case 't':
			case 'y':
			case 'l':
			case 'g':
			case 'x':
			case 'k':
			case 'w':
				sec_size = strlen(p2)+1;
				memcpy(p1, p2, sec_size);
				p1+=sec_size;
				p2+=sec_size;
				break;
			case 'W':
			case 'P':
				sec_size = get_uint32(p2);
				sec_size += sizeof(guint32);
				memcpy(p1, p2, sec_size);
				p1+=sec_size;
				p2+=sec_size;
				break;
			default:
				if (g_ascii_isupper(sametypesequence[i])) {
					sec_size = get_uint32(p2);
					sec_size += sizeof(guint32);
				} else {
					sec_size = strlen(p2)+1;
				}
				memcpy(p1, p2, sec_size);
				p1+=sec_size;
				p2+=sec_size;
				break;
			}
		}
		//calculate the last item 's size.
		sec_size = idxitem_size - (p2-origin_data);
		*p1=sametypesequence[sametypesequence_len-1];
		p1+=sizeof(gchar);
		switch (sametypesequence[sametypesequence_len-1]) {
		case 'm':
		case 't':
		case 'y':
		case 'l':
		case 'g':
		case 'x':
		case 'k':
		case 'w':
			memcpy(p1, p2, sec_size);
			p1 += sec_size;
			*p1='\0';//add the end up '\0';
			break;
		case 'W':
		case 'P':
			memcpy(p1, &sec_size, sizeof(guint32));
			p1 += sizeof(guint32);
			memcpy(p1, p2, sec_size);
			break;
		default:
			if (g_ascii_isupper(sametypesequence[sametypesequence_len-1])) {
				memcpy(p1, &sec_size, sizeof(guint32));
				p1 += sizeof(guint32);
				memcpy(p1, p2, sec_size);
			} else {
				memcpy(p1, p2, sec_size);
				p1 += sec_size;
				*p1='\0';
			}
			break;
		}
		g_free(origin_data);
		memcpy(data, &data_size, sizeof(guint32));
	} else {
		data = (gchar *)g_malloc(idxitem_size + sizeof(guint32));
		if (dictfile)
			fread(data+sizeof(guint32), idxitem_size, 1, dictfile);
		else
			dictdzfile->read(data+sizeof(guint32), idxitem_offset, idxitem_size);
		memcpy(data, &idxitem_size, sizeof(guint32));
	}
	g_free(cache[cache_cur].data);

	cache[cache_cur].data = data;
	cache[cache_cur].offset = idxitem_offset;
	cache_cur++;
	if (cache_cur==WORDDATA_CACHE_NUM)
		cache_cur = 0;
	return data;
}
Example #6
0
/* Reads an existing .mo file and adds the messages to mlp.  */
void
read_mo_file (message_list_ty *mlp, const char *filename)
{
  FILE *fp;
  struct binary_mo_file bf;
  struct mo_file_header header;
  unsigned int i;
  static lex_pos_ty pos = { __FILE__, __LINE__ };

  if (strcmp (filename, "-") == 0 || strcmp (filename, "/dev/stdin") == 0)
    {
      fp = stdin;
      SET_BINARY (fileno (fp));
    }
  else
    {
      fp = fopen (filename, "rb");
      if (fp == NULL)
	error (EXIT_FAILURE, errno,
	       _("error while opening \"%s\" for reading"), filename);
    }

  /* Read the file contents into memory.  */
  read_binary_mo_file (&bf, fp, filename);

  /* Get a 32-bit number from the file header.  */
# define GET_HEADER_FIELD(field) \
    get_uint32 (&bf, offsetof (struct mo_file_header, field))

  /* We must grope the file to determine which endian it is.
     Perversity of the universe tends towards maximum, so it will
     probably not match the currently executing architecture.  */
  bf.endian = MO_BIG_ENDIAN;
  header.magic = GET_HEADER_FIELD (magic);
  if (header.magic != _MAGIC)
    {
      bf.endian = MO_LITTLE_ENDIAN;
      header.magic = GET_HEADER_FIELD (magic);
      if (header.magic != _MAGIC)
	{
	unrecognised:
	  error (EXIT_FAILURE, 0, _("file \"%s\" is not in GNU .mo format"),
		 filename);
	}
    }

  header.revision = GET_HEADER_FIELD (revision);

  /* We support only the major revisions 0 and 1.  */
  switch (header.revision >> 16)
    {
    case 0:
    case 1:
      /* Fill the header parts that apply to major revisions 0 and 1.  */
      header.nstrings = GET_HEADER_FIELD (nstrings);
      header.orig_tab_offset = GET_HEADER_FIELD (orig_tab_offset);
      header.trans_tab_offset = GET_HEADER_FIELD (trans_tab_offset);
      header.hash_tab_size = GET_HEADER_FIELD (hash_tab_size);
      header.hash_tab_offset = GET_HEADER_FIELD (hash_tab_offset);

      for (i = 0; i < header.nstrings; i++)
	{
	  message_ty *mp;
	  char *msgid;
	  size_t msgid_len;
	  char *msgstr;
	  size_t msgstr_len;

	  /* Read the msgid.  */
	  msgid = get_string (&bf, header.orig_tab_offset + i * 8,
			      &msgid_len);

	  /* Read the msgstr.  */
	  msgstr = get_string (&bf, header.trans_tab_offset + i * 8,
			       &msgstr_len);

	  mp = message_alloc (msgid,
			      (strlen (msgid) + 1 < msgid_len
			       ? msgid + strlen (msgid) + 1
			       : NULL),
			      msgstr, msgstr_len,
			      &pos);
	  message_list_append (mlp, mp);
	}

      switch (header.revision & 0xffff)
	{
	case 0:
	  break;
	case 1:
	default:
	  /* Fill the header parts that apply to minor revision >= 1.  */
	  header.n_sysdep_segments = GET_HEADER_FIELD (n_sysdep_segments);
	  header.sysdep_segments_offset =
	    GET_HEADER_FIELD (sysdep_segments_offset);
	  header.n_sysdep_strings = GET_HEADER_FIELD (n_sysdep_strings);
	  header.orig_sysdep_tab_offset =
	    GET_HEADER_FIELD (orig_sysdep_tab_offset);
	  header.trans_sysdep_tab_offset =
	    GET_HEADER_FIELD (trans_sysdep_tab_offset);

	  for (i = 0; i < header.n_sysdep_strings; i++)
	    {
	      message_ty *mp;
	      char *msgid;
	      size_t msgid_len;
	      char *msgstr;
	      size_t msgstr_len;
	      nls_uint32 offset;

	      /* Read the msgid.  */
	      offset = get_uint32 (&bf, header.orig_sysdep_tab_offset + i * 4);
	      msgid = get_sysdep_string (&bf, offset, &header, &msgid_len);

	      /* Read the msgstr.  */
	      offset = get_uint32 (&bf, header.trans_sysdep_tab_offset + i * 4);
	      msgstr = get_sysdep_string (&bf, offset, &header, &msgstr_len);

	      mp = message_alloc (msgid,
				  (strlen (msgid) + 1 < msgid_len
				   ? msgid + strlen (msgid) + 1
				   : NULL),
				  msgstr, msgstr_len,
				  &pos);
	      message_list_append (mlp, mp);
	    }
	  break;
	}
      break;

    default:
      goto unrecognised;
    }

  if (fp != stdin)
    fclose (fp);
}
Example #7
0
/*
   read_directory(archive) -> files dict (new reference)

   Given a path to a Zip archive, build a dict, mapping file names
   (local to the archive, using SEP as a separator) to toc entries.

   A toc_entry is a tuple:

   (__file__,      # value to use for __file__, available for all files,
                   # encoded to the filesystem encoding
    compress,      # compression kind; 0 for uncompressed
    data_size,     # size of compressed data on disk
    file_size,     # size of decompressed data
    file_offset,   # offset of file header from start of archive
    time,          # mod time of file (in dos format)
    date,          # mod data of file (in dos format)
    crc,           # crc checksum of the data
   )

   Directories can be recognized by the trailing SEP in the name,
   data_size and file_offset are 0.
*/
static PyObject *
read_directory(PyObject *archive)
{
    PyObject *files = NULL;
    FILE *fp;
    unsigned short flags, compress, time, date, name_size;
    unsigned int crc, data_size, file_size, header_size, header_offset;
    unsigned long file_offset, header_position;
    unsigned long arc_offset;  /* Absolute offset to start of the zip-archive. */
    unsigned int count, i;
    unsigned char buffer[46];
    char name[MAXPATHLEN + 5];
    PyObject *nameobj = NULL;
    PyObject *path;
    const char *charset;
    int bootstrap;
    const char *errmsg = NULL;

    fp = _Py_fopen_obj(archive, "rb");
    if (fp == NULL) {
        if (PyErr_ExceptionMatches(PyExc_OSError)) {
            _PyErr_FormatFromCause(ZipImportError,
                                   "can't open Zip file: %R", archive);
        }
        return NULL;
    }

    if (fseek(fp, -22, SEEK_END) == -1) {
        goto file_error;
    }
    header_position = (unsigned long)ftell(fp);
    if (header_position == (unsigned long)-1) {
        goto file_error;
    }
    assert(header_position <= (unsigned long)LONG_MAX);
    if (fread(buffer, 1, 22, fp) != 22) {
        goto file_error;
    }
    if (get_uint32(buffer) != 0x06054B50u) {
        /* Bad: End of Central Dir signature */
        errmsg = "not a Zip file";
        goto invalid_header;
    }

    header_size = get_uint32(buffer + 12);
    header_offset = get_uint32(buffer + 16);
    if (header_position < header_size) {
        errmsg = "bad central directory size";
        goto invalid_header;
    }
    if (header_position < header_offset) {
        errmsg = "bad central directory offset";
        goto invalid_header;
    }
    if (header_position - header_size < header_offset) {
        errmsg = "bad central directory size or offset";
        goto invalid_header;
    }
    header_position -= header_size;
    arc_offset = header_position - header_offset;

    files = PyDict_New();
    if (files == NULL) {
        goto error;
    }
    /* Start of Central Directory */
    count = 0;
    if (fseek(fp, (long)header_position, 0) == -1) {
        goto file_error;
    }
    for (;;) {
        PyObject *t;
        size_t n;
        int err;

        n = fread(buffer, 1, 46, fp);
        if (n < 4) {
            goto eof_error;
        }
        /* Start of file header */
        if (get_uint32(buffer) != 0x02014B50u) {
            break;              /* Bad: Central Dir File Header */
        }
        if (n != 46) {
            goto eof_error;
        }
        flags = get_uint16(buffer + 8);
        compress = get_uint16(buffer + 10);
        time = get_uint16(buffer + 12);
        date = get_uint16(buffer + 14);
        crc = get_uint32(buffer + 16);
        data_size = get_uint32(buffer + 20);
        file_size = get_uint32(buffer + 24);
        name_size = get_uint16(buffer + 28);
        header_size = (unsigned int)name_size +
           get_uint16(buffer + 30) /* extra field */ +
           get_uint16(buffer + 32) /* comment */;

        file_offset = get_uint32(buffer + 42);
        if (file_offset > header_offset) {
            errmsg = "bad local header offset";
            goto invalid_header;
        }
        file_offset += arc_offset;

        if (name_size > MAXPATHLEN) {
            name_size = MAXPATHLEN;
        }
        if (fread(name, 1, name_size, fp) != name_size) {
            goto file_error;
        }
        name[name_size] = '\0';  /* Add terminating null byte */
#if SEP != '/'
        for (i = 0; i < name_size; i++) {
            if (name[i] == '/') {
                name[i] = SEP;
            }
        }
#endif
        /* Skip the rest of the header.
         * On Windows, calling fseek to skip over the fields we don't use is
         * slower than reading the data because fseek flushes stdio's
         * internal buffers.  See issue #8745. */
        assert(header_size <= 3*0xFFFFu);
        for (i = name_size; i < header_size; i++) {
            if (getc(fp) == EOF) {
                goto file_error;
            }
        }

        bootstrap = 0;
        if (flags & 0x0800) {
            charset = "utf-8";
        }
        else if (!PyThreadState_GET()->interp->codecs_initialized) {
            /* During bootstrap, we may need to load the encodings
               package from a ZIP file. But the cp437 encoding is implemented
               in Python in the encodings package.

               Break out of this dependency by assuming that the path to
               the encodings module is ASCII-only. */
            charset = "ascii";
            bootstrap = 1;
        }
        else {
            charset = "cp437";
        }
        nameobj = PyUnicode_Decode(name, name_size, charset, NULL);
        if (nameobj == NULL) {
            if (bootstrap) {
                PyErr_Format(PyExc_NotImplementedError,
                    "bootstrap issue: python%i%i.zip contains non-ASCII "
                    "filenames without the unicode flag",
                    PY_MAJOR_VERSION, PY_MINOR_VERSION);
            }
            goto error;
        }
        if (PyUnicode_READY(nameobj) == -1) {
            goto error;
        }
        path = PyUnicode_FromFormat("%U%c%U", archive, SEP, nameobj);
        if (path == NULL) {
            goto error;
        }
        t = Py_BuildValue("NHIIkHHI", path, compress, data_size,
                          file_size, file_offset, time, date, crc);
        if (t == NULL) {
            goto error;
        }
        err = PyDict_SetItem(files, nameobj, t);
        Py_CLEAR(nameobj);
        Py_DECREF(t);
        if (err != 0) {
            goto error;
        }
        count++;
    }
    fclose(fp);
    if (Py_VerboseFlag) {
        PySys_FormatStderr("# zipimport: found %u names in %R\n",
                           count, archive);
    }
    return files;

eof_error:
    set_file_error(archive, !ferror(fp));
    goto error;

file_error:
    PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
    goto error;

invalid_header:
    assert(errmsg != NULL);
    PyErr_Format(ZipImportError, "%s: %R", errmsg, archive);
    goto error;

error:
    fclose(fp);
    Py_XDECREF(files);
    Py_XDECREF(nameobj);
    return NULL;
}
Example #8
0
int xs::xrespondent_t::xsend (msg_t *msg_, int flags_)
{
    //  If this is the first part of the message it's the ID of the
    //  peer to send the message to.
    if (!more_out) {
        xs_assert (!current_out);

        //  If we have malformed message (prefix with no subsequent message)
        //  then just silently ignore it.
        //  TODO: The connections should be killed instead.
        if (msg_->flags () & msg_t::more && msg_->size () == 4) {

            more_out = true;

            //  Find the pipe associated with the identity stored in the prefix.
            //  If there's no such pipe just silently ignore the message.
            uint32_t identity = get_uint32 ((unsigned char*) msg_->data ());
            outpipes_t::iterator it = outpipes.find (identity);

            if (it != outpipes.end ()) {
                current_out = it->second.pipe;
                msg_t empty;
                int rc = empty.init ();
                errno_assert (rc == 0);
                if (!current_out->check_write (&empty)) {
                    it->second.active = false;
                    more_out = false;
                    current_out = NULL;
                }
                rc = empty.close ();
                errno_assert (rc == 0);
            }

        }

        int rc = msg_->close ();
        errno_assert (rc == 0);
        rc = msg_->init ();
        errno_assert (rc == 0);
        return 0;
    }

    //  Check whether this is the last part of the message.
    more_out = msg_->flags () & msg_t::more ? true : false;

    //  Push the message into the pipe. If there's no out pipe, just drop it.
    if (current_out) {
        bool ok = current_out->write (msg_);
        if (unlikely (!ok))
            current_out = NULL;
        else if (!more_out) {
            current_out->flush ();
            current_out = NULL;
        }
    }
    else {
        int rc = msg_->close ();
        errno_assert (rc == 0);
    }

    //  Detach the message from the data buffer.
    int rc = msg_->init ();
    errno_assert (rc == 0);

    return 0;
}
Example #9
0
/** Process a 'netinfo' cell: read and act on its contents, and set the
 * connection state to "open". */
static void
command_process_netinfo_cell(cell_t *cell, or_connection_t *conn)
{
  time_t timestamp;
  uint8_t my_addr_type;
  uint8_t my_addr_len;
  const char *my_addr_ptr;
  const char *cp, *end;
  uint8_t n_other_addrs;
  time_t now = time(NULL);

  long apparent_skew = 0;
  uint32_t my_apparent_addr = 0;

  if (conn->link_proto < 2) {
    log_fn(LOG_PROTOCOL_WARN, LD_OR,
           "Received a NETINFO cell on %s connection; dropping.",
           conn->link_proto == 0 ? "non-versioned" : "a v1");
    return;
  }
  if (conn->_base.state != OR_CONN_STATE_OR_HANDSHAKING) {
    log_fn(LOG_PROTOCOL_WARN, LD_OR,
           "Received a NETINFO cell on non-handshaking connection; dropping.");
    return;
  }
  tor_assert(conn->handshake_state &&
             conn->handshake_state->received_versions);
  /* Decode the cell. */
  timestamp = ntohl(get_uint32(cell->payload));
  if (labs(now - conn->handshake_state->sent_versions_at) < 180) {
    apparent_skew = now - timestamp;
  }

  my_addr_type = (uint8_t) cell->payload[4];
  my_addr_len = (uint8_t) cell->payload[5];
  my_addr_ptr = cell->payload + 6;
  end = cell->payload + CELL_PAYLOAD_SIZE;
  cp = cell->payload + 6 + my_addr_len;
  if (cp >= end) {
    log_fn(LOG_PROTOCOL_WARN, LD_OR,
           "Addresses too long in netinfo cell; closing connection.");
    connection_mark_for_close(TO_CONN(conn));
    return;
  } else if (my_addr_type == RESOLVED_TYPE_IPV4 && my_addr_len == 4) {
    my_apparent_addr = ntohl(get_uint32(my_addr_ptr));
  }

  n_other_addrs = (uint8_t) *cp++;
  while (n_other_addrs && cp < end-2) {
    /* Consider all the other addresses; if any matches, this connection is
     * "canonical." */
    tor_addr_t addr;
    const char *next = decode_address_from_payload(&addr, cp, (int)(end-cp));
    if (next == NULL) {
      log_fn(LOG_PROTOCOL_WARN,  LD_OR,
             "Bad address in netinfo cell; closing connection.");
      connection_mark_for_close(TO_CONN(conn));
      return;
    }
    if (tor_addr_eq(&addr, &conn->real_addr)) {
      conn->is_canonical = 1;
      break;
    }
    cp = next;
    --n_other_addrs;
  }

  /* Act on apparent skew. */
  /** Warn when we get a netinfo skew with at least this value. */
#define NETINFO_NOTICE_SKEW 3600
  if (labs(apparent_skew) > NETINFO_NOTICE_SKEW &&
      router_get_by_digest(conn->identity_digest)) {
    char dbuf[64];
    int severity;
    /*XXXX be smarter about when everybody says we are skewed. */
    if (router_digest_is_trusted_dir(conn->identity_digest))
      severity = LOG_WARN;
    else
      severity = LOG_INFO;
    format_time_interval(dbuf, sizeof(dbuf), apparent_skew);
    log_fn(severity, LD_GENERAL, "Received NETINFO cell with skewed time from "
           "server at %s:%d.  It seems that our clock is %s by %s, or "
           "that theirs is %s. Tor requires an accurate clock to work: "
           "please check your time and date settings.",
           conn->_base.address, (int)conn->_base.port,
           apparent_skew>0 ? "ahead" : "behind", dbuf,
           apparent_skew>0 ? "behind" : "ahead");
    if (severity == LOG_WARN) /* only tell the controller if an authority */
      control_event_general_status(LOG_WARN,
                          "CLOCK_SKEW SKEW=%ld SOURCE=OR:%s:%d",
                          apparent_skew,
                          conn->_base.address, conn->_base.port);
  }

  /* XXX maybe act on my_apparent_addr, if the source is sufficiently
   * trustworthy. */

  if (connection_or_set_state_open(conn)<0)
    connection_mark_for_close(TO_CONN(conn));
  else
    log_info(LD_OR, "Got good NETINFO cell from %s:%d; OR connection is now "
             "open, using protocol version %d",
             safe_str(conn->_base.address), conn->_base.port,
             (int)conn->link_proto);
  assert_connection_ok(TO_CONN(conn),time(NULL));
}
Example #10
0
// thread main!
int uart_win32_main(void* arg)
{
    dthread_t* self = (dthread_t*) arg;
    dthread_t* other = (dthread_t*) self->arg;
    dmessage_t* mp = NULL;
    dthread_poll_event_t ev[3];
    dthread_poll_event_t* evp;
    size_t nev;
    dterm_t term;
    uart_ctx_t ctx;
    ErlDrvTermData mp_from;
    ErlDrvTermData mp_ref;
    dthread_t*     mp_source;
    int tmo;
    int r;

    DEBUGF("uart_win32: thread started");

    uart_init(&ctx, self, other);

    dterm_init(&term);

again_tmo:
    tmo = next_timeout(&ctx);
again:
    nev = 0;

    if (ctx.writing) {
	ev[nev].event = (ErlDrvEvent) ctx.out.hEvent;
	ev[nev].events = ERL_DRV_READ; // yepp, even for write
	nev++;
    }

    while(!ctx.reading && (ctx.recv || (ctx.option.active != UART_PASSIVE)))
	process_input(&ctx, self, 0);

    if (ctx.reading) {
	ev[nev].event = (ErlDrvEvent) ctx.in.hEvent;
	ev[nev].events = ERL_DRV_READ;
	nev++;
    }

    evp = nev ? &ev[0] : NULL;

    DEBUGF("uart_win32_main: ctx.fh=%d, nev=%u, timeout = %d", 
	   ctx.fh, nev, tmo);
    r = dthread_poll(self, evp, &nev, tmo);

    if (r < 0) {
	DEBUGF("uart_win32_main: dthread_poll failed=%d", r);
	goto again_tmo;
    }
    else {
	DWORD i;
	DEBUGF("uart_win32_main: nev=%u, r=%d", nev, r);
	for (i = 0; i < nev; i++) {
	    if (ev[i].revents & ERL_DRV_READ) {
		if (ev[i].event == (ErlDrvEvent) ctx.in.hEvent) {
		    while((process_input(&ctx, self, 0) == 1) && 
			  (ctx.option.active != UART_PASSIVE))
			;
		}
		else if (ev[i].event == (ErlDrvEvent) ctx.out.hEvent) {
		    process_output(&ctx, self);
		}
	    }
	}
	tmo = next_timeout(&ctx);
	DEBUGF("uart_win32_main: timeout = %d", tmo);
	if (ctx.recv) {
	    if (tmo == 0) {
		uart_async_error_am(&ctx, ctx.dport, ctx.caller, am_timeout);
		clear_timeout(&ctx);
		ctx.remain = 0;
	    }
	}
	if (r == 0)
	    goto again;

	// r>0 (number of messages)
	DEBUGF("about to receive message r=%d", r);
	if ((mp = dthread_recv(self, NULL)) == NULL) {
	    DEBUGF("uart_win32_main: message was NULL");
	    goto again;
	}
	mp_from = mp->from;
	mp_ref  = mp->ref;
	mp_source = mp->source;

	switch (mp->cmd) {
	case DTHREAD_STOP:
	    DEBUGF("uart_win32_main: STOP");
	    close_device(&ctx);
	    uart_final(&ctx);
	    dmessage_free(mp);
	    DEBUGF("uart_win32_main: EXIT");
	    dthread_exit(0);
	    break;

	case DTHREAD_OUTPUT: // async send!
	    DEBUGF("uart_win32_main: OUTPUT");
	    if (ctx.fh == INVALID_HANDLE_VALUE) {
		dmessage_free(mp);
		goto again;
	    }
	    if (enq_output(&ctx, self, mp, 0) < 0) {
		mp = NULL;
		goto error;
	    }
	    goto again;

	case UART_CMD_CONNECT: {
	    ErlDrvTermData owner;
	    if (mp->used != 0) goto badarg;
	    owner = driver_connected(self->port);
	    self->owner   = owner;
	    other->owner  = owner;
	    goto ok;
	}

	case UART_CMD_CLOSE:
	    DEBUGF("uart_win32_main: CLOSE");
	    close_device(&ctx);
	    goto ok;

	case UART_CMD_SEND: // sync send
	    DEBUGF("uart_win32_main: SEND");
	    if (ctx.fh == INVALID_HANDLE_VALUE) goto ebadf;
	    if (enq_output(&ctx, self, mp, mp_from) < 0) {
		mp = NULL;
		goto error;
	    }
	    goto again;
	    
	case UART_CMD_SENDCHAR: // sync send
	    DEBUGF("uart_win32_main: SENDCHAR");
	    if (ctx.fh == INVALID_HANDLE_VALUE) goto ebadf;
	    if (enq_output(&ctx, self, mp, mp_from) < 0) {
		mp = NULL;
		goto error;
	    }
	    goto again;

	case UART_CMD_RECV: {  // <<Time:32, Length:32>> Time=0xffffffff=inf
	    uint32_t tm;
	    int len;
	    DEBUGF("uart_win32_main: RECV");
	    if (ctx.fh == INVALID_HANDLE_VALUE) goto ebadf;
	    if (ctx.recv) goto ealready;
	    if (mp->used != 8) goto badarg;
	    if (ctx.option.active != UART_PASSIVE) goto badarg;
	    tm = get_uint32((uint8_t*) mp->buffer);
	    len = (int) get_uint32((uint8_t*) (mp->buffer+4));
	    if ((len < 0) || (len > UART_MAX_PACKET_SIZE)) goto badarg;
	    ctx.ref = mp_ref;
	    ctx.caller = mp_from;
	    set_timeout(&ctx, tm);
	    ctx.recv = 1;
	    DEBUGF("recv timeout %lu", tm);
	    process_input(&ctx, self, len);
	    dmessage_free(mp);
	    goto again_tmo;
	}

	case UART_CMD_UNRECV: {  // argument is data to push back
	    uart_buf_push(&ctx.ib, mp->buffer, mp->used);
	    DEBUGF("unrecived %d bytes", ctx.ib.ptr - ctx.ib.ptr_start);
	    if (ctx.option.active != UART_PASSIVE) {
		while((process_input(&ctx, self, 0) == 1) && 
		      (ctx.option.active != UART_PASSIVE))
		    ;
	    }
	    goto ok;
	}

	case UART_CMD_SETOPTS: {
	    uart_com_state_t state  = ctx.state;
	    uart_opt_t       option = ctx.option;
	    uint32_t         sflags = ctx.sflags;

	    // parse & update options in state,option and sflag
	    if (uart_parse_opts(mp->buffer, mp->used, 
				&state, &option, &sflags) < 0)
		goto badarg;

	    //  apply the changed values
	    if ((r=apply_opts(&ctx, &state, &option, sflags)) < 0) {
		goto error;
	    }
	    goto ok;
	}

	case UART_CMD_GETOPTS: {
	    dterm_mark_t m1;
	    dterm_mark_t m2;
	    // {Ref, {ok,List}} || {Ref, {error,Reason}}
	    dterm_tuple_begin(&term, &m1); {
		dterm_uint(&term, mp_ref);
		dterm_tuple_begin(&term, &m2); {
		    dterm_atom(&term, am_ok);
		    if (uart_get_opts(&term, &ctx,(uint8_t*)mp->buffer,mp->used) < 0) {
			dterm_reset(&term);
			goto badarg;
		    }
		}
		dterm_tuple_end(&term, &m2);
	    }
	    dterm_tuple_end(&term, &m1);
	    dthread_port_send_dterm(mp_source, self, mp_from, &term);
	    dterm_reset(&term);
	    dmessage_free(mp);
	    goto again;
	}

	case UART_CMD_GET_MODEM: {
	    dterm_mark_t m1;
	    dterm_mark_t m2;
	    uart_modem_state_t mstate;
	    if (ctx.fh == INVALID_HANDLE_VALUE) goto ebadf;
	    if (get_modem_state(ctx.fh, &mstate) < 0) goto error;

	    dterm_tuple_begin(&term, &m1); {
		dterm_uint(&term, mp_ref);
		dterm_tuple_begin(&term, &m2); {
		    dterm_atom(&term, am_ok);
		    modem_state_dterm(&term, mstate);
		}
		dterm_tuple_end(&term, &m2);
	    }
	    dterm_tuple_end(&term, &m1);
	    dthread_port_send_dterm(mp_source, self, mp_from, &term);
	    dterm_reset(&term);
	    dmessage_free(mp);
	    goto again;
	}

	case UART_CMD_SET_MODEM: {
	    uart_modem_state_t mstate;	    
	    if (ctx.fh == INVALID_HANDLE_VALUE) goto ebadf;
	    if (mp->used != 4) goto badarg;
	    mstate = (uart_modem_state_t) get_uint32((uint8_t*) mp->buffer);
	    if (set_modem_state(ctx.fh, mstate, 1) < 0) goto error;
	    goto ok;
	}

	case UART_CMD_CLR_MODEM: {
	    uart_modem_state_t mstate;
	    if (ctx.fh == INVALID_HANDLE_VALUE) goto ebadf;
	    if (mp->used != 4) goto badarg;
	    mstate = (uart_modem_state_t) get_uint32((uint8_t*) mp->buffer);
	    if (set_modem_state(ctx.fh, mstate, 0) < 0) goto error;
	    goto ok;
	}
		
	case UART_CMD_HANGUP: {
	    if (ctx.fh == INVALID_HANDLE_VALUE) goto ebadf;
	    if (mp->used != 0) goto badarg;
	    // FIXME?
	    goto ok;
	}
		
	case UART_CMD_BREAK: {
	    int duration;
	    if (ctx.fh == INVALID_HANDLE_VALUE) goto ebadf;
	    if (mp->used != 4) goto badarg;
	    duration = (int) get_uint32((uint8_t*) mp->buffer);
	    if (!EscapeCommFunction(ctx.fh, SETBREAK)) {
		DEBUG_ERROR("EscapeCommFunction: error %d", GetLastError());
		goto error;
	    }
	    Sleep(duration);
	    if (!EscapeCommFunction(ctx.fh, CLRBREAK)) {
		DEBUG_ERROR("EscapeCommFunction: error %d", GetLastError());
		goto error;
	    }
	    goto ok;
	}

	case UART_CMD_FLOW:
	    if (ctx.fh == INVALID_HANDLE_VALUE) goto ebadf;
	    if (mp->used != 1) goto badarg;
	    switch(mp->buffer[0]) {
	    case 0:
		if (!EscapeCommFunction(ctx.fh, SETXOFF)) {
		    DEBUG_ERROR("EscapeCommFunction: error %d", GetLastError());
		    goto error;
		}
		break;
	    case 1:
		if (!EscapeCommFunction(ctx.fh, SETXON)) {
		    DEBUG_ERROR("EscapeCommFunction: error %d", GetLastError());
		    goto error;
		}
		break;
	    case 2:
		// TransmitCommChar(ctx.fh, XOFF);
		break;
	    case 3:
		// TransmitCommChar(ctx.fh, XON);
		break;
	    default: 
		goto badarg;
	    }
	    goto ok;

	default:
	    goto badarg;
	}
    }

ok:
    dthread_port_send_ok(mp_source, self,  mp_from, mp_ref);
    if (mp) dmessage_free(mp);
    goto again;

ebadf:
    errno = EBADF;
    goto error;
badarg:
    errno = EINVAL;
    goto error;
ealready:
    errno = EBUSY;
    goto error;

error:
    dthread_port_send_error(mp_source, self, mp_from, mp_ref,
			    uart_errno(&ctx));
    if (mp) dmessage_free(mp);
    goto again;
}
Example #11
0
int ape_parseheaderbuf(unsigned char* buf, struct ape_ctx_t* ape_ctx)
{
    unsigned char* header;

    memset(ape_ctx,0,sizeof(struct ape_ctx_t));
    /* TODO: Skip any leading junk such as id3v2 tags */
    ape_ctx->junklength = 0;

    memcpy(ape_ctx->magic, buf, 4);
    if (memcmp(ape_ctx->magic,"MAC ",4)!=0)
    {
        return -1;
    }

    ape_ctx->fileversion = get_int16(buf + 4);

    if (ape_ctx->fileversion >= 3980)
    {
        ape_ctx->padding1 = get_int16(buf + 6);
        ape_ctx->descriptorlength = get_uint32(buf + 8);
        ape_ctx->headerlength = get_uint32(buf + 12);
        ape_ctx->seektablelength = get_uint32(buf + 16);
        ape_ctx->wavheaderlength = get_uint32(buf + 20);
        ape_ctx->audiodatalength = get_uint32(buf + 24);
        ape_ctx->audiodatalength_high = get_uint32(buf + 28);
        ape_ctx->wavtaillength = get_uint32(buf + 32);
        memcpy(ape_ctx->md5, buf + 36, 16);

        header = buf + ape_ctx->descriptorlength;

        /* Read header data */
        ape_ctx->compressiontype = get_uint16(header + 0);
        ape_ctx->formatflags = get_uint16(header + 2);
        ape_ctx->blocksperframe = get_uint32(header + 4);
        ape_ctx->finalframeblocks = get_uint32(header + 8);
        ape_ctx->totalframes = get_uint32(header + 12);
        ape_ctx->bps = get_uint16(header + 16);
        ape_ctx->channels = get_uint16(header + 18);
        ape_ctx->samplerate = get_uint32(header + 20);

        ape_ctx->seektablefilepos = ape_ctx->junklength + 
                                    ape_ctx->descriptorlength +
                                    ape_ctx->headerlength;

        ape_ctx->firstframe = ape_ctx->junklength + ape_ctx->descriptorlength +
                              ape_ctx->headerlength + ape_ctx->seektablelength +
                              ape_ctx->wavheaderlength;
    } else {
        ape_ctx->headerlength = 32;
        ape_ctx->compressiontype = get_uint16(buf + 6);
        ape_ctx->formatflags = get_uint16(buf + 8);
        ape_ctx->channels = get_uint16(buf + 10);
        ape_ctx->samplerate = get_uint32(buf + 12);
        ape_ctx->wavheaderlength = get_uint32(buf + 16);
        ape_ctx->totalframes = get_uint32(buf + 24);
        ape_ctx->finalframeblocks = get_uint32(buf + 28);

        if (ape_ctx->formatflags & MAC_FORMAT_FLAG_HAS_PEAK_LEVEL)
        {
            ape_ctx->headerlength += 4;
        }

        if (ape_ctx->formatflags & MAC_FORMAT_FLAG_HAS_SEEK_ELEMENTS)
        {
            ape_ctx->seektablelength = get_uint32(buf + ape_ctx->headerlength);
            ape_ctx->seektablelength *= sizeof(int32_t);
            ape_ctx->headerlength += 4;
        } else {
            ape_ctx->seektablelength = ape_ctx->totalframes * sizeof(int32_t);
        }

        if (ape_ctx->formatflags & MAC_FORMAT_FLAG_8_BIT)
            ape_ctx->bps = 8;
        else if (ape_ctx->formatflags & MAC_FORMAT_FLAG_24_BIT)
            ape_ctx->bps = 24;
        else
            ape_ctx->bps = 16;

        if (ape_ctx->fileversion >= 3950)
            ape_ctx->blocksperframe = 73728 * 4;
        else if ((ape_ctx->fileversion >= 3900) || (ape_ctx->fileversion >= 3800 && ape_ctx->compressiontype >= 4000))
            ape_ctx->blocksperframe = 73728;
        else
            ape_ctx->blocksperframe = 9216;

        ape_ctx->seektablefilepos = ape_ctx->junklength + ape_ctx->headerlength +
                                    ape_ctx->wavheaderlength;

        ape_ctx->firstframe = ape_ctx->junklength + ape_ctx->headerlength +
                              ape_ctx->wavheaderlength + ape_ctx->seektablelength;
    }

    ape_ctx->totalsamples = ape_ctx->finalframeblocks;
    if (ape_ctx->totalframes > 1)
        ape_ctx->totalsamples += ape_ctx->blocksperframe * (ape_ctx->totalframes-1);

    ape_ctx->numseekpoints = APE_MAX(ape_ctx->maxseekpoints,
                                     ape_ctx->seektablelength / sizeof(int32_t));

    return 0;
}
Example #12
0
/*
   read_directory(archive) -> files dict (new reference)

   Given a path to a Zip archive, build a dict, mapping file names
   (local to the archive, using SEP as a separator) to toc entries.

   A toc_entry is a tuple:

       (__file__,      # value to use for __file__, available for all files
    compress,      # compression kind; 0 for uncompressed
    data_size,     # size of compressed data on disk
    file_size,     # size of decompressed data
    file_offset,   # offset of file header from start of archive
    time,          # mod time of file (in dos format)
    date,          # mod data of file (in dos format)
    crc,           # crc checksum of the data
       )

   Directories can be recognized by the trailing SEP in the name,
   data_size and file_offset are 0.
*/
static PyObject *
read_directory(const char *archive)
{
    PyObject *files = NULL;
    FILE *fp;
    unsigned short compress, time, date, name_size;
    unsigned int crc, data_size, file_size, header_size, header_offset;
    unsigned long file_offset, header_position;
    unsigned long arc_offset;  /* Absolute offset to start of the zip-archive. */
    unsigned int count, i;
    unsigned char buffer[46];
    size_t length;
    char path[MAXPATHLEN + 5];
    char name[MAXPATHLEN + 5];
    const char *errmsg = NULL;

    if (strlen(archive) > MAXPATHLEN) {
        PyErr_SetString(PyExc_OverflowError,
                        "Zip path name is too long");
        return NULL;
    }
    strcpy(path, archive);

    fp = fopen(archive, "rb");
    if (fp == NULL) {
        PyErr_Format(ZipImportError, "can't open Zip file: "
                     "'%.200s'", archive);
        return NULL;
    }

    if (fseek(fp, -22, SEEK_END) == -1) {
        goto file_error;
    }
    header_position = (unsigned long)ftell(fp);
    if (header_position == (unsigned long)-1) {
        goto file_error;
    }
    assert(header_position <= (unsigned long)LONG_MAX);
    if (fread(buffer, 1, 22, fp) != 22) {
        goto file_error;
    }
    if (get_uint32(buffer) != 0x06054B50u) {
        /* Bad: End of Central Dir signature */
        errmsg = "not a Zip file";
        goto invalid_header;
    }

    header_size = get_uint32(buffer + 12);
    header_offset = get_uint32(buffer + 16);
    if (header_position < header_size) {
        errmsg = "bad central directory size";
        goto invalid_header;
    }
    if (header_position < header_offset) {
        errmsg = "bad central directory offset";
        goto invalid_header;
    }
    if (header_position - header_size < header_offset) {
        errmsg = "bad central directory size or offset";
        goto invalid_header;
    }
    header_position -= header_size;
    arc_offset = header_position - header_offset;

    files = PyDict_New();
    if (files == NULL) {
        goto error;
    }

    length = (long)strlen(path);
    path[length] = SEP;

    /* Start of Central Directory */
    count = 0;
    if (fseek(fp, (long)header_position, 0) == -1) {
        goto file_error;
    }
    for (;;) {
        PyObject *t;
        size_t n;
        int err;

        n = fread(buffer, 1, 46, fp);
        if (n < 4) {
            goto eof_error;
        }
        /* Start of file header */
        if (get_uint32(buffer) != 0x02014B50u) {
            break;              /* Bad: Central Dir File Header */
        }
        if (n != 46) {
            goto eof_error;
        }
        compress = get_uint16(buffer + 10);
        time = get_uint16(buffer + 12);
        date = get_uint16(buffer + 14);
        crc = get_uint32(buffer + 16);
        data_size = get_uint32(buffer + 20);
        file_size = get_uint32(buffer + 24);
        name_size = get_uint16(buffer + 28);
        header_size = (unsigned int)name_size +
           get_uint16(buffer + 30) /* extra field */ +
           get_uint16(buffer + 32) /* comment */;

        file_offset = get_uint32(buffer + 42);
        if (file_offset > header_offset) {
            errmsg = "bad local header offset";
            goto invalid_header;
        }
        file_offset += arc_offset;

        if (name_size > MAXPATHLEN) {
            name_size = MAXPATHLEN;
        }
        if (fread(name, 1, name_size, fp) != name_size) {
            goto file_error;
        }
        name[name_size] = '\0';  /* Add terminating null byte */
        if (SEP != '/') {
            for (i = 0; i < name_size; i++) {
                if (name[i] == '/') {
                    name[i] = SEP;
                }
            }
        }
        /* Skip the rest of the header.
         * On Windows, calling fseek to skip over the fields we don't use is
         * slower than reading the data because fseek flushes stdio's
         * internal buffers.  See issue #8745. */
        assert(header_size <= 3*0xFFFFu);
        for (i = name_size; i < header_size; i++) {
            if (getc(fp) == EOF) {
                goto file_error;
            }
        }

        strncpy(path + length + 1, name, MAXPATHLEN - length - 1);

        t = Py_BuildValue("sHIIkHHI", path, compress, data_size,
                          file_size, file_offset, time, date, crc);
        if (t == NULL) {
            goto error;
        }
        err = PyDict_SetItemString(files, name, t);
        Py_DECREF(t);
        if (err != 0) {
            goto error;
        }
        count++;
    }
    fclose(fp);
    if (Py_VerboseFlag) {
        PySys_WriteStderr("# zipimport: found %u names in %.200s\n",
                           count, archive);
    }
    return files;

eof_error:
    set_file_error(archive, !ferror(fp));
    goto error;

file_error:
    PyErr_Format(ZipImportError, "can't read Zip file: %.200s", archive);
    goto error;

invalid_header:
    assert(errmsg != NULL);
    PyErr_Format(ZipImportError, "%s: %.200s", errmsg, archive);
    goto error;

error:
    fclose(fp);
    Py_XDECREF(files);
    return NULL;
}
Example #13
0
struct gme_playlistlist* gme_game_get_playlistlist(const struct gme_game* g,struct gme* gme,uint16_t i) {
  assert(i<((g->type==6) ? 7 : 5));
  return (struct gme_playlistlist*)
    gme_get_ptr(gme,get_uint32(gme_game_get_last_round_p(g)+10+i*4));
}
Example #14
0
static int
ikev2_process_cfg_request_attribs(struct ikev2_sa *ike_sa,
				  struct ikev2_child_sa *child_sa,
				  struct ikev2payl_config *cfg,
				  struct ikev2_child_param *param)
{
	struct ikev2cfg_attrib *attr;
	size_t bytes;
	int attr_type;
	unsigned int attr_len;
	int ip4_address = 0;
	int ip6_address = 0;
	int af;
	size_t addrsize;
	uint8_t *addrbits;
	struct rcf_address *addr;
	int address_fail = 0;
	int address_success = 0;
#ifdef DEBUG_TRACE
	char addrstr[INET6_ADDRSTRLEN];
#endif

	for (bytes = get_payload_length(cfg) - sizeof(*cfg),
		 attr = (struct ikev2cfg_attrib *)(cfg + 1);
	     bytes > 0;
	     bytes -= IKEV2CFG_ATTR_TOTALLENGTH(attr),
		 attr = IKEV2CFG_ATTR_NEXT(attr)) {
		attr_type = IKEV2CFG_ATTR_TYPE(attr);
		attr_len = IKEV2CFG_ATTR_LENGTH(attr);
		TRACE((PLOGLOC, "attribute type %d length %d\n",
		       attr_type, attr_len));
		assert(bytes >= sizeof(struct ikev2cfg_attrib));

		switch (attr_type) {
		case IKEV2_CFG_INTERNAL_IP4_ADDRESS:
			TRACE((PLOGLOC, "INTERNAL_IP4_ADDRESS\n"));
			if (++ip4_address > ike_max_ip4_alloc(ike_sa->rmconf)) {
				TRACE((PLOGLOC,
				       "INTERNAL_IP4_ADDRESS request exceeds allocation limit (%d)\n",
				       ike_max_ip4_alloc(ike_sa->rmconf)));
				++address_fail;
				break;
			}

			af = AF_INET;
			addrsize = sizeof(struct in_addr);
			addrbits = (uint8_t *)(attr + 1);
			if (attr_len != 0 && attr_len < addrsize) {
				TRACE((PLOGLOC,
				       "bogus attribute length %d, ignoring content\n",
				       attr_len));
				goto alloc_addr;
			}

			if (attr_len == 0 ||
			    get_uint32((uint32_t *)addrbits) == INADDR_ANY)
				goto alloc_addr;

		    try_assign:
			TRACE((PLOGLOC, "trying peer-specified address %s\n",
			       inet_ntop(af, addrbits, addrstr, sizeof(addrstr))));
			addr = rc_addrpool_assign(ikev2_addresspool(ike_sa->rmconf),
					       af, addrbits);
			if (addr) {
				TRACE((PLOGLOC, "OK.\n"));
				goto alloc_success;
			}

			TRACE((PLOGLOC, "failed, trying to allocate different address\n"));
			/* go on */
		    alloc_addr:
			addr = rc_addrpool_alloc_any(ikev2_addresspool(ike_sa->rmconf), af);
			if (!addr) {
				TRACE((PLOGLOC, "no address available for lease\n"));
				++address_fail;
				break;
			}

			TRACE((PLOGLOC, "allocated %s\n",
			       inet_ntop(af, addr->address, addrstr, sizeof(addrstr))));
		    alloc_success:
			++address_success;
			LIST_INSERT_HEAD(&child_sa->lease_list, addr, link_sa);
			break;

		case IKEV2_CFG_INTERNAL_IP6_ADDRESS:
			if (++ip6_address > ike_max_ip6_alloc(ike_sa->rmconf)) {
				TRACE((PLOGLOC,
				       "INTERNAL_IP6_ADDRESS request exceeds allocation limit (%d)\n",
				       ike_max_ip6_alloc(ike_sa->rmconf)));
				++address_fail;
				break;
			}
			af = AF_INET6;
			addrsize = sizeof(struct in6_addr);
			addrbits = (uint8_t *)(attr + 1);

			if (attr_len != 0 &&
			    attr_len < sizeof(struct ikev2cfg_ip6addr)) {
				TRACE((PLOGLOC,
				       "bogus attribute length %d, ignoring content\n",
				       attr_len));
				goto alloc_addr;
			}

			/* :: */
			if (attr_len == 0 ||
			    IN6_IS_ADDR_UNSPECIFIED((struct in6_addr *)addrbits))
				goto alloc_addr;

			/* ::xxxx:yyyy:zzzz:qqqq/64 */
			/* XXX not sure about prefix, ignore for now */
			if (/* ((struct ikev2cfg_ip6addr *)(attr + 1))->prefixlen == 64 && */
			    memcmp(addrbits, &in6addr_any, 64/8) == 0) {
				TRACE((PLOGLOC,
				       "peer-specified interface identifier %s/%d\n",
				       inet_ntop(af, addrbits, addrstr, sizeof(addrstr)),
				       64));
				addr = rc_addrpool_assign_ip6intf(ikev2_addresspool(ike_sa->rmconf), addrbits);
				if (addr)
					goto alloc_success;

				TRACE((PLOGLOC, "assign failed\n"));
			}

			/* aaaa:bbbb:cccc:dddd:eeee:ffff:gggg:hhhh/64 */
			/* XXX again, prefix ignored */
			if (!IN6_IS_ADDR_UNSPECIFIED((struct in6_addr *)addrbits))
				goto try_assign;

			goto alloc_addr;

		case IKEV2_CFG_APPLICATION_VERSION:
			++param->cfg_application_version;
			break;
		case IKEV2_CFG_INTERNAL_IP4_DNS:
			++param->cfg_ip4_dns;
			break;
		case IKEV2_CFG_INTERNAL_IP6_DNS:
			++param->cfg_ip6_dns;
			break;
		case IKEV2_CFG_INTERNAL_IP4_DHCP:
			++param->cfg_ip4_dhcp;
			break;
		case IKEV2_CFG_INTERNAL_IP6_DHCP:
			++param->cfg_ip6_dhcp;
			break;
		case IKEV2_CFG_SUPPORTED_ATTRIBUTES:
			++param->cfg_supported_attributes;
			break;
		case IKEV2_CFG_MIP6_HOME_PREFIX:
			++param->cfg_mip6_home_prefix;
			break;
		default:
			TRACE((PLOGLOC, "ignored\n"));
			break;
		}
	}
	if (address_fail > 0 && address_success == 0)
		return IKEV2_INTERNAL_ADDRESS_FAILURE;
	return 0;
}
Example #15
0
// thread main!
int uart_unix_main(void* arg)
{
    dthread_t* self = (dthread_t*) arg;
    dthread_t* other = (dthread_t*) self->arg;
    dmessage_t* mp = NULL;
    dthread_poll_event_t ev, *evp;
    size_t nev;
    dterm_t term;
    uart_ctx_t ctx;
    ErlDrvTermData mp_from;
    ErlDrvTermData mp_ref;
    dthread_t*     mp_source;
    int tmo;
    int r;

    DEBUGF("uart_unix: thread started");

    uart_init(&ctx, self, other);

    dterm_init(&term);

again_tmo:
    tmo = next_timeout(&ctx);
again:
    nev = 0;
    evp = NULL;
    if (ctx.fd >= 0) {
	ev.event = (ErlDrvEvent) ((long)ctx.fd);
	ev.events = 0;
	if ((ctx.option.active != UART_PASSIVE) || ctx.recv) {
	    ev.events |= ERL_DRV_READ;
	    if (ctx.option.ptypkt && (ctx.fd != ctx.tty_fd))
		ev.events |= ERL_DRV_EXCEP;
	}
	if (ctx.oq.mesg)
	    ev.events |= ERL_DRV_WRITE;
	if (ev.events) {
	    evp = &ev;
	    nev = 1;
	}
	DEBUGF("ctx.fd=%d, ev.events=%d", ctx.fd, ev.events);
    }

    DEBUGF("uart_unix_main: nev=%d, events=%x, timeout = %d", 
	   nev, ev.events, tmo);
    r = dthread_poll(self, evp, &nev, tmo);

    if (r < 0) {
	DEBUGF("uart_unix_main: dthread_poll failed=%d", r);
	goto again_tmo;
    }
    else {
	DEBUGF("uart_unix_main: nev=%d, r=%d", nev, r);

	if (evp && (nev == 1)) {
	    if (evp->revents & ERL_DRV_WRITE)
		process_output(&ctx, self);
	    if (evp->revents & (ERL_DRV_READ|ERL_DRV_EXCEP)) {
		while((process_input(&ctx, self, 0) == 1) && 
		      (ctx.option.active != UART_PASSIVE))
		    ;
	    }
	}
	tmo = next_timeout(&ctx);
	DEBUGF("uart_unix_main: timeout = %d", tmo);
	if (ctx.recv) {
	    if (tmo == 0) {
		uart_async_error_am(&ctx, ctx.dport, ctx.caller, am_timeout);
		clear_timeout(&ctx);
		ctx.remain = 0;
	    }
	}
	if (r == 0)
	    goto again;

	// r>0 (number of messages)
	DEBUGF("about to receive message r=%d", r);
	if ((mp = dthread_recv(self, NULL)) == NULL) {
	    DEBUGF("uart_unix_main: message was NULL");
	    goto again;
	}
	mp_from = mp->from;
	mp_ref  = mp->ref;
	mp_source = mp->source;

	switch (mp->cmd) {
	case DTHREAD_STOP:
	    DEBUGF("uart_unix_main: STOP");
	    close_device(&ctx);
	    uart_final(&ctx);
	    dmessage_free(mp);
	    DEBUGF("uart_unix_main: EXIT");
	    dthread_exit(0);
	    break;

	case DTHREAD_OUTPUT: // async send!
	    DEBUGF("uart_unix_main: OUTPUT");
	    if (ctx.fd < 0) {
		dmessage_free(mp);
		goto again;
	    }
	    if (enq_output(&ctx, self, mp, 0) < 0) {
		mp = NULL;
		goto error;
	    }
	    goto again;

	case UART_CMD_CONNECT: {
	    ErlDrvTermData owner;
	    if (mp->used != 0) goto badarg;
	    owner = driver_connected(self->port);
	    self->owner   = owner;
	    other->owner  = owner;
	    goto ok;
	}

	case UART_CMD_CLOSE:
	    DEBUGF("uart_unix_main: CLOSE");
	    close_device(&ctx);
	    goto ok;

	case UART_CMD_SEND: // sync send
	    DEBUGF("uart_unix_main: SEND");
	    if (ctx.fd < 0) goto ebadf;
	    if (enq_output(&ctx, self, mp, mp_from) < 0) {
		mp = NULL;
		goto error;
	    }
	    goto again;
	    
	case UART_CMD_SENDCHAR: // sync send
	    DEBUGF("uart_unix_main: SENDCHAR");
	    if (ctx.fd < 0) goto ebadf;
	    if (enq_output(&ctx, self, mp, mp_from) < 0) {
		mp = NULL;
		goto error;
	    }
	    goto again;

	case UART_CMD_RECV: {  // <<Time:32, Length:32>> Time=0xffffffff=inf
	    uint32_t tm;
	    int len;
	    DEBUGF("uart_unix_main: RECV");
	    if (ctx.fd < 0) goto ebadf;
	    if (ctx.recv) goto ealready;
	    if (mp->used != 8) goto badarg;
	    if (ctx.option.active != UART_PASSIVE) goto badarg;
	    tm = get_uint32((uint8_t*) mp->buffer);
	    len = (int) get_uint32((uint8_t*) (mp->buffer+4));
	    if ((len < 0) || (len > UART_MAX_PACKET_SIZE)) goto badarg;
	    ctx.ref = mp_ref;
	    ctx.caller = mp_from;
	    set_timeout(&ctx, tm);
	    ctx.recv = 1;
	    DEBUGF("recv timeout %lu", tm);
	    process_input(&ctx, self, len);
	    dmessage_free(mp);
	    goto again_tmo;
	}

	case UART_CMD_UNRECV: {  // argument is data to push back
	    uart_buf_push(&ctx.ib, mp->buffer, mp->used);
	    DEBUGF("unrecived %d bytes", ctx.ib.ptr - ctx.ib.ptr_start);
	    if (ctx.option.active != UART_PASSIVE) {
		while((process_input(&ctx, self, 0) == 1) && 
		      (ctx.option.active != UART_PASSIVE))
		    ;
	    }
	    goto ok;
	}

	case UART_CMD_SETOPTS: {
	    uart_com_state_t state  = ctx.state;
	    uart_opt_t       option = ctx.option;
	    uint32_t         sflags = ctx.sflags;

	    // parse & update options in state,option and sflag
	    if (uart_parse_opts(mp->buffer, mp->used, 
				&state, &option, &sflags) < 0)
		goto badarg;

	    //  apply the changed values
	    if ((r=apply_opts(&ctx, &state, &option, sflags)) < 0)
		goto error;

	    if (r == 1) {
		while((process_input(&ctx, self, 0) == 1) && 
		      (ctx.option.active != UART_PASSIVE))
		    ;
	    }
	    goto ok;
	}

	case UART_CMD_GETOPTS: {
	    dterm_mark_t m1;
	    dterm_mark_t m2;
	    // {Ref, {ok,List}} || {Ref, {error,Reason}}
	    dterm_tuple_begin(&term, &m1); {
		dterm_uint(&term, mp_ref);
		dterm_tuple_begin(&term, &m2); {
		    dterm_atom(&term, am_ok);
		    if (uart_get_opts(&term, &ctx,(uint8_t*)mp->buffer,mp->used) < 0) {
			dterm_reset(&term);
			goto badarg;
		    }
		}
		dterm_tuple_end(&term, &m2);
	    }
	    dterm_tuple_end(&term, &m1);
	    dthread_port_send_dterm(mp_source, self, mp_from, &term);
	    dterm_reset(&term);
	    dmessage_free(mp);
	    goto again;
	}

	case UART_CMD_GET_MODEM: {
	    dterm_mark_t m1;
	    dterm_mark_t m2;
	    uart_modem_state_t mstate;
	    if (ctx.tty_fd < 0) goto ebadf;
	    if (get_modem_state(ctx.tty_fd, &mstate) < 0) goto error;

	    dterm_tuple_begin(&term, &m1); {
		dterm_uint(&term, mp_ref);
		dterm_tuple_begin(&term, &m2); {
		    dterm_atom(&term, am_ok);
		    modem_state_dterm(&term, mstate);
		}
		dterm_tuple_end(&term, &m2);
	    }
	    dterm_tuple_end(&term, &m1);
	    dthread_port_send_dterm(mp_source, self, mp_from, &term);
	    dterm_reset(&term);
	    dmessage_free(mp);
	    goto again;
	}

	case UART_CMD_SET_MODEM: {
	    uart_modem_state_t mstate;	    
	    if (ctx.tty_fd < 0) goto ebadf;
	    if (mp->used != 4) goto badarg;
	    mstate = (uart_modem_state_t) get_uint32((uint8_t*) mp->buffer);
	    if (set_modem_state(ctx.tty_fd, mstate, 1) < 0) goto error;
	    goto ok;
	}

	case UART_CMD_CLR_MODEM: {
	    uart_modem_state_t mstate;
	    if (ctx.tty_fd < 0) goto ebadf;
	    if (mp->used != 4) goto badarg;
	    mstate = (uart_modem_state_t) get_uint32((uint8_t*) mp->buffer);
	    if (set_modem_state(ctx.tty_fd, mstate, 0) < 0) goto error;
	    goto ok;
	}
		
	case UART_CMD_HANGUP: {
	    struct termios tio;
	    int r;
	    if (ctx.tty_fd < 0) goto ebadf;
	    if (mp->used != 0) goto badarg;
	    if ((r = tcgetattr(ctx.tty_fd, &tio)) < 0) {
		INFOF("tcgetattr: error=%s\n", strerror(errno));
		goto badarg;
	    }
	    cfsetispeed(&tio, B0);
	    cfsetospeed(&tio, B0);
	    if ((r = tcsetattr(ctx.tty_fd, TCSANOW, &tio)) < 0) {
		INFOF("tcsetattr: error=%s\n", strerror(errno));
		goto badarg;		
	    }
	    goto ok;
	}
		
	case UART_CMD_BREAK: {
	    int duration;
	    if (ctx.tty_fd < 0) goto ebadf;
	    if (mp->used != 4) goto badarg;
	    duration = (int) get_uint32((uint8_t*) mp->buffer);
	    if (tcsendbreak(ctx.tty_fd, duration) < 0)
		goto error;
	    goto ok;
	}
	    
	case UART_CMD_FLOW:
	    if (ctx.tty_fd < 0) goto ebadf;
	    if (mp->used != 1) goto badarg;
	    switch(mp->buffer[0]) {
	    case 0: r = tcflow(ctx.tty_fd, TCIOFF); break;
	    case 1: r = tcflow(ctx.tty_fd, TCION); break;
	    case 2: r = tcflow(ctx.tty_fd, TCOOFF); break;
	    case 3: r = tcflow(ctx.tty_fd, TCOON); break;
	    default: goto badarg; break;
	    }
	    if (r < 0)
		goto error;
	    goto ok;

	default:
	    goto badarg;
	}
    }

ok:
    dthread_port_send_ok(mp_source, self,  mp_from, mp_ref);
    if (mp) dmessage_free(mp);
    goto again;

ebadf:
    errno = EBADF;
    goto error;
badarg:
    errno = EINVAL;
    goto error;
ealready:
    errno = EALREADY;
    goto error;

error:
    dthread_port_send_error(mp_source, self, mp_from, mp_ref,
			    uart_errno(&ctx));
    if (mp) dmessage_free(mp);
    goto again;
}
Example #16
0
//  Called when POLLIN is fired on the socket.
void zmq::udp_receiver_t::in_event (fd_t fd_)
{
    //  Receive a packet.
    ssize_t recv_bytes = recv (socket, data, sizeof data, 0);
    //  At the moment, go back to polling on EAGAIN and assert on any
    //  other error.
    if ((recv_bytes < 0) && errno == EAGAIN)
        return;
    assert (recv_bytes > 0);

    //  Parse UDP packet header.
    unsigned char *data_p = data;
    uint32_t seq_no = get_uint32 (data_p);
    uint16_t offset = get_uint16 (data_p + 4);
    data_p += udp_header_size;
    recv_bytes -= udp_header_size;

    //  If this is our first packet, join the message stream.
    if (last_seq_no == 0) {
        if (offset == 0xffff)
            return;
        else {
            data_p += offset;
            recv_bytes -= offset;
        }
    }
    //  Otherwise, decide based on the sequence number.
    else {
        //  If this packet is in sequence, process the whole packet.
        if ((last_seq_no + 1) == seq_no)
            ;
        //  Otherwise, if it is an old packet, drop it.
        else if (seq_no <= last_seq_no)
            return;
        //  Otherwise we have packet loss, rejoin the message stream.
        else {
            if (offset == 0xffff)
                return;
            else {
                data_p += offset;
                recv_bytes -= offset;

                //  Re-create decoder to clear state.
                delete decoder;
                decoder = NULL;
                decoder = new (std::nothrow) v1_decoder_t (in_batch_size,
                    options.maxmsgsize);
                alloc_assert (decoder);
                //decoder->set_session (session);
            }
        }
    }
    //  If we get here, we will process this packet and it becomes our
    //  last seen sequence number.
    last_seq_no = seq_no;

    //  Decode data and push it to our pipe.
    ssize_t processed_bytes = 0;//decoder->process_buffer (data_p, recv_bytes);
    if (processed_bytes < recv_bytes) {
        //  Some data could not be written to the pipe. Save it for later.
        pending_bytes = recv_bytes - processed_bytes;
        pending_p = data_p + processed_bytes;
        //  Stop polling. We will be restarted by a call to activate_in ().
        reset_pollin (socket_handle);
    }

    //  Flush any messages produced by the decoder to the pipe.
    session->flush ();
}
Example #17
0
/* Get a system dependent string from the file, at the given file position.  */
static char *
get_sysdep_string (const struct binary_mo_file *bfp, size_t offset,
		   const struct mo_file_header *header, size_t *lengthp)
{
  /* See 'struct sysdep_string'.  */
  size_t length;
  char *string;
  size_t i;
  char *p;
  nls_uint32 s_offset;

  /* Compute the length.  */
  length = 0;
  for (i = 4; ; i += 8)
    {
      nls_uint32 segsize = get_uint32 (bfp, offset + i);
      nls_uint32 sysdepref = get_uint32 (bfp, offset + i + 4);
      nls_uint32 sysdep_segment_offset;
      nls_uint32 ss_length;
      nls_uint32 ss_offset;
      size_t n;

      length += segsize;

      if (sysdepref == SEGMENTS_END)
	break;
      if (sysdepref >= header->n_sysdep_segments)
	/* Invalid.  */
	  error (EXIT_FAILURE, 0, _("file \"%s\" is not in GNU .mo format"),
		 bfp->filename);
      /* See 'struct sysdep_segment'.  */
      sysdep_segment_offset = header->sysdep_segments_offset + sysdepref * 8;
      ss_length = get_uint32 (bfp, sysdep_segment_offset);
      ss_offset = get_uint32 (bfp, sysdep_segment_offset + 4);
      if (ss_offset + ss_length > bfp->size)
	error (EXIT_FAILURE, 0, _("file \"%s\" is truncated"), bfp->filename);
      if (!(ss_length > 0 && bfp->data[ss_offset + ss_length - 1] == '\0'))
	{
	  char location[30];
	  sprintf (location, "sysdep_segment[%u]", (unsigned int) sysdepref);
	  error (EXIT_FAILURE, 0,
		 _("file \"%s\" contains a not NUL terminated string, at %s"),
		 bfp->filename, location);
	}
      n = strlen (bfp->data + ss_offset);
      length += (n > 1 ? 1 + n + 1 : n);
    }

  /* Allocate and fill the string.  */
  string = (char *) xmalloc (length);
  p = string;
  s_offset = get_uint32 (bfp, offset);
  for (i = 4; ; i += 8)
    {
      nls_uint32 segsize = get_uint32 (bfp, offset + i);
      nls_uint32 sysdepref = get_uint32 (bfp, offset + i + 4);
      nls_uint32 sysdep_segment_offset;
      nls_uint32 ss_length;
      nls_uint32 ss_offset;
      size_t n;

      if (s_offset + segsize > bfp->size)
	error (EXIT_FAILURE, 0, _("file \"%s\" is truncated"), bfp->filename);
      memcpy (p, bfp->data + s_offset, segsize);
      p += segsize;
      s_offset += segsize;

      if (sysdepref == SEGMENTS_END)
	break;
      if (sysdepref >= header->n_sysdep_segments)
	abort ();
      /* See 'struct sysdep_segment'.  */
      sysdep_segment_offset = header->sysdep_segments_offset + sysdepref * 8;
      ss_length = get_uint32 (bfp, sysdep_segment_offset);
      ss_offset = get_uint32 (bfp, sysdep_segment_offset + 4);
      if (ss_offset + ss_length > bfp->size)
	abort ();
      if (!(ss_length > 0 && bfp->data[ss_offset + ss_length - 1] == '\0'))
	abort ();
      n = strlen (bfp->data + ss_offset);
      if (n > 1)
	*p++ = '<';
      memcpy (p, bfp->data + ss_offset, n);
      p += n;
      if (n > 1)
	*p++ = '>';
    }

  if (p != string + length)
    abort ();

  *lengthp = length;
  return string;
}
bool DictBase::SearchData(std::vector<std::string> &SearchWords, guint32 idxitem_offset, guint32 idxitem_size, gchar *origin_data)
{
	const int nWord = SearchWords.size();
	std::vector<bool> WordFind(nWord, false);
	int nfound=0;

	if (dictfile)
		fseek(dictfile, idxitem_offset, SEEK_SET);
	if (dictfile) {
		size_t fread_size;
		fread_size = fread(origin_data, idxitem_size, 1, dictfile);
		if (fread_size != 1) {
			g_print("fread error!\n");
		}
	} else {
		dictdzfile->read(origin_data, idxitem_offset, idxitem_size);
	}
	gchar *p = origin_data;
	guint32 sec_size;
	int j;
	if (!sametypesequence.empty()) {
		const gint sametypesequence_len = sametypesequence.length();
		for (int i=0; i<sametypesequence_len-1; i++) {
			if(is_dict_data_type_search_data(sametypesequence[i])) {
				sec_size = strlen(p);
				for (j=0; j<nWord; j++)
					// KMP() is faster than strstr() in theory. Really? Always be true?
					if (!WordFind[j] && KMP(p, sec_size, SearchWords[j].c_str())!=-1) {
						WordFind[j] = true;
						++nfound;
					}

				if (nfound==nWord)
					return true;
				sec_size += sizeof(gchar);
				p+=sec_size;
			} else {
				if (g_ascii_isupper(sametypesequence[i])) {
					sec_size = g_ntohl(get_uint32(p));
					sec_size += sizeof(guint32);
				} else {
					sec_size = strlen(p)+1;
				}
				p+=sec_size;
			}
		}
		if(is_dict_data_type_search_data(sametypesequence[sametypesequence_len-1])) {
			sec_size = idxitem_size - (p-origin_data);
			for (j=0; j<nWord; j++)
				if (!WordFind[j] && KMP(p, sec_size, SearchWords[j].c_str())!=-1) {
					WordFind[j] = true;
					++nfound;
				}

			if (nfound==nWord)
				return true;
		}
	} else {
		while (guint32(p - origin_data)<idxitem_size) {
			if(is_dict_data_type_search_data(*p)) {
				for (j=0; j<nWord; j++)
					if (!WordFind[j] && strstr(p, SearchWords[j].c_str())) {
						WordFind[j] = true;
						++nfound;
					}

				if (nfound==nWord)
					return true;
				sec_size = strlen(p)+1;
				p+=sec_size;
			} else {
				if (g_ascii_isupper(*p)) {
					sec_size = g_ntohl(get_uint32(p));
					sec_size += sizeof(guint32);
				} else {
					sec_size = strlen(p)+1;
				}
				p+=sec_size;
			}
		}
	}
	return false;
}
Example #19
0
/* Given a path to a Zip file and a toc_entry, return the (uncompressed)
   data as a new reference. */
static PyObject *
get_data(PyObject *archive, PyObject *toc_entry)
{
    PyObject *raw_data = NULL, *data, *decompress;
    char *buf;
    FILE *fp;
    PyObject *datapath;
    unsigned short compress, time, date;
    unsigned int crc;
    Py_ssize_t data_size, file_size, bytes_size;
    long file_offset, header_size;
    unsigned char buffer[30];
    const char *errmsg = NULL;

    if (!PyArg_ParseTuple(toc_entry, "OHnnlHHI", &datapath, &compress,
                          &data_size, &file_size, &file_offset, &time,
                          &date, &crc)) {
        return NULL;
    }
    if (data_size < 0) {
        PyErr_Format(ZipImportError, "negative data size");
        return NULL;
    }

    fp = _Py_fopen_obj(archive, "rb");
    if (!fp) {
        return NULL;
    }
    /* Check to make sure the local file header is correct */
    if (fseek(fp, file_offset, 0) == -1) {
        goto file_error;
    }
    if (fread(buffer, 1, 30, fp) != 30) {
        goto eof_error;
    }
    if (get_uint32(buffer) != 0x04034B50u) {
        /* Bad: Local File Header */
        errmsg = "bad local file header";
        goto invalid_header;
    }

    header_size = (unsigned int)30 +
        get_uint16(buffer + 26) /* file name */ +
        get_uint16(buffer + 28) /* extra field */;
    if (file_offset > LONG_MAX - header_size) {
        errmsg = "bad local file header size";
        goto invalid_header;
    }
    file_offset += header_size;  /* Start of file data */

    if (data_size > LONG_MAX - 1) {
        fclose(fp);
        PyErr_NoMemory();
        return NULL;
    }
    bytes_size = compress == 0 ? data_size : data_size + 1;
    if (bytes_size == 0) {
        bytes_size++;
    }
    raw_data = PyBytes_FromStringAndSize((char *)NULL, bytes_size);
    if (raw_data == NULL) {
        goto error;
    }
    buf = PyBytes_AsString(raw_data);

    if (fseek(fp, file_offset, 0) == -1) {
        goto file_error;
    }
    if (fread(buf, 1, data_size, fp) != (size_t)data_size) {
        PyErr_SetString(PyExc_IOError,
                        "zipimport: can't read data");
        goto error;
    }

    fclose(fp);
    fp = NULL;

    if (compress != 0) {
        buf[data_size] = 'Z';  /* saw this in zipfile.py */
        data_size++;
    }
    buf[data_size] = '\0';

    if (compress == 0) {  /* data is not compressed */
        data = PyBytes_FromStringAndSize(buf, data_size);
        Py_DECREF(raw_data);
        return data;
    }

    /* Decompress with zlib */
    decompress = get_decompress_func();
    if (decompress == NULL) {
        PyErr_SetString(ZipImportError,
                        "can't decompress data; "
                        "zlib not available");
        goto error;
    }
    data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
    Py_DECREF(decompress);
    Py_DECREF(raw_data);
    return data;

eof_error:
    set_file_error(archive, !ferror(fp));
    goto error;

file_error:
    PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
    goto error;

invalid_header:
    assert(errmsg != NULL);
    PyErr_Format(ZipImportError, "%s: %R", errmsg, archive);
    goto error;

error:
    if (fp != NULL) {
        fclose(fp);
    }
    Py_XDECREF(raw_data);
    return NULL;
}
gchar* DictBase::GetWordData(guint32 idxitem_offset, guint32 idxitem_size)
{
	for (int i=0; i<WORDDATA_CACHE_NUM; i++)
		if (cache[i].data && cache[i].offset == idxitem_offset)
			return cache[i].data;

	if (dictfile)
		fseek(dictfile, idxitem_offset, SEEK_SET);

	gchar *data;
	if (!sametypesequence.empty()) {
		gchar *origin_data = (gchar *)g_malloc(idxitem_size);

		if (dictfile) {
			size_t fread_size;
			fread_size = fread(origin_data, idxitem_size, 1, dictfile);
			if (fread_size != 1) {
				g_print("fread error!\n");
			}
		} else {
			dictdzfile->read(origin_data, idxitem_offset, idxitem_size);
		}

		const gint sametypesequence_len = sametypesequence.length();
		guint32 data_size = idxitem_size + sametypesequence_len;

		//if the last item's size is determined by the end up '\0',then +=sizeof(gchar);
		//if the last item's size is determined by the head guint32 type data,then +=sizeof(guint32);
		if(is_dict_data_type_lower_case(sametypesequence[sametypesequence_len-1])) {
			data_size += sizeof(gchar);
		} else if(is_dict_data_type_upper_case(sametypesequence[sametypesequence_len-1])) {
			data_size += sizeof(guint32);
		} else {
			if (g_ascii_isupper(sametypesequence[sametypesequence_len-1]))
				data_size += sizeof(guint32);
			else
				data_size += sizeof(gchar);
		}
		data = (gchar *)g_malloc(data_size + sizeof(guint32));
		gchar *p1,*p2;
		p1 = data + sizeof(guint32);
		p2 = origin_data;
		guint32 sec_size;
		//copy the head items.
		for (int i=0; i<sametypesequence_len-1; i++) {
			*p1=sametypesequence[i];
			p1+=sizeof(gchar);
			if(is_dict_data_type_lower_case(sametypesequence[i])) {
				sec_size = strlen(p2)+1;
				memcpy(p1, p2, sec_size);
				p1+=sec_size;
				p2+=sec_size;
			} else if(is_dict_data_type_upper_case(sametypesequence[i])) {
				sec_size = g_ntohl(get_uint32(p2));
				sec_size += sizeof(guint32);
				memcpy(p1, p2, sec_size);
				p1+=sec_size;
				p2+=sec_size;
			} else {
				if (g_ascii_isupper(sametypesequence[i])) {
					sec_size = g_ntohl(get_uint32(p2));
					sec_size += sizeof(guint32);
				} else {
					sec_size = strlen(p2)+1;
				}
				memcpy(p1, p2, sec_size);
				p1+=sec_size;
				p2+=sec_size;
			}
		}
		//calculate the last item 's size.
		sec_size = idxitem_size - (p2-origin_data);
		*p1=sametypesequence[sametypesequence_len-1];
		p1+=sizeof(gchar);
		if(is_dict_data_type_lower_case(sametypesequence[sametypesequence_len-1])) {
			memcpy(p1, p2, sec_size);
			p1 += sec_size;
			*p1='\0';//add the end up '\0';
		} else if(is_dict_data_type_upper_case(sametypesequence[sametypesequence_len-1])) {
			guint32 t = g_htonl(sec_size);
			memcpy(p1, &t, sizeof(guint32));
			p1 += sizeof(guint32);
			memcpy(p1, p2, sec_size);
		} else {
			if (g_ascii_isupper(sametypesequence[sametypesequence_len-1])) {
				guint32 t = g_htonl(sec_size);
				memcpy(p1, &t, sizeof(guint32));
				p1 += sizeof(guint32);
				memcpy(p1, p2, sec_size);
			} else {
				memcpy(p1, p2, sec_size);
				p1 += sec_size;
				*p1='\0';
			}
		}
		g_free(origin_data);
		memcpy(data, &data_size, sizeof(guint32));
	} else {
		data = (gchar *)g_malloc(idxitem_size + sizeof(guint32));
		if (dictfile) {
			size_t fread_size;
			fread_size = fread(data+sizeof(guint32), idxitem_size, 1, dictfile);
			if (fread_size != 1) {
				g_print("fread error!\n");
			}
		} else {
			dictdzfile->read(data+sizeof(guint32), idxitem_offset, idxitem_size);
		}
		memcpy(data, &idxitem_size, sizeof(guint32));
	}
	g_free(cache[cache_cur].data);

	cache[cache_cur].data = data;
	cache[cache_cur].offset = idxitem_offset;
	cache_cur++;
	if (cache_cur==WORDDATA_CACHE_NUM)
		cache_cur = 0;
	return data;
}
Example #21
0
/** Send a resolve request for <b>hostname</b> to the Tor listening on
 * <b>sockshost</b>:<b>socksport</b>.  Store the resulting IPv4
 * address (in host order) into *<b>result_addr</b>.
 */
static int
do_resolve(const char *hostname, uint32_t sockshost, uint16_t socksport,
           int reverse, int version,
           uint32_t *result_addr, char **result_hostname)
{
  int s;
  struct sockaddr_in socksaddr;
  char *req = NULL;
  ssize_t len = 0;

  tor_assert(hostname);
  tor_assert(result_addr);
  tor_assert(version == 4 || version == 5);

  *result_addr = 0;
  *result_hostname = NULL;

  s = tor_open_socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
  if (s<0) {
    log_sock_error("creating_socket", -1);
    return -1;
  }

  memset(&socksaddr, 0, sizeof(socksaddr));
  socksaddr.sin_family = AF_INET;
  socksaddr.sin_port = htons(socksport);
  socksaddr.sin_addr.s_addr = htonl(sockshost);
  if (connect(s, (struct sockaddr*)&socksaddr, sizeof(socksaddr))) {
    log_sock_error("connecting to SOCKS host", s);
    return -1;
  }

  if (version == 5) {
    char method_buf[2];
    if (write_all(s, "\x05\x01\x00", 3, 1) != 3) {
      log_err(LD_NET, "Error sending SOCKS5 method list.");
      return -1;
    }
    if (read_all(s, method_buf, 2, 1) != 2) {
      log_err(LD_NET, "Error reading SOCKS5 methods.");
      return -1;
    }
    if (method_buf[0] != '\x05') {
      log_err(LD_NET, "Unrecognized socks version: %u",
              (unsigned)method_buf[0]);
      return -1;
    }
    if (method_buf[1] != '\x00') {
      log_err(LD_NET, "Unrecognized socks authentication method: %u",
              (unsigned)method_buf[1]);
      return -1;
    }
  }

  if ((len = build_socks_resolve_request(&req, "", hostname, reverse,
                                         version))<0) {
    log_err(LD_BUG,"Error generating SOCKS request");
    tor_assert(!req);
    return -1;
  }
  if (write_all(s, req, len, 1) != len) {
    log_sock_error("sending SOCKS request", s);
    tor_free(req);
    return -1;
  }
  tor_free(req);

  if (version == 4) {
    char reply_buf[RESPONSE_LEN_4];
    if (read_all(s, reply_buf, RESPONSE_LEN_4, 1) != RESPONSE_LEN_4) {
      log_err(LD_NET, "Error reading SOCKS4 response.");
      return -1;
    }
    if (parse_socks4a_resolve_response(hostname,
                                       reply_buf, RESPONSE_LEN_4,
                                       result_addr)<0){
      return -1;
    }
  } else {
    char reply_buf[4];
    if (read_all(s, reply_buf, 4, 1) != 4) {
      log_err(LD_NET, "Error reading SOCKS5 response.");
      return -1;
    }
    if (reply_buf[0] != 5) {
      log_err(LD_NET, "Bad SOCKS5 reply version.");
      return -1;
    }
    /* Give a user some useful feedback about SOCKS5 errors */
    if (reply_buf[1] != 0) {
      log_warn(LD_NET,"Got SOCKS5 status response '%u': %s",
               (unsigned)reply_buf[1],
               socks5_reason_to_string(reply_buf[1]));
      if (reply_buf[1] == 4 && !strcasecmpend(hostname, ".onion")) {
        log_warn(LD_NET,
            "%s is a hidden service; those don't have IP addresses. "
            "To connect to a hidden service, you need to send the hostname "
            "to Tor; we suggest an application that uses SOCKS 4a.",
            hostname);
      }
      return -1;
    }
    if (reply_buf[3] == 1) {
      /* IPv4 address */
      if (read_all(s, reply_buf, 4, 1) != 4) {
        log_err(LD_NET, "Error reading address in socks5 response.");
        return -1;
      }
      *result_addr = ntohl(get_uint32(reply_buf));
    } else if (reply_buf[3] == 3) {
      size_t result_len;
      if (read_all(s, reply_buf, 1, 1) != 1) {
        log_err(LD_NET, "Error reading address_length in socks5 response.");
        return -1;
      }
      result_len = *(uint8_t*)(reply_buf);
      *result_hostname = tor_malloc(result_len+1);
      if (read_all(s, *result_hostname, result_len, 1) != (int) result_len) {
        log_err(LD_NET, "Error reading hostname in socks5 response.");
        return -1;
      }
      (*result_hostname)[result_len] = '\0';
    }
  }

  return 0;
}
Example #22
0
int ssh2_censor_packet(
    const PacketLogSettings *pls, int type, int sender_is_client,
    ptrlen pkt, logblank_t *blanks)
{
    int nblanks = 0;
    ptrlen str;
    BinarySource src[1];

    BinarySource_BARE_INIT(src, pkt.ptr, pkt.len);

    if (pls->omit_data &&
        (type == SSH2_MSG_CHANNEL_DATA ||
         type == SSH2_MSG_CHANNEL_EXTENDED_DATA)) {
        /* "Session data" packets - omit the data string. */
        get_uint32(src);              /* skip channel id */
        if (type == SSH2_MSG_CHANNEL_EXTENDED_DATA)
            get_uint32(src);          /* skip extended data type */
        str = get_string(src);
        if (!get_err(src)) {
            assert(nblanks < MAX_BLANKS);
            blanks[nblanks].offset = src->pos - str.len;
            blanks[nblanks].type = PKTLOG_OMIT;
            blanks[nblanks].len = str.len;
            nblanks++;
        }
    }

    if (sender_is_client && pls->omit_passwords) {
        if (type == SSH2_MSG_USERAUTH_REQUEST) {
            /* If this is a password packet, blank the password(s). */
            get_string(src);              /* username */
            get_string(src);              /* service name */
            str = get_string(src);        /* auth method */
            if (ptrlen_eq_string(str, "password")) {
                get_bool(src);
                /* Blank the password field. */
                str = get_string(src);
                if (!get_err(src)) {
                    assert(nblanks < MAX_BLANKS);
                    blanks[nblanks].offset = src->pos - str.len;
                    blanks[nblanks].type = PKTLOG_BLANK;
                    blanks[nblanks].len = str.len;
                    nblanks++;
                    /* If there's another password field beyond it
                     * (change of password), blank that too. */
                    str = get_string(src);
                    if (!get_err(src))
                        blanks[nblanks-1].len =
                            src->pos - blanks[nblanks].offset;
                }
            }
        } else if (pls->actx == SSH2_PKTCTX_KBDINTER &&
                   type == SSH2_MSG_USERAUTH_INFO_RESPONSE) {
            /* If this is a keyboard-interactive response packet,
             * blank the responses. */
            get_uint32(src);
            assert(nblanks < MAX_BLANKS);
            blanks[nblanks].offset = src->pos;
            blanks[nblanks].type = PKTLOG_BLANK;
            do {
                str = get_string(src);
            } while (!get_err(src));
            blanks[nblanks].len = src->pos - blanks[nblanks].offset;
            nblanks++;
        } else if (type == SSH2_MSG_CHANNEL_REQUEST) {
            /*
             * If this is an X forwarding request packet, blank the
             * fake auth data.
             *
             * Note that while we blank the X authentication data
             * here, we don't take any special action to blank the
             * start of an X11 channel, so using MIT-MAGIC-COOKIE-1
             * and actually opening an X connection without having
             * session blanking enabled is likely to leak your cookie
             * into the log.
             */
            get_uint32(src);
            str = get_string(src);
            if (ptrlen_eq_string(str, "x11-req")) {
                get_bool(src);
                get_bool(src);
                get_string(src);
                str = get_string(src);
                if (!get_err(src)) {
                    assert(nblanks < MAX_BLANKS);
                    blanks[nblanks].offset = src->pos - str.len;
                    blanks[nblanks].type = PKTLOG_BLANK;
                    blanks[nblanks].len = str.len;
                    nblanks++;
                }
            }
        }
    }

    return nblanks;
}
Example #23
0
bool DictBase::SearchData(std::vector<std::string> &SearchWords, guint32 idxitem_offset, guint32 idxitem_size, gchar *origin_data)
{
	int nWord = SearchWords.size();
	std::vector<bool> WordFind(nWord, false);
	int nfound=0;

	if (dictfile)
		fseek(dictfile, idxitem_offset, SEEK_SET);
	if (dictfile)
		fread(origin_data, idxitem_size, 1, dictfile);
	else
		dictdzfile->read(origin_data, idxitem_offset, idxitem_size);
	gchar *p = origin_data;
	guint32 sec_size;
	int j;
	if (!sametypesequence.empty()) {
		gint sametypesequence_len = sametypesequence.length();
		for (int i=0; i<sametypesequence_len-1; i++) {
			switch (sametypesequence[i]) {
			case 'm':
			case 't':
			case 'y':
			case 'l':
			case 'g':
			case 'x':
			case 'k':
			case 'w':
			case 'h':
				for (j=0; j<nWord; j++)
					// KMP() is faster than strstr() in theory. Really? Always be true?
					//if (!WordFind[j] && strstr(p, SearchWords[j].c_str())) {
					if (!WordFind[j] && KMP(p, strlen(p), SearchWords[j].c_str())!=-1) {
						WordFind[j] = true;
						++nfound;
					}

				if (nfound==nWord)
					return true;
				sec_size = strlen(p)+1;
				p+=sec_size;
				break;
			default:
				if (g_ascii_isupper(sametypesequence[i])) {
					sec_size = get_uint32(p);
					sec_size += sizeof(guint32);
				} else {
					sec_size = strlen(p)+1;
				}
				p+=sec_size;
			}
		}
		switch (sametypesequence[sametypesequence_len-1]) {
		case 'm':
		case 't':
		case 'y':
		case 'l':
		case 'g':
		case 'x':
		case 'k':
		case 'w':
		case 'h':
			sec_size = idxitem_size - (p-origin_data);
			for (j=0; j<nWord; j++)
				//if (!WordFind[j] && g_strstr_len(p, sec_size, SearchWords[j].c_str())) {
				if (!WordFind[j] && KMP(p, sec_size, SearchWords[j].c_str())!=-1) {
					WordFind[j] = true;
					++nfound;
				}

			if (nfound==nWord)
				return true;
			break;
		}
	} else {
		while (guint32(p - origin_data)<idxitem_size) {
			switch (*p) {
			case 'm':
			case 't':
			case 'y':
			case 'l':
			case 'g':
			case 'x':
			case 'k':
			case 'w':
			case 'h':
				for (j=0; j<nWord; j++)
					if (!WordFind[j] && strstr(p, SearchWords[j].c_str())) {
						WordFind[j] = true;
						++nfound;
					}

				if (nfound==nWord)
					return true;
				sec_size = strlen(p)+1;
				p+=sec_size;
				break;
                        default:
                                if (g_ascii_isupper(*p)) {
                                        sec_size = get_uint32(p);
					sec_size += sizeof(guint32);
                                } else {
                                        sec_size = strlen(p)+1;
                                }
                                p+=sec_size;
			}
		}
	}
	return false;
}
Example #24
0
gchar *mdk_dict::get_entry_data(mdk_entry *entry)
{
    int i;
    guint32 idxitem_offset = entry->offset;
    guint32 idxitem_size = entry->size;

    if (dictfile)
        fseek(dictfile, idxitem_offset, SEEK_SET);

    gchar *data;
    if (! sametypesequence.empty())
    {
        gchar *origin_data = (gchar *) g_malloc(idxitem_size);

        if (fread(origin_data, idxitem_size, 1, dictfile) != 1)
        {
            g_free(origin_data);
            return NULL;
        }

        guint32 data_size;
        gint sametypesequence_len = sametypesequence.length();
        // there have sametypesequence_len char being omitted.
        // Here is a bug fix of 2.4.8, which don't add sizeof(guint32) anymore.
        data_size = idxitem_size + sametypesequence_len;

        // if the last item's size is determined by the end up '\0',
        // then += sizeof(gchar);
        // if the last item's size is determined by the head guint32 type data,
        // then += sizeof(guint32);
        switch (sametypesequence[sametypesequence_len - 1])
        {
        case 'm':
        case 't':
        case 'y':
        case 'l':
        case 'g':
        case 'x':
        case 'k':
        case 'w':
            data_size += sizeof(gchar);
            break;
        case 'W':
        case 'P':
            data_size += sizeof(guint32);
            break;
        default:
            if (g_ascii_isupper(sametypesequence[sametypesequence_len-1]))
                data_size += sizeof(guint32);
            else
                data_size += sizeof(gchar);
            break;
        }

        data = (gchar *) g_malloc(data_size + sizeof(guint32));
        gchar *p1,*p2;
        p1 = data + sizeof(guint32);
        p2 = origin_data;
        guint32 sec_size;
        // copy the head items.
        for (i = 0; i < sametypesequence_len - 1; i++)
        {
            *p1=sametypesequence[i];
            p1+=sizeof(gchar);
            switch (sametypesequence[i]) {
            case 'm':
            case 't':
            case 'y':
            case 'l':
            case 'g':
            case 'x':
            case 'k':
            case 'w':
                sec_size = strlen(p2)+1;
                memcpy(p1, p2, sec_size);
                p1+=sec_size;
                p2+=sec_size;
                break;
            case 'W':
            case 'P':
                sec_size = get_uint32(p2);
                sec_size += sizeof(guint32);
                memcpy(p1, p2, sec_size);
                p1+=sec_size;
                p2+=sec_size;
                break;
            default:
                if (g_ascii_isupper(sametypesequence[i])) {
                    sec_size = get_uint32(p2);
                    sec_size += sizeof(guint32);
                } else {
                    sec_size = strlen(p2)+1;
                }
                memcpy(p1, p2, sec_size);
                p1+=sec_size;
                p2+=sec_size;
                break;
            }
        }

        // calculate the last item 's size.
        sec_size = idxitem_size - (p2-origin_data);
        *p1=sametypesequence[sametypesequence_len-1];
        p1 += sizeof(gchar);

        switch (sametypesequence[sametypesequence_len - 1])
        {
        case 'm':
        case 't':
        case 'y':
        case 'l':
        case 'g':
        case 'x':
        case 'k':
        case 'w':
            memcpy(p1, p2, sec_size);
            p1 += sec_size;
            *p1='\0';//add the end up '\0';
            break;
        case 'W':
        case 'P':
            memcpy(p1, &sec_size, sizeof(guint32));
            p1 += sizeof(guint32);
            memcpy(p1, p2, sec_size);
            break;

        default:
            if (g_ascii_isupper(sametypesequence[sametypesequence_len-1]))
            {
                memcpy(p1, &sec_size, sizeof(guint32));
                p1 += sizeof(guint32);
                memcpy(p1, p2, sec_size);
            } else {
                memcpy(p1, p2, sec_size);
                p1 += sec_size;
                *p1='\0';
            }
            break;
        }

        g_free(origin_data);
        memcpy(data, &data_size, sizeof(guint32));
    } else
    {
        data = (gchar *) g_malloc(idxitem_size + sizeof(guint32));

        if (fread(data + sizeof(guint32), idxitem_size, 1, dictfile) != 1)
        {
            g_free(data);
            return NULL;
        }

        memcpy(data, &idxitem_size, sizeof(guint32));
    }

    return data;
}
Example #25
0
File: onion.c Project: NickKok/tor
/** Parse an EXTEND or EXTEND2 cell (according to <b>command</b>) from the
 * <b>payload_length</b> bytes of <b>payload</b> into <b>cell_out</b>. Return
 * 0 on success, -1 on failure. */
int
extend_cell_parse(extend_cell_t *cell_out, const uint8_t command,
                  const uint8_t *payload, size_t payload_length)
{
  const uint8_t *eop;

  memset(cell_out, 0, sizeof(*cell_out));
  if (payload_length > RELAY_PAYLOAD_SIZE)
    return -1;
  eop = payload + payload_length;

  switch (command) {
  case RELAY_COMMAND_EXTEND:
    {
      if (payload_length != 6 + TAP_ONIONSKIN_CHALLENGE_LEN + DIGEST_LEN)
        return -1;

      cell_out->cell_type = RELAY_COMMAND_EXTEND;
      tor_addr_from_ipv4n(&cell_out->orport_ipv4.addr, get_uint32(payload));
      cell_out->orport_ipv4.port = ntohs(get_uint16(payload+4));
      tor_addr_make_unspec(&cell_out->orport_ipv6.addr);
      if (tor_memeq(payload + 6, NTOR_CREATE_MAGIC, 16)) {
        cell_out->create_cell.cell_type = CELL_CREATE2;
        cell_out->create_cell.handshake_type = ONION_HANDSHAKE_TYPE_NTOR;
        cell_out->create_cell.handshake_len = NTOR_ONIONSKIN_LEN;
        memcpy(cell_out->create_cell.onionskin, payload + 22,
               NTOR_ONIONSKIN_LEN);
      } else {
        cell_out->create_cell.cell_type = CELL_CREATE;
        cell_out->create_cell.handshake_type = ONION_HANDSHAKE_TYPE_TAP;
        cell_out->create_cell.handshake_len = TAP_ONIONSKIN_CHALLENGE_LEN;
        memcpy(cell_out->create_cell.onionskin, payload + 6,
               TAP_ONIONSKIN_CHALLENGE_LEN);
      }
      memcpy(cell_out->node_id, payload + 6 + TAP_ONIONSKIN_CHALLENGE_LEN,
             DIGEST_LEN);
      break;
    }
  case RELAY_COMMAND_EXTEND2:
    {
      uint8_t n_specs, spectype, speclen;
      int i;
      int found_ipv4 = 0, found_ipv6 = 0, found_id = 0;
      tor_addr_make_unspec(&cell_out->orport_ipv4.addr);
      tor_addr_make_unspec(&cell_out->orport_ipv6.addr);

      if (payload_length == 0)
        return -1;

      cell_out->cell_type = RELAY_COMMAND_EXTEND2;
      n_specs = *payload++;
      /* Parse the specifiers. We'll only take the first IPv4 and first IPv6
       * address, and the node ID, and ignore everything else */
      for (i = 0; i < n_specs; ++i) {
        if (eop - payload < 2)
          return -1;
        spectype = payload[0];
        speclen = payload[1];
        payload += 2;
        if (eop - payload < speclen)
          return -1;
        switch (spectype) {
        case SPECTYPE_IPV4:
          if (speclen != 6)
            return -1;
          if (!found_ipv4) {
            tor_addr_from_ipv4n(&cell_out->orport_ipv4.addr,
                                get_uint32(payload));
            cell_out->orport_ipv4.port = ntohs(get_uint16(payload+4));
            found_ipv4 = 1;
          }
          break;
        case SPECTYPE_IPV6:
          if (speclen != 18)
            return -1;
          if (!found_ipv6) {
            tor_addr_from_ipv6_bytes(&cell_out->orport_ipv6.addr,
                                     (const char*)payload);
            cell_out->orport_ipv6.port = ntohs(get_uint16(payload+16));
            found_ipv6 = 1;
          }
          break;
        case SPECTYPE_LEGACY_ID:
          if (speclen != 20)
            return -1;
          if (found_id)
            return -1;
          memcpy(cell_out->node_id, payload, 20);
          found_id = 1;
          break;
        }
        payload += speclen;
      }
      if (!found_id || !found_ipv4)
        return -1;
      if (parse_create2_payload(&cell_out->create_cell,payload,eop-payload)<0)
        return -1;
      break;
    }
  default:
    return -1;
  }

  return check_extend_cell(cell_out);
}
/* Reads an existing .mo file and adds the messages to mlp.  */
void
read_mo_file (message_list_ty *mlp, const char *filename)
{
  FILE *fp;
  struct binary_mo_file bf;
  struct mo_file_header header;
  unsigned int i;
  static lex_pos_ty pos = { __FILE__, __LINE__ };

  if (strcmp (filename, "-") == 0 || strcmp (filename, "/dev/stdin") == 0)
    {
      fp = stdin;
      SET_BINARY (fileno (fp));
    }
  else
    {
      fp = fopen (filename, "rb");
      if (fp == NULL)
        error (EXIT_FAILURE, errno,
               _("error while opening \"%s\" for reading"), filename);
    }

  /* Read the file contents into memory.  */
  read_binary_mo_file (&bf, fp, filename);

  /* Get a 32-bit number from the file header.  */
# define GET_HEADER_FIELD(field) \
    get_uint32 (&bf, offsetof (struct mo_file_header, field))

  /* We must grope the file to determine which endian it is.
     Perversity of the universe tends towards maximum, so it will
     probably not match the currently executing architecture.  */
  bf.endian = MO_BIG_ENDIAN;
  header.magic = GET_HEADER_FIELD (magic);
  if (header.magic != _MAGIC)
    {
      bf.endian = MO_LITTLE_ENDIAN;
      header.magic = GET_HEADER_FIELD (magic);
      if (header.magic != _MAGIC)
        {
        unrecognised:
          error (EXIT_FAILURE, 0, _("file \"%s\" is not in GNU .mo format"),
                 filename);
        }
    }

  header.revision = GET_HEADER_FIELD (revision);

  /* We support only the major revisions 0 and 1.  */
  switch (header.revision >> 16)
    {
    case 0:
    case 1:
      /* Fill the header parts that apply to major revisions 0 and 1.  */
      header.nstrings = GET_HEADER_FIELD (nstrings);
      header.orig_tab_offset = GET_HEADER_FIELD (orig_tab_offset);
      header.trans_tab_offset = GET_HEADER_FIELD (trans_tab_offset);
      header.hash_tab_size = GET_HEADER_FIELD (hash_tab_size);
      header.hash_tab_offset = GET_HEADER_FIELD (hash_tab_offset);

      for (i = 0; i < header.nstrings; i++)
        {
          message_ty *mp;
          char *msgctxt;
          char *msgid;
          size_t msgid_len;
          char *separator;
          char *msgstr;
          size_t msgstr_len;

          /* Read the msgctxt and msgid.  */
          msgid = get_string (&bf, header.orig_tab_offset + i * 8,
                              &msgid_len);
          /* Split into msgctxt and msgid.  */
          separator = strchr (msgid, MSGCTXT_SEPARATOR);
          if (separator != NULL)
            {
              /* The part before the MSGCTXT_SEPARATOR is the msgctxt.  */
              *separator = '\0';
              msgctxt = msgid;
              msgid = separator + 1;
              msgid_len -= msgid - msgctxt;
            }
          else
            msgctxt = NULL;

          /* Read the msgstr.  */
          msgstr = get_string (&bf, header.trans_tab_offset + i * 8,
                               &msgstr_len);

          mp = message_alloc (msgctxt,
                              msgid,
                              (strlen (msgid) + 1 < msgid_len
                               ? msgid + strlen (msgid) + 1
                               : NULL),
                              msgstr, msgstr_len,
                              &pos);
          message_list_append (mlp, mp);
        }

      switch (header.revision & 0xffff)
        {
        case 0:
          break;
        case 1:
        default:
          /* Fill the header parts that apply to minor revision >= 1.  */
          header.n_sysdep_segments = GET_HEADER_FIELD (n_sysdep_segments);
          header.sysdep_segments_offset =
            GET_HEADER_FIELD (sysdep_segments_offset);
          header.n_sysdep_strings = GET_HEADER_FIELD (n_sysdep_strings);
          header.orig_sysdep_tab_offset =
            GET_HEADER_FIELD (orig_sysdep_tab_offset);
          header.trans_sysdep_tab_offset =
            GET_HEADER_FIELD (trans_sysdep_tab_offset);

          for (i = 0; i < header.n_sysdep_strings; i++)
            {
              message_ty *mp;
              char *msgctxt;
              char *msgid;
              size_t msgid_len;
              char *separator;
              char *msgstr;
              size_t msgstr_len;
              nls_uint32 offset;
              size_t f;

              /* Read the msgctxt and msgid.  */
              offset = get_uint32 (&bf, header.orig_sysdep_tab_offset + i * 4);
              msgid = get_sysdep_string (&bf, offset, &header, &msgid_len);
              /* Split into msgctxt and msgid.  */
              separator = strchr (msgid, MSGCTXT_SEPARATOR);
              if (separator != NULL)
                {
                  /* The part before the MSGCTXT_SEPARATOR is the msgctxt.  */
                  *separator = '\0';
                  msgctxt = msgid;
                  msgid = separator + 1;
                  msgid_len -= msgid - msgctxt;
                }
              else
                msgctxt = NULL;

              /* Read the msgstr.  */
              offset = get_uint32 (&bf, header.trans_sysdep_tab_offset + i * 4);
              msgstr = get_sysdep_string (&bf, offset, &header, &msgstr_len);

              mp = message_alloc (msgctxt,
                                  msgid,
                                  (strlen (msgid) + 1 < msgid_len
                                   ? msgid + strlen (msgid) + 1
                                   : NULL),
                                  msgstr, msgstr_len,
                                  &pos);

              /* Only messages with c-format or objc-format annotation are
                 recognized as having system-dependent strings by msgfmt.
                 Which one of the two, we don't know.  We have to guess,
                 assuming that c-format is more probable than objc-format and
                 that the .mo was likely produced by "msgfmt -c".  */
              for (f = format_c; ; f = format_objc)
                {
                  bool valid = true;
                  struct formatstring_parser *parser = formatstring_parsers[f];
                  const char *str_end;
                  const char *str;

                  str_end = msgid + msgid_len;
                  for (str = msgid; str < str_end; str += strlen (str) + 1)
                    {
                      char *invalid_reason = NULL;
                      void *descr =
                        parser->parse (str, false, NULL, &invalid_reason);

                      if (descr != NULL)
                        parser->free (descr);
                      else
                        {
                          free (invalid_reason);
                          valid = false;
                          break;
                        }
                    }
                  if (valid)
                    {
                      str_end = msgstr + msgstr_len;
                      for (str = msgstr; str < str_end; str += strlen (str) + 1)
                        {
                          char *invalid_reason = NULL;
                          void *descr =
                            parser->parse (str, true, NULL, &invalid_reason);

                          if (descr != NULL)
                            parser->free (descr);
                          else
                            {
                              free (invalid_reason);
                              valid = false;
                              break;
                            }
                        }
                    }

                  if (valid)
                    {
                      /* Found the most likely among c-format, objc-format.  */
                      mp->is_format[f] = yes;
                      break;
                    }

                  /* Try next f.  */
                  if (f == format_objc)
                    break;
                }

              message_list_append (mlp, mp);
            }
          break;
        }
      break;

    default:
      goto unrecognised;
    }

  if (fp != stdin)
    fclose (fp);
}
Example #27
0
static ast::Exp* get_exp(void)
{
  ast::Exp* exp;
  // std::cerr << "get_exp at pos " << (buf - initial_buf) << std::endl;
  int code = get_uint8();
  // std::cerr << "    code = " << code << std::endl;
  Location *loc = get_location();
  int is_verbose = get_bool();
  int is_break = get_bool();
  int is_breakable = get_bool();
  int is_return = get_bool();
  int is_returnable = get_bool();
  int is_continue = get_bool();
  int is_continuable = get_bool();
  
  
  switch(code){
  case 1: {   
    std::list<ast::Exp *>* l_body = get_exps();
    exp = new ast::SeqExp(*loc, *l_body);
    break;
  }
  case 2: {
    std::wstring* s = get_wstring();
    exp = new ast::StringExp(*loc, *s);
    break;
  }
  case 3: {
    std::wstring* s = get_wstring();
    exp = new ast::CommentExp(*loc, s);
    break;
  }
  case 4: {
    ast::IntExp::Prec prec = get_IntExp_Prec();
    int value = get_int32();
    exp = new ast::IntExp(*loc, prec, value);
    break;
  }
  case 5: {
    double d = get_double();
    exp = new ast::FloatExp(*loc, d);
    break;
  }
  case 6: {
    double d = get_double();
    exp = new ast::DoubleExp(*loc,d);
    break;
  }
  case 7: {
    bool b = get_bool();
    exp = new ast::BoolExp(*loc, b);
    break;
  }
  case 8: {
    exp = new ast::NilExp(*loc);
    break;
  }
  case 9: {
    symbol::Symbol *name = get_Symbol();
    exp = new ast::SimpleVar(*loc, *name);
    break;
  }
  case 10: {
    exp = new ast::ColonVar(*loc);
    break;
  }
  case 11: {
    exp = new ast::DollarVar(*loc);
    break;
  }
  case 12: {
    std::list<ast::Var*>* vars = get_vars();
    exp = new ast::ArrayListVar(*loc, *vars);
    break;
  }
  case 13: {
    ast::Exp *head = get_exp();
    ast::Exp *tail = get_exp();
    exp = new ast::FieldExp(*loc, *head, *tail);
    break;
  }
  case 14: {
    ast::IfExp::Kind kind = get_IfExp_Kind();
    bool has_else = get_bool();
    ast::Exp* test = get_exp();
    ast::Exp* _then = get_exp();
    ast::IfExp* ifexp;
    if( has_else ){
      ast::Exp* _else = get_exp();
      ifexp = new ast::IfExp(*loc, *test, *_then, *_else);
    } else {
      ifexp = new ast::IfExp(*loc, *test, *_then);
    }
    ifexp->kind_set(kind);
    exp = ifexp;
    break;
  }
  case 15: {
    Location *try_location = get_location();
    Location *catch_location = get_location();
    std::list<ast::Exp *>* try_exps = get_exps();
    std::list<ast::Exp *>* catch_exps = get_exps();
    ast::SeqExp *_try = new ast::SeqExp(*try_location, *try_exps);
    ast::SeqExp *_catch = new ast::SeqExp(*catch_location, *catch_exps);
    exp = new ast::TryCatchExp(*loc, *_try, *_catch);
    break;
  }
  case 16: {
    ast::Exp* test = get_exp();
    ast::Exp* body = get_exp();
    exp = new ast::WhileExp(*loc, *test, *body);
    break;
  }
  case 17: {
    Location *vardec_location = get_location();
    ast::VarDec* vardec = get_VarDec(vardec_location);
    ast::Exp* body = get_exp();
    exp = new ast::ForExp(*loc, *vardec, *body);
    break;
  }
  case 18: {
    exp = new ast::BreakExp(*loc);
    break;
  }
  case 19: {
    exp = new ast::ContinueExp(*loc);
    break;
  }
  case 20: {
    bool is_global = get_bool();
    if( is_global ){
      exp = new ast::ReturnExp(*loc);
    } else {
      ast::Exp* returnExp_exp = get_exp();    
      exp = new ast::ReturnExp(*loc, returnExp_exp);
    }
    break;
  }
  case 21: {
    bool has_default = get_bool();
    ast::SeqExp * default_case = NULL;
    if( has_default ){
      Location *default_case_location = get_location();
      std::list<ast::Exp *>* default_case_exps = get_exps();
      default_case = new ast::SeqExp(*default_case_location, 
				     *default_case_exps);    
    }
    ast::Exp* select = get_exp();

    int nitems = get_uint32();
    std::list<ast::CaseExp*> *cases = new  std::list<ast::CaseExp*>;
    for(int i = 0; i < nitems; i++){

      Location *case_location = get_location();
      Location *body_location = get_location();
      ast::Exp* test = get_exp();
      std::list<ast::Exp *>* body_exps = get_exps();
      ast::SeqExp *body = new ast::SeqExp(*body_location,  *body_exps);

      ast::CaseExp* _case = new ast::CaseExp(*case_location, *test, *body);
      cases->push_back(_case);
    }
    

    if( has_default ){
      exp = new ast::SelectExp(*loc, *select, *cases, *default_case);
    } else {
      exp = new ast::SelectExp(*loc, *select, *cases);
    }
    break;
  }
    /* SHOULD NEVER HAPPEN
  case 22: {
    exp = new ast::CaseExp(*loc);
    break;
  }
    */
  case 23: {
    std::list<ast::MatrixLineExp *>* lines = get_MatrixLines();
    exp = new ast::CellExp(*loc, *lines);
    break;
  }
  case 24: {
    std::list<ast::Exp *>* exps = get_exps();
    exp = new ast::ArrayListExp(*loc, *exps);
    break;
  }
  case 25: {
    std::list<ast::Exp *>* exps = get_exps();
    exp = new ast::AssignListExp(*loc, *exps);
    break;
  }
  case 26: {
    ast::Exp* notexp = get_exp();
    exp = new ast::NotExp(*loc, *notexp);
    break;
  }
  case 27: {
    ast::TransposeExp::Kind kind = get_TransposeExp_Kind();
    ast::Exp* _exp = get_exp();    
    exp = new ast::TransposeExp(*loc, *_exp, kind);
    break;
  }
  case 28: {
    exp = get_VarDec(loc);
    break;
  }
  case 29: {
    symbol::Symbol* name = get_Symbol();
    Location *args_loc = get_location();
    Location *returns_loc = get_location();
    ast::Exp* body = get_exp();
    std::list <ast::Var*>* args_list = get_vars();
    std::list <ast::Var*>* returns_list = get_vars();
    ast::ArrayListVar *args = new ast::ArrayListVar(*args_loc, *args_list);
    ast::ArrayListVar *returns = new ast::ArrayListVar(*returns_loc, *returns_list);
    exp = new ast::FunctionDec(*loc, *name, *args, *returns, *body);
    break;
  }
  case 30: {
    ast::Exp* _start = get_exp();    
    ast::Exp* _step = get_exp();    
    ast::Exp* _end = get_exp();    
    exp = new ast::ListExp(*loc, *_start, *_step, *_end);
    break;
  }
  case 31: {
    ast::Exp* _left = get_exp();    
    ast::Exp* _right = get_exp();    
    exp = new ast::AssignExp(*loc, *_left, *_right);
    break;
  }
  case 32: {
    ast::OpExp::Kind kind = get_OpExp_Kind();
    ast::OpExp::Oper oper = get_OpExp_Oper();
    ast::Exp *left = get_exp();
    ast::Exp *right = get_exp(); 
    ast::OpExp *_opexp  = new ast::OpExp(*loc, *left, oper, *right);
    exp = _opexp;
    _opexp->kind_set(kind);
    break;
  }
  case 33: {
    ast::OpExp::Kind kind = get_OpExp_Kind();
    ast::OpExp::Oper oper = get_OpExp_Oper();
    ast::Exp *left = get_exp();
    ast::Exp *right = get_exp(); 
    ast::LogicalOpExp *_opexp  = 
      new ast::LogicalOpExp(*loc, *left, oper, *right);
    exp = _opexp;
    _opexp->kind_set(kind);
    break;
  }
  case 34: {
    std::list<ast::MatrixLineExp *>* lines = get_MatrixLines();
    exp = new ast::MatrixExp(*loc, *lines);
    break;
  }
  case 35: {
    ast::Exp* name = get_exp();    
    std::list<ast::Exp *> * args = get_exps();
    exp = new ast::CallExp(*loc, *name, *args);
    break;
  }
    /* SHOULD NEVER HAPPEN
  case 36: {
    exp = new ast::MatrixLineExp(*loc);
    break;
  }
    */
  case 37: {
    ast::Exp* name = get_exp();    
    std::list<ast::Exp *>* args = get_exps();
    exp = new ast::CellCallExp(*loc, *name, *args);
    break;
  }
  default: 
    std::cerr << "Unknown code " << code << std::endl;
    exit(2);
  }

  exp->set_verbose(is_verbose);
  if(is_break) exp->break_set();
  if(is_breakable) exp->breakable_set();
  if(is_return) exp->return_set();
  if(is_returnable) exp->returnable_set();
  if(is_continue) exp->continue_set();
  if(is_continuable) exp->continuable_set();
  
  return exp;
}
Example #28
0
static int get_tmevent(FILE *fp, tmevent *event)
{
    int c;
    char *s;

    c = getc(fp);
    if (c == EOF)
        return 0;
    event->type = (char) c;
    if (!get_uint32(fp, &event->serial))
        return 0;
    switch (c) {
      case TM_EVENT_LIBRARY:
        s = get_string(fp);
        if (!s)
            return 0;
        event->u.libname = s;
#ifdef DEBUG_tmreader
        fprintf(stderr, "tmevent %c %u libname=\"%s\"\n", event->type, event->serial,
                event->u.libname);
#endif
        break;

      case TM_EVENT_FILENAME:
        s = get_string(fp);
        if (!s)
            return 0;
        event->u.srcname = s;
#ifdef DEBUG_tmreader
        fprintf(stderr, "tmevent %c %u srcname=\"%s\"\n",
                event->type, event->serial, event->u.srcname);
#endif
        break;

      case TM_EVENT_METHOD:
        if (!get_uint32(fp, &event->u.method.library))
            return 0;
        if (!get_uint32(fp, &event->u.method.filename))
            return 0;
        if (!get_uint32(fp, &event->u.method.linenumber))
            return 0;
        s = get_string(fp);
        if (!s)
            return 0;
        event->u.method.name = s;
#ifdef DEBUG_tmreader
        fprintf(stderr, "tmevent %c %u library=%u filename=%u linenumber=%u "
                "name=\"%s\"\n",
                event->type, event->serial,
                event->u.method.library, event->u.method.filename,
                event->u.method.linenumber, event->u.method.name);
#endif
        break;

      case TM_EVENT_CALLSITE:
        if (!get_uint32(fp, &event->u.site.parent))
            return 0;
        if (!get_uint32(fp, &event->u.site.method))
            return 0;
        if (!get_uint32(fp, &event->u.site.offset))
            return 0;
#ifdef DEBUG_tmreader
        fprintf(stderr, "tmevent %c %u parent=%u method=%u offset=%u\n",
                event->type, event->serial,
                event->u.site.parent, event->u.site.method,
                event->u.site.offset);
#endif
        break;

      case TM_EVENT_MALLOC:
      case TM_EVENT_CALLOC:
      case TM_EVENT_FREE:
        if (!get_uint32(fp, &event->u.alloc.interval))
            return 0;
        if (!get_uint32(fp, &event->u.alloc.cost))
            return 0;
        if (!get_uint32(fp, &event->u.alloc.ptr))
            return 0;
        if (!get_uint32(fp, &event->u.alloc.size))
            return 0;
        event->u.alloc.oldserial = 0;
        event->u.alloc.oldptr = 0;
        event->u.alloc.oldsize = 0;
#ifdef DEBUG_tmreader
        fprintf(stderr, "tmevent %c %u interval=%u cost=%u ptr=0x%x size=%u\n",
                event->type, event->serial,
                event->u.alloc.interval, event->u.alloc.cost,
                event->u.alloc.ptr, event->u.alloc.size);
#endif
#if defined(DEBUG_dp)
        if (c == TM_EVENT_MALLOC)
            printf("%d malloc %d 0x%p\n", event->u.alloc.cost,
                   event->u.alloc.size, event->u.alloc.ptr);
        else if (c == TM_EVENT_CALLOC)
            printf("%d calloc %d 0x%p\n", event->u.alloc.cost,
                   event->u.alloc.size, event->u.alloc.ptr);
        else
            printf("%d free %d 0x%p\n", event->u.alloc.cost,
                   event->u.alloc.size, event->u.alloc.ptr);
#endif
        break;

      case TM_EVENT_REALLOC:
        if (!get_uint32(fp, &event->u.alloc.interval))
            return 0;
        if (!get_uint32(fp, &event->u.alloc.cost))
            return 0;
        if (!get_uint32(fp, &event->u.alloc.ptr))
            return 0;
        if (!get_uint32(fp, &event->u.alloc.size))
            return 0;
        if (!get_uint32(fp, &event->u.alloc.oldserial))
            return 0;
        if (!get_uint32(fp, &event->u.alloc.oldptr))
            return 0;
        if (!get_uint32(fp, &event->u.alloc.oldsize))
            return 0;
#ifdef DEBUG_tmreader
        fprintf(stderr, "tmevent %c %u interval=%u cost=%u ptr=0x%x size=%u "
                "oldserial=%u oldptr=0x%x oldsize=%u\n",
                event->type, event->serial,
                event->u.alloc.interval, event->u.alloc.cost,
                event->u.alloc.ptr, event->u.alloc.size,
                event->u.alloc.oldserial, event->u.alloc.oldptr,
                event->u.alloc.oldsize);
#endif
#if defined(DEBUG_dp)
        printf("%d realloc %d 0x%p %d\n", event->u.alloc.cost,
               event->u.alloc.size, event->u.alloc.ptr, event->u.alloc.oldsize);
#endif
        break;

      case TM_EVENT_STATS:
        if (!get_uint32(fp, &event->u.stats.tmstats.calltree_maxstack))
            return 0;
        if (!get_uint32(fp, &event->u.stats.tmstats.calltree_maxdepth))
            return 0;
        if (!get_uint32(fp, &event->u.stats.tmstats.calltree_parents))
            return 0;
        if (!get_uint32(fp, &event->u.stats.tmstats.calltree_maxkids))
            return 0;
        if (!get_uint32(fp, &event->u.stats.tmstats.calltree_kidhits))
            return 0;
        if (!get_uint32(fp, &event->u.stats.tmstats.calltree_kidmisses))
            return 0;
        if (!get_uint32(fp, &event->u.stats.tmstats.calltree_kidsteps))
            return 0;
        if (!get_uint32(fp, &event->u.stats.tmstats.callsite_recurrences))
            return 0;
        if (!get_uint32(fp, &event->u.stats.tmstats.backtrace_calls))
            return 0;
        if (!get_uint32(fp, &event->u.stats.tmstats.backtrace_failures))
            return 0;
        if (!get_uint32(fp, &event->u.stats.tmstats.btmalloc_failures))
            return 0;
        if (!get_uint32(fp, &event->u.stats.tmstats.dladdr_failures))
            return 0;
        if (!get_uint32(fp, &event->u.stats.tmstats.malloc_calls))
            return 0;
        if (!get_uint32(fp, &event->u.stats.tmstats.malloc_failures))
            return 0;
        if (!get_uint32(fp, &event->u.stats.tmstats.calloc_calls))
            return 0;
        if (!get_uint32(fp, &event->u.stats.tmstats.calloc_failures))
            return 0;
        if (!get_uint32(fp, &event->u.stats.tmstats.realloc_calls))
            return 0;
        if (!get_uint32(fp, &event->u.stats.tmstats.realloc_failures))
            return 0;
        if (!get_uint32(fp, &event->u.stats.tmstats.free_calls))
            return 0;
        if (!get_uint32(fp, &event->u.stats.tmstats.null_free_calls))
            return 0;
        if (!get_uint32(fp, &event->u.stats.calltree_maxkids_parent))
            return 0;
        if (!get_uint32(fp, &event->u.stats.calltree_maxstack_top))
            return 0;
#ifdef DEBUG_tmreader
        fprintf(stderr, "tmevent %c %u\n", event->type, event->serial);
#endif
        break;
      default:
        fprintf(stderr, "Unknown event type 0x%x\n", (unsigned int)event->type);
        return 0;
    }
    return 1;
}
Example #29
0
void ArticleView::AppendData(gchar *data, const gchar *oword,
			     const gchar *real_oword)
{
	std::string mark;

	guint32 sec_size=0;
	const guint32 data_size=get_uint32(data);
	data+=sizeof(guint32);
	const gchar *p=data;
	bool first_time = true;
	size_t iPlugin;
	size_t nPlugins = gpAppFrame->oStarDictPlugins->ParseDataPlugins.nplugins();
	unsigned int parsed_size;
	ParseResult parse_result;
	while (guint32(p - data)<data_size) {
		if (first_time)
			first_time=false;
		else
			mark+= "\n";
		for (iPlugin = 0; iPlugin < nPlugins; iPlugin++) {
			parse_result.clear();
			if (gpAppFrame->oStarDictPlugins->ParseDataPlugins.parse(iPlugin, p, &parsed_size, parse_result, oword)) {
				p += parsed_size;
				break;
			}
		}
		if (iPlugin != nPlugins) {
			append_and_mark_orig_word(mark, real_oword, LinksPosList());
			mark.clear();
			append_data_parse_result(real_oword, parse_result);
			parse_result.clear();
			continue;
		}
		switch (*p) {
			case 'm':
			//case 'l': //TODO: convert from local encoding to utf-8
				p++;
				sec_size = strlen(p);
				if (sec_size) {
					gchar *m_str = g_markup_escape_text(p, sec_size);
					mark+=m_str;
					g_free(m_str);
				}
				sec_size++;
				break;
			case 'g':
				p++;
				sec_size=strlen(p);
				if (sec_size) {
					mark+=p;
				}
				sec_size++;
				break;
			case 'x':
				p++;
				sec_size = strlen(p) + 1;
				mark+= _("XDXF data parsing plug-in is not found!");
				break;
			case 'k':
				p++;
				sec_size = strlen(p) + 1;
				mark+= _("PowerWord data parsing plug-in is not found!");
				break;
			case 'w':
				p++;
				sec_size = strlen(p) + 1;
				mark+= _("Wiki data parsing plug-in is not found!");
				break;
			case 'h':
				p++;
				sec_size = strlen(p) + 1;
				mark+= _("HTML data parsing plug-in is not found!");
				break;
			case 'n':
				p++;
				sec_size = strlen(p) + 1;
				mark+= _("WordNet data parsing plug-in is not found!");
				break;
			case 't':
				p++;
				sec_size = strlen(p);
				if (sec_size) {
					mark += "[<span foreground=\"blue\">";
					gchar *m_str = g_markup_escape_text(p, sec_size);
					mark += m_str;
					g_free(m_str);
					mark += "</span>]";
				}
				sec_size++;
				break;
			case 'y':
				p++;
				sec_size = strlen(p);
				if (sec_size) {
					mark += "[<span foreground=\"red\">";
					gchar *m_str = g_markup_escape_text(p, sec_size);
					mark += m_str;
					g_free(m_str);
					mark += "</span>]";
				}
				sec_size++;
				break;
			case 'r':
				p++;
				sec_size = strlen(p);
				if(sec_size) {
					append_and_mark_orig_word(mark, real_oword, LinksPosList());
					mark.clear();
					append_resource_file_list(p);
				}
				sec_size++;
				break;
			/*case 'W':
				{
				p++;
				sec_size=g_ntohl(get_uint32(p));
				//TODO: sound button.
				sec_size += sizeof(guint32);
				}
				break;*/
			case 'P':
				{
				p++;
				sec_size=g_ntohl(get_uint32(p));
				if (sec_size) {
					if (for_float_win) {
						append_and_mark_orig_word(mark, real_oword, LinksPosList());
						mark.clear();
						append_pixbuf(NULL);
					} else {
						GdkPixbufLoader* loader = gdk_pixbuf_loader_new();
						gdk_pixbuf_loader_write(loader, (const guchar *)(p+sizeof(guint32)), sec_size, NULL);
						gdk_pixbuf_loader_close(loader, NULL);
						GdkPixbuf* pixbuf = gdk_pixbuf_loader_get_pixbuf(loader);
						if (pixbuf) {
							append_and_mark_orig_word(mark, real_oword, LinksPosList());
							mark.clear();
							append_pixbuf(pixbuf);
						} else {
							mark += _("<span foreground=\"red\">[Load image error!]</span>");
						}
						g_object_unref(loader);
					}
				} else {
					mark += _("<span foreground=\"red\">[Missing Image]</span>");
				}
				sec_size += sizeof(guint32);
				}
				break;
			default:
				if (g_ascii_isupper(*p)) {
					p++;
					sec_size=g_ntohl(get_uint32(p));
					sec_size += sizeof(guint32);
				} else {
					p++;
					sec_size = strlen(p)+1;
				}
				mark += _("Unknown data type, please upgrade StarDict!");
				break;
		}
		p += sec_size;
	}

	append_and_mark_orig_word(mark, real_oword, LinksPosList());
}
Example #30
0
bool_t
xdr_rpc_gss_unwrap_data(struct mbuf **resultsp,
                        gss_ctx_id_t ctx, gss_qop_t qop,
                        rpc_gss_service_t svc, u_int seq)
{
    struct mbuf	*results, *message, *mic;
    uint32_t	len, cklen;
    OM_uint32	maj_stat, min_stat;
    u_int		seq_num, conf_state, qop_state;

    results = *resultsp;
    *resultsp = NULL;

    message = NULL;
    if (svc == rpc_gss_svc_integrity) {
        /*
         * Extract the seq+message part. Remember that there
         * may be extra RPC padding in the checksum. The
         * message part is RPC encoded already so no
         * padding.
         */
        len = get_uint32(&results);
        message = results;
        results = m_split(results, len, M_WAITOK);
        if (!results) {
            m_freem(message);
            return (FALSE);
        }

        /*
         * Extract the MIC and make it contiguous.
         */
        cklen = get_uint32(&results);
        if (!results) {
            m_freem(message);
            return (FALSE);
        }
        KASSERT(cklen <= MHLEN, ("unexpected large GSS-API checksum"));
        mic = results;
        if (cklen > mic->m_len) {
            mic = m_pullup(mic, cklen);
            if (!mic) {
                m_freem(message);
                return (FALSE);
            }
        }
        if (cklen != RNDUP(cklen))
            m_trim(mic, cklen);

        /* Verify checksum and QOP. */
        maj_stat = gss_verify_mic_mbuf(&min_stat, ctx,
                                       message, mic, &qop_state);
        m_freem(mic);

        if (maj_stat != GSS_S_COMPLETE || qop_state != qop) {
            m_freem(message);
            rpc_gss_log_status("gss_verify_mic", NULL,
                               maj_stat, min_stat);
            return (FALSE);
        }
    } else if (svc == rpc_gss_svc_privacy) {
        /* Decode databody_priv. */
        len = get_uint32(&results);
        if (!results)
            return (FALSE);

        /* Decrypt databody. */
        message = results;
        if (len != RNDUP(len))
            m_trim(message, len);
        maj_stat = gss_unwrap_mbuf(&min_stat, ctx, &message,
                                   &conf_state, &qop_state);

        /* Verify encryption and QOP. */
        if (maj_stat != GSS_S_COMPLETE) {
            rpc_gss_log_status("gss_unwrap", NULL,
                               maj_stat, min_stat);
            return (FALSE);
        }
        if (qop_state != qop || conf_state != TRUE) {
            m_freem(results);
            return (FALSE);
        }
    }

    /* Decode rpc_gss_data_t (sequence number + arguments). */
    seq_num = get_uint32(&message);
    if (!message)
        return (FALSE);

    /* Verify sequence number. */
    if (seq_num != seq) {
        rpc_gss_log_debug("wrong sequence number in databody");
        m_freem(message);
        return (FALSE);
    }

    *resultsp = message;
    return (TRUE);
}