示例#1
0
文件: workout.c 项目: ra1fh/s725
/*
 * Attempt to auto-detect the HRM type based on some information in the file.
 * This may not always succeed, but it seems to work relatively well.
 */
static S725_HRM_Type
workout_detect_hrm_type(BUF *buf)
{
    int duration = 0;
    int samples;
    int laps;
    int header = 0;
    int bps = 0;
    int bpl = 0;
    int ri;

    if (buf_len(buf) <= 37) {
        log_error("workout_detect_hrm_type: buffer size too small");
        return S725_HRM_UNKNOWN;
    }

    if (buf_getc(buf, 34) == 0 && buf_getc(buf, 36) == 251) {
        return S725_HRM_S610;
    }

    if (buf_getc(buf, 37) == 251 &&
            (buf_getc(buf, 35) == 0 || buf_getc(buf, 35) == 48)) {
        /* this is either an s725 or s625x or...? */

        if ((ri = workout_get_recording_interval(buf_getc(buf, 27))) != 0) {
            /* compute the number of bytes per sample and per lap */
            bps = workout_bytes_per_sample(buf_getc(buf, 26));
            bpl = workout_bytes_per_lap(S725_HRM_UNKNOWN, buf_getc(buf, 26),
                                        buf_getc(buf, 23));

            /* obtain the number of laps and samples in the file */
            duration = buf_getbcd(buf, 16)
                       + 60 * (buf_getbcd(buf, 17) + 60 * buf_getbcd(buf, 18));
            samples = duration / ri + 1;
            laps = buf_getbcd(buf, 21);

            /* now compute the size of the file header */
            header = buf_len(buf) - samples * bps - laps * bpl;

            /*
             * based on the header size, we can make a guess at the
             * HRM type. note that this will NOT work if the file was
             * truncated due to the watch memory filling up before
             * recording was stopped.
             *
             * assume it's an S725 unless the header size matches
             * the S625x header size.
             */
            if (header == S725_HEADER_SIZE_S625X) {
                return S725_HRM_S625X;
            } else {
                return S725_HRM_S725;
            }
        }
    }

    return S725_HRM_UNKNOWN;
}
示例#2
0
文件: xbm.c 项目: ajinkya007/pike-1
static struct object *load_xbm( struct pike_string *data )
{
  int width, height;
  int x, y;
  struct buffer buff;
  struct buffer *b = &buff;
  rgb_group *dest;
  struct object *io;

  buff.str = data->str;
  buff.len = data->len;

  if(!buf_search( b, '#' ) || !buf_search( b, ' ' ) || !buf_search( b, ' ' ))
    Pike_error("This is not a XBM image!\n");
  width = atoi(b->str);
  if(width <= 0)
    Pike_error("This is not a XBM image!\n");
  if(!buf_search( b, '#' ) || !buf_search( b, ' ' ) || !buf_search( b, ' ' ))
    Pike_error("This is not a XBM image!\n");
  height = atoi(b->str);
  if(height <= 0)
    Pike_error("This is not a XBM image!\n");
  
  if(!buf_search( b, '{' ))
    Pike_error("This is not a XBM image!\n");


  push_int( width );
  push_int( height );
  io = clone_object( image_program, 2 );
  dest = ((struct image *)get_storage(io, image_program))->img;
  /* .. the code below asumes black if the read fails.. */
  for(y=0; y<height; y++)
  {
    int next_byte, cnt;
    for(x=0; x<width;)
    {
      if(buf_search( b, 'x' ))
      {
        next_byte = (hextoint(buf_getc( b ))*0x10) | hextoint(buf_getc( b ));
        for(cnt=0; cnt<8&&x<width; cnt++,x++)
        {
          if((next_byte&(1<<(x%8))))
            dest->r = dest->g = dest->b = 255;
          dest++;
        }
      } else
	Pike_error("This is not a XBM image!\n");
    }
  }
  return io;
}
示例#3
0
文件: workout.c 项目: ra1fh/s725
static void
workout_read_preamble(workout_t *w, BUF *buf)
{
    if (buf_len(buf) <= 10) {
        log_error("workout_read_preamble: buffer too small");
        return /* TODO: ERROR */;
    }

    /* number of bytes in the buffer (including these two) */
    w->bytes = buf_getc(buf, 0) + (buf_getc(buf, 1) << 8);

    w->exercise_number = buf_getc(buf, 2);
    if (w->exercise_number > 0 && w->exercise_number <= 5) {
        workout_label_extract(buf, 3, &w->exercise_label, 7);
    } else {
        strncpy(w->exercise_label, "<empty>", sizeof(w->exercise_label) - 1);
        w->exercise_label[sizeof(w->exercise_label) - 1] = '\0';
    }
}
示例#4
0
文件: workout.c 项目: ra1fh/s725
static void
workout_read_date(workout_t *w, BUF *buf)
{
    /* date of workout */
    w->date.tm_sec   = buf_getbcd(buf, 10);
    w->date.tm_min   = buf_getbcd(buf, 11);
    w->date.tm_hour  = buf_getbcd(buf, 12) & 0x7f;

    /* PATCH for AM/PM mode detection from Berend Ozceri */
    w->ampm = S725_AM_PM_MODE_UNSET;
    if (buf_getc(buf, 13) & 0x80) w->ampm |= S725_AM_PM_MODE_SET;
    if (buf_getc(buf, 12) & 0x80) w->ampm |= S725_AM_PM_MODE_PM;

    w->date.tm_hour += (buf_getc(buf, 13) & 0x80) ?                       /* am/pm mode?   */
                       ((buf_getc(buf, 12) & 0x80) ? ((w->date.tm_hour < 12) ? 12 : 0) : /* yes, pm set   */
                        ((w->date.tm_hour >= 12) ? -12 : 0)) :                           /* yes, pm unset */
                       0;                                                                /* no            */

    w->date.tm_mon   = (buf_getc(buf, 15) & 0x0f) - 1;
    w->date.tm_mday  = buf_getbcd(buf, 13) & 0x7f;
    w->date.tm_year  = 100 + buf_getbcd(buf, 14);
    w->date.tm_isdst = -1; /* Daylight savings time not known yet? */
    w->unixtime = mktime(&w->date);
}
示例#5
0
文件: workout.c 项目: ra1fh/s725
static workout_t *
workout_extract(BUF *buf, S725_HRM_Type type)
{
    workout_t *w = NULL;
    int ok = 1;

    if ((w = calloc(1, sizeof(workout_t))) == NULL) {
        log_info("workout_extract: calloc: %s", strerror(errno));
        return NULL;
    }

    /* Define the type of the HRM */
    w->type = type;

    /* Now extract the header data */
    workout_read_preamble(w, buf);
    workout_read_date(w, buf);
    workout_read_duration(w, buf, 15);

    if (buf_get_readerr(buf)) {
        log_info("workout_extract: readerr after header (%d > %d)",
                 buf_get_readerr_offset(buf), buf_len(buf));
        workout_free(w);
        return NULL;
    }

    w->avg_hr        = buf_getc(buf, 19);
    w->max_hr        = buf_getc(buf, 20);
    w->laps          = buf_getbcd(buf, 21);
    w->manual_laps   = buf_getbcd(buf, 22);
    w->interval_mode = buf_getc(buf, 23);
    w->user_id       = buf_getbcd(buf, 24);

    workout_read_units(w, buf);

    if (buf_get_readerr(buf)) {
        log_info("workout_extract: readerr after units (%d > %d)",
                 buf_get_readerr_offset(buf), buf_len(buf));
        workout_free(w);
        return NULL;
    }

    /* recording mode and interval */
    if (w->type == S725_HRM_S610) {
        w->mode = 0;
        workout_read_recording_interval  (w, buf, 26);
        workout_read_hr_limits           (w, buf, 28);
        workout_read_bestlap_split       (w, buf, 65);
        workout_read_energy              (w, buf, 69);
        workout_read_cumulative_exercise (w, buf, 75);
    } else {
        w->mode = buf_getc(buf, 26);
        workout_read_recording_interval  (w, buf, 27);
        workout_read_hr_limits           (w, buf, 29);
        workout_read_bestlap_split       (w, buf, 66);
        workout_read_energy              (w, buf, 70);
        workout_read_cumulative_exercise (w, buf, 76);
        workout_read_ride_info           (w, buf, 79);
    }

    if (buf_get_readerr(buf)) {
        log_info("workout_extract: readerr after mode (%d > %d)",
                 buf_get_readerr_offset(buf), buf_len(buf));
        workout_free(w);
        return NULL;
    }

    ok = workout_read_laps(w, buf);
    if (buf_get_readerr(buf)) {
        log_info("workout_extract: readerr after read laps (%d > %d)",
                 buf_get_readerr_offset(buf), buf_len(buf));
        workout_free(w);
        return NULL;
    }
    if (!ok) {
        workout_free(w);
        return NULL;
    }

    ok = workout_read_samples(w, buf);
    if (buf_get_readerr(buf)) {
        log_info("workout_extract: readerr after read samples (%d > %d)",
                 buf_get_readerr_offset(buf), buf_len(buf));
        workout_free(w);
        return NULL;
    }
    if (!ok) {
        workout_free(w);
        return NULL;
    }

    workout_compute_speed_info(w);

    return w;
}
示例#6
0
文件: rem2.c 项目: crooks/mixmaster
int v2body(BUFFER *body)
{
  int i, n;
  BUFFER *to, *newsgroups;
  BUFFER *temp, *out;
  BUFFER *line;
  int type = MSG_MAIL;
  int subject = 0;

  line = buf_new();
  to = buf_new();
  newsgroups = buf_new();
  temp = buf_new();
  out = buf_new();

  n = buf_getc(body);
  for (i = 0; i < n; i++) {
    buf_get(body, line, 80);
    buf_chop(line);
    if (bufileft(line, "null:"))
      goto end;
    if (bufileft(line, "post:")) {
      type = MSG_POST;
      if (line->length > 5) {
	int j = 5;

	while (j < line->length && isspace(line->data[j]))
	  j++;
	if (newsgroups->length > 0)
	  buf_appends(newsgroups, ",");
	buf_append(newsgroups, line->data + j, line->length - j);
      }
    } else {
      if (to->length > 0)
	buf_appends(to, ",");
      buf_cat(to, line);
    }
  }
  if (to->length > 0) {
    buf_appends(out, "To: ");
    buf_cat(out, to);
    buf_nl(out);
  }
  if (newsgroups->length > 0) {
    buf_appends(out, "Newsgroups: ");
    buf_cat(out, newsgroups);
    buf_nl(out);
  }
  n = buf_getc(body);
  for (i = 0; i < n; i++) {
    buf_get(body, line, 80);
    buf_chop(line);
    if (bufileft(line, "Subject:"))
      subject = 1;
    buf_cat(out, line);
    buf_nl(out);
  }

  buf_rest(temp, body);
  buf_uncompress(temp);
  buf_set(body, temp);
  buf_reset(temp);

  if (buf_lookahead(body, line) == 0 && isline(line, HASHMARK)) {
    buf_getline(body, line);
    while (buf_getline(body, line) == 0) {
      if (bufileft(line, "subject:"))
	subject = 1;
      buf_cat(out, line);
      buf_nl(out);
    }
  }
  if (type == MSG_POST && !subject)
    buf_appends(out, "Subject: (no subject)\n");

  buf_nl(out);
  buf_rest(out, body);
  buf_reset(body);
  mix_pool(out, type, -1);

end:
  buf_free(line);
  buf_free(to);
  buf_free(newsgroups);
  buf_free(temp);
  buf_free(out);
  return (0);
}
示例#7
0
文件: rem2.c 项目: crooks/mixmaster
int mix2_decrypt(BUFFER *m)
     /*  0: ok
      * -1: error
      * -2: old message */
{
  int err = 0;
  int i,rsalen,rsalen_as_byte;
  BUFFER *privkey;
  BUFFER *keyid;
  BUFFER *dec, *deskey;
  BUFFER *packetid, *mid, *digest, *addr, *temp, *iv, *ivvec;
  int type, packet = 0, numpackets = 0, timestamp = 0;
  BUFFER *body;
  BUFFER *header, *out;
  BUFFER *otherdigest, *bodydigest, *antitag, *extract;
  BUFFER *ttedigest, *hkey, *aes_pre_key, *aes_header_key, *aes_body_key, *aes_tte_key, *aes_iv;
  BUFFER *trail;

  privkey = buf_new();
  keyid = buf_new();
  dec = buf_new();
  deskey = buf_new();
  packetid = buf_new();
  mid = buf_new();
  digest = buf_new();
  addr = buf_new();
  temp = buf_new();
  iv = buf_new();
  ivvec = buf_new();
  body = buf_new();
  header = buf_new();
  out = buf_new();
  otherdigest = buf_new();
  bodydigest = buf_new();
  antitag = buf_new();
  extract = buf_new();
  ttedigest = buf_new();
  hkey = buf_new();
  aes_pre_key = buf_new();
  aes_header_key = buf_new();
  aes_body_key = buf_new();
  aes_tte_key = buf_new();
  aes_iv = buf_new();
  trail=buf_new();

  aes_pre_key->sensitive=1;
  aes_body_key->sensitive=1;
  aes_tte_key->sensitive=1;
  dec->sensitive=1;
  deskey->sensitive=1;
  extract->sensitive=1;
  hkey->sensitive=1;
  privkey->sensitive=1;

  buf_get(m, keyid, 16);
  err = db_getseckey(keyid->data, privkey);
  if (err == -1) {
    errlog(WARNING, "rem2.c mix2_decrypt not found keyid %s\n", showdata(keyid,0));
    goto end;
  }
  rsalen_as_byte=buf_getc(m);
  switch(rsalen_as_byte) {
      case 128:
        /* legacy 1024-bit */
        rsalen_as_byte=1;
        rsalen=128;
        break;
      case 2:
        rsalen_as_byte=2;
        rsalen=256;
        break;
      case 3:
        rsalen_as_byte=3;
        rsalen=384;
        break;
      case 4:
        rsalen_as_byte=4;
        rsalen=512;
        break;
      default:
        err = -1;
        errlog(NOTICE, "problem with RSA key size encoded as %d\n", rsalen_as_byte);
        goto end;
        break;
  }
  assert(128==rsalen || 256==rsalen || 384==rsalen || 512==rsalen);
  buf_get(m, extract, rsalen);   /* 3DES key and maybe more */
  err = pk_decrypt(extract, privkey);
  if (err == -1) {
    err = -1;
    errlog(NOTICE, "Cannot decrypt message.\n");
    goto end;
  }
  buf_append(body, m->data + 20 * 512, 10240);
  buf_get(m, iv, 8);
  buf_get(m, dec, 328);
  if (128==rsalen) {
      if (extract->length != 24) {
        err = -1;
        errlog(NOTICE, "Cannot decrypt message - RSA 1024 data has wrong length %d not 24.\n", extract->length);
        /* If this length is greater someone may have wrongly sent digests under 1k RSA. */
        goto end;
      }
      buf_cat(deskey, extract);
  } else {
      if (extract->length != 216) {
        err = -1;
        errlog(NOTICE, "Cannot decrypt message - RSA (large key) data has wrong length %d.\n", extract->length);
        /* supposed to be:
         * 3DES
         * hmac key
         * hmac-sha256(18*512 headers)
         * hmac-sha256(body)
         * hmac-sha256(328-block)
         * aes_pre_key
         */
        goto end;
      }
      /* antitagging measure */
      buf_get(extract, deskey, 24);
      buf_get(extract, hkey, 64);
      buf_get(extract, otherdigest, 32);
      buf_get(extract, bodydigest, 32);
      buf_get(extract, ttedigest, 32);
      buf_get(extract, aes_pre_key, 32);

      buf_reset(temp);
      hmac_sha256(body, hkey, temp);
      if (!buf_eq(bodydigest, temp)) {
          errlog(NOTICE, "Antitagging test - wrong digest on body.\n");
          err = -1;
          goto end;
      }
      buf_reset(temp);
      hmac_sha256(dec, hkey, temp);
      if (!buf_eq(ttedigest, temp)) {
          errlog(NOTICE, "Antitagging test - wrong digest on 328-block.\n");
          err = -1;
          goto end;
      }
      /* There is one more test applicable if packet type is 0. */

      derive_aes_keys(aes_pre_key, hkey,
                      aes_header_key, aes_body_key, aes_tte_key, aes_iv);
      buf_aescrypt(dec, aes_tte_key, aes_iv, DECRYPT);
  }

  buf_crypt(dec, deskey, iv, DECRYPT);
  buf_get(dec, packetid, 16);
  buf_get(dec, deskey, 24);
  type = buf_getc(dec);


  switch (type) {
  case 0:
    if (rsalen>=256) {
      buf_append(antitag, m->data +  2*512, 2*512);
      buf_reset(temp);
      hmac_sha256(antitag, hkey, temp);
      if (!buf_eq(otherdigest, temp)) {
          errlog(NOTICE, "Antitagging test - wrong digest on later header\n");
          err = -1;
          goto end;
      }
    }
    buf_get(dec, ivvec, 152);
    buf_get(dec, addr, 80);
    break;
  case 1:
    buf_get(dec, mid, 16);
    buf_get(dec, iv, 8);
    break;
  case 2:
    packet = buf_getc(dec);
    numpackets = buf_getc(dec);
    buf_get(dec, mid, 16);
    buf_get(dec, iv, 8);
    break;
  default:
    errlog(WARNING, "Unknown message type.\n");
    err = -1;
    goto end;
  }
  if (dec->data[dec->ptr] == '0' && dec->data[dec->ptr + 1] == '0' &&
      dec->data[dec->ptr + 2] == '0' && dec->data[dec->ptr + 3] == '0' &&
      dec->data[dec->ptr + 4] == '\0') {
    dec->ptr += 5;
    timestamp = buf_geti_lo(dec);
  } else {
    errlog(LOG, "Ignoring message without timestamp.\n");
    err = -1;
    goto end;
  }

  buf_get(dec, digest, 16);  /* digest of this block, but not so far as to include the digest  */
  dec->length = dec->ptr - 16;	/* ignore digest */
  dec->ptr = dec->length;
  /* If using 1024-bit RSA this is the only integrity protection.
     (It is still present but less important with larger key sizes.)
  if (!isdigest_md5(dec, digest)) {
    errlog(NOTICE, "Message digest does not match.\n");
    err = -1;
    goto end;
  }

/* Statistics are gathered in the isnewid() function. */
  switch (isnewid(packetid, rsalen_as_byte, timestamp * SECONDSPERDAY)) {
    case  0: err = -2; /* redundant message */
	     goto end;
    case -1: err = -1; /* future timestamp */
	     goto end; 
  }

  if (rsalen == 128) {
     /* skip either 1 or 2 blocks of 512 bytes */
     buf_append(trail, m->data + 512, 19*512);
  } else {
     /* and AES */
     buf_aescrypt(body, aes_body_key, aes_iv, DECRYPT);
 
     buf_append(trail, m->data + 2*512, 19*512);
     buf_aescrypt(trail, aes_header_key, aes_iv, DECRYPT);
  }

  switch (type) {
  case 0:
    buf_chop(addr);
    buf_cat(out, addr);
    buf_nl(out);
    for (i = 0; i < 19; i++) {
      buf_reset(header);
      buf_append(header, trail->data + i * 512, 512);
      buf_reset(iv);
      buf_append(iv, ivvec->data + i * 8, 8);
      buf_crypt(header, deskey, iv, DECRYPT);
      buf_cat(out, header);
    }
    buf_reset(header);
    buf_pad(header, 512); /* one block of 512 random data regardless of RSA key size */
    buf_cat(out, header);
    buf_reset(iv);
    buf_append(iv, ivvec->data + 144, 8);
    buf_crypt(body, deskey, iv, DECRYPT);
    buf_cat(out, body);
    mix_pool(out, INTERMEDIATE, -1);
    break;
  case 1:
    buf_crypt(body, deskey, iv, DECRYPT);
    err = v2body_setlen(body);
    if (err == -1)
      goto end;
    assert(body->ptr == 4);
    v2body(body);
    break;
  case 2:
    buf_crypt(body, deskey, iv, DECRYPT);
    v2partial(body, mid, packet, numpackets);
    break;
  }
end:
  buf_free(addr);
  buf_free(aes_body_key);
  buf_free(aes_header_key);
  buf_free(aes_iv);
  buf_free(aes_pre_key);
  buf_free(aes_tte_key);
  buf_free(antitag);
  buf_free(body);
  buf_free(bodydigest);
  buf_free(dec);
  buf_free(deskey);
  buf_free(digest);
  buf_free(extract);
  buf_free(header);
  buf_free(hkey);
  buf_free(iv);
  buf_free(ivvec);
  buf_free(keyid);
  buf_free(mid);
  buf_free(otherdigest);
  buf_free(out);
  buf_free(packetid);
  buf_free(privkey);
  buf_free(temp);
  buf_free(trail);
  buf_free(ttedigest);

  return (err);
}
示例#8
0
void
read_aobpcm(AOBPCMDecoder* decoder,
            struct bs_buffer* packet,
            array_ia* framelist)
{
    const static uint8_t AOB_BYTE_SWAP[2][6][36] = {
        {   /*16 bps*/
            {1, 0, 3, 2},                                    /*1 ch*/
            {1, 0, 3, 2, 5, 4, 7, 6},                        /*2 ch*/
            {1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10},          /*3 ch*/
            {   1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10,
                13, 12, 15, 14
            },                                /*4 ch*/
            {   1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10,
                13, 12, 15, 14, 17, 16, 19, 18
            },                /*5 ch*/
            {   1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10,
                13, 12, 15, 14, 17, 16, 19, 18, 21, 20, 23, 22
            } /*6 ch*/
        },
        {   /*24 bps*/
            {  2,  1,  5,  4,  0,  3},  /*1 ch*/
            {   2,  1,  5,  4,  8,  7,
                11, 10,  0,  3,  6,  9
            },  /*2 ch*/
            {   8,  7, 17, 16,  6, 15,
                2,  1,  5,  4, 11, 10,
                14, 13,  0,  3,  9, 12
            },  /*3 ch*/
            {   8,  7, 11, 10, 20, 19,
                23, 22,  6,  9, 18, 21,
                2,  1,  5,  4, 14, 13,
                17, 16,  0,  3, 12, 15
            },  /*4 ch*/
            {   8,  7, 11, 10, 14, 13,
                23, 22, 26, 25, 29, 28,
                6,  9, 12, 21, 24, 27,
                2,  1,  5,  4, 17, 16,
                20, 19,  0,  3, 15, 18
            },  /*5 ch*/
            {   8,  7, 11, 10, 26, 25,
                29, 28,  6,  9, 24, 27,
                2,  1,  5,  4, 14, 13,
                17, 16, 20, 19, 23, 22,
                32, 31, 35, 34,  0,  3,
                12, 15, 18, 21, 30, 33
            }  /*6 ch*/
        }
    };
    const unsigned bps = decoder->bps;
    const unsigned channels = decoder->channels;
    const unsigned chunk_size = decoder->chunk_size;
    const unsigned bytes_per_sample = decoder->bytes_per_sample;
    unsigned i;

    assert(framelist->len == channels);

    while ((packet->buffer_size - packet->buffer_position) >= chunk_size) {
        uint8_t unswapped[36];
        uint8_t* unswapped_ptr = unswapped;
        /*swap read bytes to proper order*/
        for (i = 0; i < chunk_size; i++) {
            unswapped[AOB_BYTE_SWAP[bps][channels - 1][i]] =
                (uint8_t)buf_getc(packet);
        }

        /*decode bytes to PCM ints and place them in proper channels*/
        for (i = 0; i < (channels * 2); i++) {
            array_i* channel = framelist->_[i % channels];
            channel->append(channel, decoder->converter(unswapped_ptr));
            unswapped_ptr += bytes_per_sample;
        }
    }
}
示例#9
0
文件: protocol.c 项目: fis/mcmap
packet_t *packet_read(packet_state_t *state)
{
	jint t = buf_getc(state);
	if (t < 0)
		return 0;

	unsigned type = t;

	state->p.type = type;

	struct packet_format_desc *fmt;
	if (type >= MAX_PACKET_FORMAT || !(fmt = &packet_format[t])->known)
	{
#if DEBUG_PROTOCOL >= 1
		log_print("IMMINENT CRASH, reading tail for log");
		unsigned char buf[256];
		for (int i = 0; i < sizeof buf; i++) buf[i] = buf_getc(state);
		for (int i = 0; i < sizeof buf; i+=16)
			log_print("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
			          buf[i+0],buf[i+1],buf[i+2],buf[i+3],buf[i+4],buf[i+5],buf[i+6],buf[i+7],
			          buf[i+8],buf[i+9],buf[i+10],buf[i+11],buf[i+12],buf[i+13],buf[i+14],buf[i+15]);
#endif
		dief("Unknown packet id: 0x%02x", type);
	}

	state->p.field_offset = state->offset;

	for (unsigned f = 0; f < fmt->nfields; f++)
	{
		state->p.field_offset[f] = state->buf_pos - state->buf_start;

		switch (fmt->ftype[f])
		{
		case FIELD_BYTE:
		case FIELD_UBYTE:
			if (!buf_skip(state, 1)) return 0;
			break;

		case FIELD_SHORT:
			if (!buf_skip(state, 2)) return 0;
			break;

		case FIELD_INT:
		case FIELD_FLOAT:
			if (!buf_skip(state, 4)) return 0;
			break;

		case FIELD_LONG:
		case FIELD_DOUBLE:
			if (!buf_skip(state, 8)) return 0;
			break;

		case FIELD_STRING:
			t = buf_get_jshort(state);
			if (!buf_skip(state, t*2)) return 0;
			break;

		case FIELD_ITEM:
			if (!buf_skip_item(state)) return 0;
			break;

		case FIELD_BYTE_ARRAY:
			t = buf_get_jint(state);
			if (!buf_skip(state, t)) return 0;
			break;

		case FIELD_BLOCK_ARRAY:
			t = buf_get_jshort(state);
			if (!buf_skip(state, 4*t)) return 0;
			break;

		case FIELD_ITEM_ARRAY:
			t = buf_get_jshort(state);
			for (int i = 0; i < t; i++)
				if (!buf_skip_item(state)) return 0;
			break;

		case FIELD_EXPLOSION_ARRAY:
			t = buf_get_jint(state);
			// FIXME: Possible over/underflow?
			if (!buf_skip(state, 3*t)) return 0;
			break;

		case FIELD_MAP_ARRAY:
			t = buf_getc(state); // Note: Unsigned
			if (!buf_skip(state, t)) return 0;
			break;

		case FIELD_ENTITY_DATA:
			while (1)
			{
				t = buf_getc(state);
				if (t == 127)
					break;
				switch (t >> 5)
				{
				case 0: if (!buf_skip(state, 1)) return 0; break;
				case 1: if (!buf_skip(state, 2)) return 0; break;
				case 2: case 3: if (!buf_skip(state, 4)) return 0; break;
				case 4: t = buf_get_jshort(state); if (!buf_skip(state, t)) return 0; break;
				case 5: if (!buf_skip(state, 5)) return 0; break;
				}
			}
			break;

		case FIELD_OBJECT_DATA:
			t = buf_get_jint(state);
			if (t > 0)
				if (!buf_skip(state, 6)) return 0; // Skip 3 short
			break;
		}
	}

	state->p.field_offset[fmt->nfields] = state->buf_pos - state->buf_start;

	state->p.size = state->buf_pos - state->buf_start;
	state->p.bytes = &state->buf[state->buf_start];

	state->buf_start = state->buf_pos;

	return &state->p;
}
示例#10
0
static void
rcsclean_file(char *fname, const char *rev_str)
{
	int fd, match;
	RCSFILE *file;
	char fpath[PATH_MAX], numb[RCS_REV_BUFSZ];
	RCSNUM *rev;
	BUF *b1, *b2;
	time_t rcs_mtime = -1;

	b1 = b2 = NULL;
	file = NULL;
	rev = NULL;

	if ((fd = rcs_choosefile(fname, fpath, sizeof(fpath))) < 0)
		goto out;

	if ((file = rcs_open(fpath, fd, RCS_RDWR)) == NULL)
		goto out;

	if (flags & PRESERVETIME)
		rcs_mtime = rcs_get_mtime(file);

	rcs_kwexp_set(file, kflag);

	if (rev_str == NULL)
		rev = file->rf_head;
	else if ((rev = rcs_getrevnum(rev_str, file)) == NULL) {
		warnx("%s: Symbolic name `%s' is undefined.", fpath, rev_str);
		goto out;
	}

	if ((b1 = rcs_getrev(file, rev)) == NULL) {
		warnx("failed to get needed revision");
		goto out;
	}
	if ((b2 = buf_load(fname)) == NULL) {
		warnx("failed to load `%s'", fname);
		goto out;
	}

	/* If buffer lengths are the same, compare contents as well. */
	if (buf_len(b1) != buf_len(b2))
		match = 0;
	else {
		size_t len, n;

		len = buf_len(b1);

		match = 1;
		for (n = 0; n < len; ++n)
			if (buf_getc(b1, n) != buf_getc(b2, n)) {
				match = 0;
				break;
			}
	}

	if (match == 1) {
		if (uflag == 1 && !TAILQ_EMPTY(&(file->rf_locks))) {
			if (!(flags & QUIET) && nflag == 0) {
				printf("rcs -u%s %s\n",
				    rcsnum_tostr(rev, numb, sizeof(numb)),
				    fpath);
			}
			(void)rcs_lock_remove(file, locker, rev);
		}

		if (TAILQ_EMPTY(&(file->rf_locks))) {
			if (!(flags & QUIET))
				printf("rm -f %s\n", fname);

			if (nflag == 0)
				(void)unlink(fname);
		}
	}

	rcs_write(file);
	if (flags & PRESERVETIME)
		rcs_set_mtime(file, rcs_mtime);

out:
	if (b1 != NULL)
		buf_free(b1);
	if (b2 != NULL)
		buf_free(b2);
	if (file != NULL)
		rcs_close(file);
}