Ejemplo n.º 1
0
apr_status_t h2_conn_io_flush(h2_conn_io *io)
{
    if (io->unflushed) {
        if (io->buflen > 0) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, io->connection,
                          "h2_conn_io: flush, flushing %ld bytes", (long)io->buflen);
            apr_bucket *b = apr_bucket_transient_create(io->buffer, io->buflen, 
                                                        io->output->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(io->output, b);
            io->buflen = 0;
        }
        /* Append flush.
         */
        APR_BRIGADE_INSERT_TAIL(io->output,
                                apr_bucket_flush_create(io->output->bucket_alloc));
        
        /* Send it out through installed filters (TLS) to the client */
        apr_status_t status = flush_out(io->output, io);
        
        if (status == APR_SUCCESS
            || APR_STATUS_IS_ECONNABORTED(status)
            || APR_STATUS_IS_EPIPE(status)) {
            /* These are all fine and no reason for concern. Everything else
             * is interesting. */
            io->unflushed = 0;
        }
        else {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, io->connection,
                          "h2_conn_io: flush error");
        }
        
        return status;
    }
    return APR_SUCCESS;
}
Ejemplo n.º 2
0
static bool_t
xdrrec_putbytes(
	XDR *xdrs,
	void *baddr,
	uint_t len)
{
	char *addr = baddr;
	RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
	int current;

	while (len > 0) {
		current = (uint_t)rstrm->out_boundry - (uint_t)rstrm->out_finger;
		current = (len < current) ? len : current;
		memmove(rstrm->out_finger, addr, current);
		rstrm->out_finger += current;
		addr += current;
		len -= current;
		if (rstrm->out_finger == rstrm->out_boundry) {
			rstrm->frag_sent = TRUE;
			if (! flush_out(rstrm, FALSE))
				return (FALSE);
		}
	}
	return (TRUE);
}
Ejemplo n.º 3
0
bool zlib_stream::unzip_finish(string* out)
{
	bool ret = flush_out(__inflate, zlib_flush_finish, out);
	//(void) __inflateReset(zstream_);
	__inflateEnd(zstream_);
	finished_ = false;
	return (ret);
}
Ejemplo n.º 4
0
void prepare_write (int x) {
  if (x < 0) {
    x = WRITE_THRESHOLD;
  }
  assert (x > 0 && x <= WRITE_THRESHOLD);
  if (!wptr) {
    wptr = wst = WB;
  }
  if (WB + WRITE_BUFFER_SIZE - wptr < x) {
    flush_out();
  }
}
Ejemplo n.º 5
0
void my_out_str_raw(FILE *fp, unsigned long digits, mpf_t f, unsigned long offset)
{
    unsigned long d;

    if (digits <= LINE_SIZE*NUM_BLOCKS) {
        unsigned long cursor = offset % LINE_SIZE;
        for (d = 0; d < digits; ) {
            mpf_set_prec_raw(f, (int)((digits-d)*BITS_PER_DIGIT+1));
            mpf_mul_ui(f, f, UNIT_MOD);
            unsigned long i = mpf_get_ui(f);
            mpf_sub_ui(f, f, i);

            utoa(i, UNIT_SIZE);
            *out_ptr++ = ' ';
            d += UNIT_SIZE;
            cursor += UNIT_SIZE;
            if (cursor == LINE_SIZE) {
                cursor = 0;
                *out_ptr++ = ':';
                *out_ptr++ = ' ';
                utoa(offset + d, 0);
                *out_ptr++ = '\n';
                if ((offset + d) % (LINE_SIZE*10) == 0)
                    flush_out(fp);
            }
        }
    } else {
        mpf_t block, mod;
        unsigned long num_units = (digits + UNIT_SIZE-1)/UNIT_SIZE;
        unsigned long block_size =  (num_units + NUM_BLOCKS-1)/NUM_BLOCKS*UNIT_SIZE;
        mpf_set_default_prec((int)(block_size*BITS_PER_DIGIT+1));
        mpf_init(block);
        mpf_init_set_ui(mod, 10);
        mpf_pow_ui(mod, mod, block_size);

        for (d = 0; d < digits; d += block_size) {
            unsigned long size = block_size < digits - d ? block_size : digits - d;
            mpf_set_prec_raw(block, (int)(size*BITS_PER_DIGIT+1));
            mpf_set(block, f);
            my_out_str_raw(fp, size, block, offset+d);
            if (block_size < digits - d) {
                mpf_set_prec_raw(f, (int)((digits-d)*BITS_PER_DIGIT+1));
                mpf_mul(f, f, mod);
                mpf_floor(trunk, f);
                mpf_sub(f, f, trunk);
            }
        }
        mpf_clear(block);
        mpf_clear(mod);
    }
}
Ejemplo n.º 6
0
apr_status_t h2_conn_io_write(h2_conn_io *io, 
                              const char *buf, size_t length)
{
    apr_status_t status = APR_SUCCESS;
    io->unflushed = 1;

#if H2_CONN_IO_USE_BUFFER
    
    ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, io->connection,
                  "h2_conn_io: buffering %ld bytes", (long)length);
    while (length > 0 && (status == APR_SUCCESS)) {
        apr_size_t avail = io->bufsize - io->buflen;
        if (avail <= 0) {
            bucketeer_buffer(io);
            status = flush_out(io->output, io);
            io->buflen = 0;
        }
        else if (length > avail) {
            memcpy(io->buffer + io->buflen, buf, avail);
            io->buflen += avail;
            length -= avail;
            buf += avail;
        }
        else {
            memcpy(io->buffer + io->buflen, buf, length);
            io->buflen += length;
            length = 0;
            break;
        }
    }

#else /* H2_CONN_IO_USE_BUFFER */
    
    status = apr_brigade_write(io->output, flush_out, io, buf, length);
    if (status == APR_SUCCESS
        || APR_STATUS_IS_ECONNABORTED(status)
        || APR_STATUS_IS_EPIPE(status)) {
        /* These are all fine and no reason for concern. Everything else
         * is interesting. */
        status = APR_SUCCESS;
    }
    else {
        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, io->connection,
                      "h2_conn_io: write error");
    }
#endif /* H2_CONN_IO_USE_BUFFER (else) */
    
    return status;
}
Ejemplo n.º 7
0
void my_out_str(FILE *fp, unsigned long base, unsigned long digits, mpf_t f)
{
    unsigned long num_units = (digits + UNIT_SIZE-1)/UNIT_SIZE;
    unsigned long block_size =  (num_units + NUM_BLOCKS-1)/NUM_BLOCKS*UNIT_SIZE;
    mpf_init2(trunk, (int)(block_size*BITS_PER_DIGIT+1));

    unsigned long i = mpf_get_ui(f);
    fprintf(fp, "%lu.\n", i);
    mpf_sub_ui(f, f, i);
    my_out_str_raw(fp, digits, f, 0);
    if (out_ptr != out_buf)
        flush_out(fp);

    mpf_clear(trunk);
}
Ejemplo n.º 8
0
/*
 * The client must tell the package when an end-of-record has occurred.
 * The second paraemters tells whether the record should be flushed to the
 * (output) tcp stream.  (This let's the package support batched or
 * pipelined procedure calls.)  TRUE => immmediate flush to tcp connection.
 */
bool_t
xdrrec_endofrecord(XDR *xdrs, bool_t sendnow)
{
	register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
	register uint32_t len;  /* fragment length */

	if (sendnow || rstrm->frag_sent ||
		((long)rstrm->out_finger + BYTES_PER_XDR_UNIT >=
		(long)rstrm->out_boundry)) {
		rstrm->frag_sent = FALSE;
		return (flush_out(rstrm, TRUE));
	}
	len = (long)(rstrm->out_finger) - (long)(rstrm->frag_header) -
	   BYTES_PER_XDR_UNIT;
	*(rstrm->frag_header) = htonl((uint32_t)len | LAST_FRAG);
	rstrm->frag_header = (uint32_t *)(void *)rstrm->out_finger;
	rstrm->out_finger += BYTES_PER_XDR_UNIT;
	return (TRUE);
}
Ejemplo n.º 9
0
/*
 * The client must tell the package when an end-of-record has occurred.
 * The second paraemters tells whether the record should be flushed to the
 * (output) tcp stream.  (This let's the package support batched or
 * pipelined procedure calls.)  TRUE => immmediate flush to tcp connection.
 */
bool_t
xdrrec_endofrecord(XDR *xdrs, bool_t sendnow)
{
	RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
	u_long len;  /* fragment length */

	if (sendnow || rstrm->frag_sent ||
		((u_long)rstrm->out_finger + sizeof(u_int32_t) >=
		(u_long)rstrm->out_boundry)) {
		rstrm->frag_sent = FALSE;
		return (flush_out(rstrm, TRUE));
	}
	len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->frag_header) -
	   sizeof(u_int32_t);
	*(rstrm->frag_header) = htonl((u_int32_t)len | LAST_FRAG);
	rstrm->frag_header = (u_int32_t *)(void *)rstrm->out_finger;
	rstrm->out_finger += sizeof(u_int32_t);
	return (TRUE);
}
Ejemplo n.º 10
0
static bool_t
xdrrec_putlong(XDR *xdrs, long *lp)
{
	register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
	register int32_t *dest_lp = ((int32_t *)(void *)(rstrm->out_finger));

	if (rstrm->out_boundry - rstrm->out_finger < BYTES_PER_XDR_UNIT) {
		/*
		 * this case should almost never happen so the code is
		 * inefficient
		 */
		rstrm->frag_sent = TRUE;
		if (! flush_out(rstrm, FALSE))
			return (FALSE);
		dest_lp = ((int32_t *)(void *)(rstrm->out_finger));
	}
	rstrm->out_finger += BYTES_PER_XDR_UNIT;
	*dest_lp = (int32_t)htonl((uint32_t)(*lp));
	return (TRUE);
}
Ejemplo n.º 11
0
/*
 * The client must tell the package when an end-of-record has occurred.
 * The second paramter tells whether the record should be flushed to the
 * (output) tcp stream.  (This let's the package support batched or
 * pipelined procedure calls.)  true => immmediate flush to tcp connection.
 */
bool
xdrrec_endofrecord(XDR *xdrs, bool sendnow)
{
	RECSTREAM *rstrm = (RECSTREAM *) (xdrs->x_private);
	u_long len;		/* fragment length */

	if (sendnow || rstrm->frag_sent
	    || (PtrToUlong(rstrm->out_finger) + sizeof(u_int32_t) >=
		PtrToUlong(rstrm->out_boundry))) {
		rstrm->frag_sent = false;
		return (flush_out(rstrm, true));
	}
	len =
	    PtrToUlong((rstrm->out_finger)) - PtrToUlong((rstrm->frag_header)) -
	    sizeof(u_int32_t);
	*(rstrm->frag_header) = htonl((u_int32_t) len | LAST_FRAG);
	rstrm->frag_header = (u_int32_t *) (void *)rstrm->out_finger;
	rstrm->out_finger += sizeof(u_int32_t);
	return (true);
}
Ejemplo n.º 12
0
/*
 * The client must tell the package when an end-of-record has occurred.
 * The second parameters tells whether the record should be flushed to the
 * (output) tcp stream.  (This let's the package support batched or
 * pipelined procedure calls.)  TRUE => immediate flush to tcp connection.
 */
bool_t
xdrrec_endofrecord(
	XDR *xdrs,
	bool_t sendnow)
{
	register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
	register uint32_t len;  /* fragment length */

	if (sendnow || rstrm->frag_sent ||
		    (rstrm->out_finger + sizeof(uint32_t) >=
		    rstrm->out_boundry)) {
		rstrm->frag_sent = FALSE;
		return (flush_out(rstrm, TRUE));
	}
	len = (uint32_t)(rstrm->out_finger - (char*)rstrm->frag_header -
	   sizeof(uint32_t));
	*(rstrm->frag_header) = (uint32_t)htonl((uint32_t)(len | LAST_FRAG));
	rstrm->frag_header = (uint32_t*)rstrm->out_finger;
	rstrm->out_finger += sizeof(uint32_t);
	return (TRUE);
}
Ejemplo n.º 13
0
static bool_t
xdrrec_putlong(XDR *xdrs, const long *lp)
{
	RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
	int32_t *dest_lp = ((int32_t *)(void *)(rstrm->out_finger));

	if ((rstrm->out_finger += sizeof(int32_t)) > rstrm->out_boundry) {
		/*
		 * this case should almost never happen so the code is
		 * inefficient
		 */
		rstrm->out_finger -= sizeof(int32_t);
		rstrm->frag_sent = TRUE;
		if (! flush_out(rstrm, FALSE))
			return (FALSE);
		dest_lp = ((int32_t *)(void *)(rstrm->out_finger));
		rstrm->out_finger += sizeof(int32_t);
	}
	*dest_lp = (int32_t)htonl((u_int32_t)(*lp));
	return (TRUE);
}
Ejemplo n.º 14
0
/*
 * The client must tell the package when an end-of-record has occurred.
 * The second parameters tells whether the record should be flushed to the
 * (output) tcp stream.  (This let's the package support batched or
 * pipelined procedure calls.)  TRUE => immmediate flush to tcp connection.
 */
XDR_API bool_t
xdrrec_endofrecord(XDR *xdrs, bool_t sendnow)
{
	/* LINTED pointer cast */
	RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
	uint32_t len;	/* fragment length */

	if (sendnow || rstrm->frag_sent ||
		((uintptr_t)rstrm->out_finger + sizeof (uint32_t) >=
		(uintptr_t)rstrm->out_boundry)) {
		rstrm->frag_sent = FALSE;
		return (flush_out(rstrm, TRUE));
	}
	len = (uintptr_t)(rstrm->out_finger) - (uintptr_t)(rstrm->frag_header) -
		sizeof (uint32_t);
	*(rstrm->frag_header) = xdr_hton32((uint32_t)len | LAST_FRAG);
	/* LINTED pointer cast */
	rstrm->frag_header = (uint32_t *)rstrm->out_finger;
	rstrm->out_finger += sizeof (uint32_t);
	return (TRUE);
}
Ejemplo n.º 15
0
static bool_t
xdrrec_putbytes(XDR *xdrs, caddr_t addr, int32_t len)
{
	RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
	ptrdiff_t current;

	while (len > 0) {
		current = rstrm->out_boundry - rstrm->out_finger;
		current = (len < current) ? len : current;
		bcopy(addr, rstrm->out_finger, current);
		rstrm->out_finger += current;
		addr += current;
		len -= current;
		if (rstrm->out_finger == rstrm->out_boundry) {
			rstrm->frag_sent = TRUE;
			if (! flush_out(rstrm, FALSE))
				return (FALSE);
		}
	}
	return (TRUE);
}
Ejemplo n.º 16
0
static bool_t
xdrrec_putbytes(XDR *xdrs, const char *addr, u_int len)
{
	RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
	size_t current;

	while (len > 0) {
		current = (size_t)((u_long)rstrm->out_boundry -
		    (u_long)rstrm->out_finger);
		current = (len < current) ? len : current;
		memmove(rstrm->out_finger, addr, current);
		rstrm->out_finger += current;
		addr += current;
		len -= current;
		if (rstrm->out_finger == rstrm->out_boundry) {
			rstrm->frag_sent = TRUE;
			if (! flush_out(rstrm, FALSE))
				return (FALSE);
		}
	}
	return (TRUE);
}
Ejemplo n.º 17
0
static bool
xdrrec_putbytes(XDR *xdrs, const char *addr, u_int len)
{
	RECSTREAM *rstrm = (RECSTREAM *) (xdrs->x_private);
	size_t current;

	while (len > 0) {
		current =
		    (size_t) (PtrToUlong(rstrm->out_boundry) -
			      PtrToUlong(rstrm->out_finger));
		current = (len < current) ? len : current;
		memmove(rstrm->out_finger, addr, current);
		rstrm->out_finger += current;
		addr += current;
		len -= current;
		if (rstrm->out_finger == rstrm->out_boundry) {
			rstrm->frag_sent = true;
			if (!flush_out(rstrm, false))
				return (false);
		}
	}
	return (true);
}
Ejemplo n.º 18
0
static bool_t
xdrrec_putbytes(
	XDR *xdrs,
	register char* addr,
	register unsigned len)
{
	register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
	register int current;

	while (len != 0) {
		current = (int)(rstrm->out_boundry - rstrm->out_finger);
		current = (len < current) ? (int)len : current;
		bcopy(addr, rstrm->out_finger, current);
		rstrm->out_finger += current;
		addr += current;
		len -= current;
		if (rstrm->out_finger == rstrm->out_boundry) {
			rstrm->frag_sent = TRUE;
			if (! flush_out(rstrm, FALSE))
				return (FALSE);
		}
	}
	return (TRUE);
}
Ejemplo n.º 19
0
static bool_t
xdrrec_putint32(XDR *xdrs, int32_t *ip)
{
	/* LINTED pointer cast */
	RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
	/* LINTED pointer cast */
	int32_t *dest_lp = ((int32_t *)(rstrm->out_finger));

	if ((rstrm->out_finger += sizeof (int32_t)) > rstrm->out_boundry) {
		/*
		 * this case should almost never happen so the code is
		 * inefficient
		 */
		rstrm->out_finger -= sizeof (int32_t);
		rstrm->frag_sent = TRUE;
		if (!flush_out(rstrm, FALSE))
			return (FALSE);
		/* LINTED pointer cast */
		dest_lp = ((int32_t *)(rstrm->out_finger));
		rstrm->out_finger += sizeof (int32_t);
	}
	*dest_lp = (int32_t)xdr_hton32((uint32_t)(*ip));
	return (TRUE);
}
Ejemplo n.º 20
0
static bool_t
xdrrec_putbytes(XDR *xdrs, caddr_t addr, int len)
{
	/* LINTED pointer cast */
	RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
	int current;

	while (len > 0) {

		current = (uintptr_t)rstrm->out_boundry -
			(uintptr_t)rstrm->out_finger;
		current = (len < current) ? len : current;
		(void) memcpy(rstrm->out_finger, addr, current);
		rstrm->out_finger += current;
		addr += current;
		len -= current;
		if (rstrm->out_finger == rstrm->out_boundry) {
			rstrm->frag_sent = TRUE;
			if (!flush_out(rstrm, FALSE))
				return (FALSE);
		}
	}
	return (TRUE);
}
Ejemplo n.º 21
0
int main (int argc, char *argv[]) {
  int i;
  progname = argv[0];
  while ((i = getopt (argc, argv, "hvu:m:f:g:o:")) != -1) {
    switch (i) {
    case 'v':
      verbosity = 1;
      break;
    case 'h':
      usage();
      return 2;
    case 'm':
      assert (sscanf(optarg, "%d,%d", &split_rem, &split_mod) == 2);
      assert (split_mod > 0 && split_mod <= 1000 && split_rem >= 0 && split_rem < split_mod);
      break;
    case 'f':
      table_format = get_dump_format(optarg);
      if (!table_format) {
	fprintf (stderr, "fatal: unsupported table dump format: %s\n", optarg);
	return 2;
      }
      break;
    case 'g':
      groups_fname = optarg;
      break;
    case 'o':
      output_format = atol (optarg);
      break;
    case 'u':
      username = optarg;
      break;
    }
  }

  if (optind >= argc || optind + 2 < argc) {
    usage();
    return 2;
  }

  src_fname = argv[optind];

  if (username && change_user (username) < 0) {
    fprintf (stderr, "fatal: cannot change user to %s\n", username ? username : "******");
    return 1;
  }

  src_fd = open (src_fname, O_RDONLY);
  if (src_fd < 0) {
    fprintf (stderr, "cannot open %s: %m\n", src_fname);
    return 1;
  }

  if (!table_format) {
    table_format = get_dump_format (fname_last (src_fname));
    if (!table_format) {
      fprintf (stderr, "fatal: cannot determine table type from filename %s\n", src_fname);
    }
  }

  if (optind + 1 < argc) {
    targ_fname = argv[optind+1];
    targ_fd = open (targ_fname, O_WRONLY | O_APPEND | O_CREAT, 0644);
    if (targ_fd < 0) {
      fprintf (stderr, "cannot create %s: %m\n", targ_fname);
      return 1;
    }
  } else {
    targ_fname = "stdout";
    targ_fd = 1;
  }

  switch (table_format) {
  case TF_AUDIO:
    Args_per_line = au_END;
    start_binlog(SEARCH_SCHEMA_V1, "audio_search");
    while (read_record() > 0) {
      process_audio_row();
    }
    break;
  case TF_VIDEO:
    Args_per_line = vi_END;
    start_binlog(SEARCH_SCHEMA_V1, "video_search");
    while (read_record() > 0) {
      process_video_row();
    }
    break;
  case TF_APPS:
    Args_per_line = ap_END;
    start_binlog(SEARCH_SCHEMA_V1, "apps_search");
    while (read_record() > 0) {
      process_applications_row();
    }
    break;
  case TF_GROUPS:
    Args_per_line = gr_END;
    start_binlog(SEARCH_SCHEMA_V1, "group_search");
    while (read_record() > 0) {
      process_groups_row();
    }
    break;
  case TF_EVENTS:
    Args_per_line = gr_END;
    start_binlog(SEARCH_SCHEMA_V1, "event_search");
    while (read_record() > 0) {
      process_events_row();
    }
    break;
  case TF_BLOG_POSTS:
    Args_per_line = bp_END;
    start_binlog(SEARCH_SCHEMA_V1, "blog_posts_search");
    while (read_record() > 0) {
      process_blog_posts_row();
    }
    break;
  case TF_MEMLITE:
    Args_per_line = ml_END;
    start_binlog(SEARCH_SCHEMA_V1, "member_name_search");
    while (read_record() > 0) {
      process_memlite_row();
    }
    break;
  case TF_MARKET_ITEMS:
    Args_per_line = mi_END;
    start_binlog(SEARCH_SCHEMA_V1, "market_search");
    while (read_record() > 0) {
      process_market_row();
    }
    break;
  case TF_QUESTIONS:
    Args_per_line = qu_END;
    start_binlog(SEARCH_SCHEMA_V1, "question_search");
    while (read_record() > 0) {
      process_questions_row();
    }
    break;
  case TF_TOPICS:
    load_map (1);
    Args_per_line = to_END;
    start_binlog(SEARCH_SCHEMA_V1, "topic_search");
    while (read_record() > 0) {
      process_topics_row();
    }
    break;
  case TF_MINIFEED:
    Args_per_line = mf_END;
    start_binlog(SEARCH_SCHEMA_V1, "status_search");
    while (read_record() > 0) {
      process_minifeed_row();
    }
    break;
  default:
    fprintf (stderr, "unknown table type\n");
    exit(1);
  }

  flush_out();
  if (targ_fd != 1) {
    if (fdatasync(targ_fd) < 0) {
      fprintf (stderr, "error syncing %s: %m", targ_fname);
      exit (1);
    }
    close (targ_fd);
  }

  if (map_size > 0 && map_changes > 0 && groups_fname) {
    map_fd = open (groups_fname, O_WRONLY | O_CREAT | O_TRUNC, 0640);
    if (map_fd < 0) {
      fprintf (stderr, "cannot create map file %s: %m\n", groups_fname);
      exit (1);
    }
    assert (write (map_fd, Map, map_size) == map_size);
    close (map_fd);
    if (verbosity > 0) {
      fprintf (stderr, "%d bytes written to map file %s\n", map_size, groups_fname);
    }
  }

  if (verbosity > 0) {
    output_stats();
  }

  return 0;
}
Ejemplo n.º 22
0
int main (int argc, char *argv[]) {
  int i;
  progname = argv[0];
  while ((i = getopt (argc, argv, "fhvu:m:s:t:M:F")) != -1) {
    switch (i) {
    case 'F':
      filter_member_fan = 1;
      break;
    case 'v':
      verbosity += 1;
      break;
    case 'f':
      // vkprintf(2, "setting skip_rotate\n");
      skip_rotate = 1;
      break;
    case 'h':
      usage ();
      return 2;
    case 'u':
      username = optarg;
      break;
    case 'm':
      if (sscanf (optarg, "%d,%d", &copy_rem, &copy_mod) != 2 || copy_rem < 0 || copy_rem >= copy_mod) {
	usage();
	return 2;
      }
      break;
    case 's':
      jump_log_pos = atoll (optarg);
      break;
    case 't':
      keep_log_limit_pos = log_limit_pos = atoll (optarg);
      break;
    case 'M':
      if (!strncmp(optarg, "firstint", 9)) {
        split_mode = SPLIT_FIRSTINT;
      } else if (!strncmp(optarg, "liked", 6)) {
        split_mode = SPLIT_LIKED;
      } else {
        usage();
        return 2;
      }
      break;
    default:
      assert (0);
      return 2;
    }
  }

  if (optind >= argc || optind + 2 < argc) {
    usage();
    return 2;
  }

  if (filter_member_fan) {
    vkprintf (1, "fix member_fans, fan_members mode\n");
    char *p = strrchr (argv[optind], '/');
    p = (p == NULL) ? argv[optind] : (p + 1);
    if (!strncmp (p, "member_fans", 11)) {
      want_write = member_fans_want_write;
    } else if (!strncmp (p, "fan_members", 11)) {
      want_write = fan_members_want_write;
    } else {
      kprintf ("binlogname should starts from member_fans of fan_members when command line switch -F used.\n");
      exit (1);
    }
  }

  if (log_limit_pos >= 0) {
    if (jump_log_pos > log_limit_pos) {
      fprintf (stderr, "fatal: log start position %lld after stop position %lld\n", jump_log_pos, log_limit_pos);
      return 2;
    }
  }

  if (username && change_user (username) < 0) {
    fprintf (stderr, "fatal: cannot change user to %s\n", username ? username : "******");
    return 1;
  }

  if (engine_preload_filelist (argv[optind], binlogname) < 0) {
    fprintf (stderr, "cannot open binlog files for %s\n", binlogname ? binlogname : argv[optind]);
    exit (1);
  }

  Binlog = open_binlog (engine_replica, 0);
  if (!Binlog) {
    fprintf (stderr, "fatal: cannot find binlog for %s, log position %lld\n", engine_replica->replica_prefix, 0LL);
    exit (1);
  }

  binlogname = Binlog->info->filename;

  if (verbosity) {
    fprintf (stderr, "replaying binlog file %s (size %lld)\n", binlogname, Binlog->info->file_size);
  }

  clear_log();

  init_log_data (0, 0, 0);

  if (optind + 1 < argc) {
    targ_fname = argv[optind+1];
    targ_fd = open (targ_fname, O_WRONLY | O_APPEND | O_CREAT, 0644);
    if (targ_fd < 0) {
      fprintf (stderr, "cannot create %s: %m\n", targ_fname);
      return 1;
    }
    targ_orig_size = lseek (targ_fd, 0, SEEK_END);
    targ_existed = (targ_orig_size > 0);
  } else {
    targ_fname = "stdout";
    targ_fd = 1;
  }

  if (jump_log_pos > 0) {

    log_limit_pos = 256;
    immediate_exit = 1;

    i = replay_log (0, 1);

    if (!list_id_ints) {
      fprintf (stderr, "fatal: cannot parse first LEV_START entry");
      exit (1);
    }

    log_limit_pos = keep_log_limit_pos;
    immediate_exit = 0;

    clear_log ();

    close_binlog (Binlog, 1);
    Binlog = 0;

    Binlog = open_binlog (engine_replica, jump_log_pos);
    if (!Binlog) {
      fprintf (stderr, "fatal: cannot find binlog for %s, log position %lld\n", engine_replica->replica_prefix, jump_log_pos);
      exit (1);
    }

    binlogname = Binlog->info->filename;

    if (verbosity) {
      fprintf (stderr, "replaying binlog file %s (size %lld) from log position %lld\n", binlogname, Binlog->info->file_size, jump_log_pos);
    }

    init_log_data (jump_log_pos, 0, 0);
  }

  i = replay_log (0, 1);

  if (i < 0) {
    fprintf (stderr, "fatal: error reading binlog\n");
    exit (1);
  }

  if (log_limit_pos >= 0 && log_readto_pos != log_limit_pos) {
    fprintf (stderr, "fatal: binlog read up to position %lld instead of %lld\n", log_readto_pos, log_limit_pos);
    exit (1);
  }

  if (!targ_orig_size && !jump_log_pos) {
    vkprintf (1, "Writing CRC32 to the end of target binlog.\n");
    struct lev_crc32 *C = write_alloc (20);
    C->type = LEV_CRC32;
    C->timestamp = last_timestamp;
    C->pos = wr_bytes;
    C->crc32 = ~wr_crc32_complement;
    wr_bytes += 20;
    wr_rec++;
  }

  flush_out ();

  if (targ_fd != 1) {
    if (fdatasync (targ_fd) < 0) {
      fprintf (stderr, "error syncing %s: %m", targ_fname);
      exit (1);
    }
    close (targ_fd);
  }

  if (verbosity > 0) {
    output_stats ();
  }

  return 0;
}
Ejemplo n.º 23
0
int main (int argc, char *argv[]) {
  int i;
  progname = argv[0];
  while ((i = getopt (argc, argv, "hvu:m:s:t:p")) != -1) {
    switch (i) {
    case 'p':
      fits = positive_counter_fits;
      break;
    case 'v':
      verbosity = 1;
      break;
    case 'h':
      usage();
      return 2;
    case 'u':
      username = optarg;
      break;
    case 'm':
      if (sscanf (optarg, "%d,%d", &copy_rem, &copy_mod) != 2 || copy_rem < 0 || copy_rem >= copy_mod) {
	usage();
	return 2;
      }
      break;
    case 's':
      jump_log_pos = atoll (optarg);
      break;
    case 't':
      log_limit_pos = atoll (optarg);
      break;
    }
  }

  if (copy_mod < 0) {
    usage ();
    return 2;
  }

  if (optind >= argc || optind + 2 < argc) {
    usage();
    return 2;
  }

  if (log_limit_pos >= 0) {
    if (jump_log_pos > log_limit_pos) {
      fprintf (stderr, "fatal: log start position %lld after stop position %lld\n", jump_log_pos, log_limit_pos);
      return 2;
    }
  }

  if (username && change_user (username) < 0) {
    fprintf (stderr, "fatal: cannot change user to %s\n", username ? username : "******");
    return 1;
  }

  if (engine_preload_filelist (argv[optind], binlogname) < 0) {
    fprintf (stderr, "cannot open binlog files for %s\n", binlogname ? binlogname : argv[optind]);
    exit (1);
  }

  Binlog = open_binlog (engine_replica, jump_log_pos);
  if (!Binlog) {
    fprintf (stderr, "fatal: cannot find binlog for %s, log position %lld\n", engine_replica->replica_prefix, 0LL);
    exit (1);
  }

  binlogname = Binlog->info->filename;

  if (verbosity) {
    fprintf (stderr, "replaying binlog file %s (size %lld)\n", binlogname, Binlog->info->file_size);
  }

  clear_log();

  init_log_data (jump_log_pos, 0, 0);

  if (jump_log_pos > 0) {
    init_stats_data (0);
  }

  if (optind + 1 < argc) {
    targ_fname = argv[optind+1];
    targ_fd = open (targ_fname, O_WRONLY | O_APPEND | O_CREAT, 0644);
    if (targ_fd < 0) {
      fprintf (stderr, "cannot create %s: %m\n", targ_fname);
      return 1;
    }
    targ_orig_size = lseek (targ_fd, 0, SEEK_END);
    targ_existed = (targ_orig_size > 0);
  } else {
    targ_fname = "stdout";
    targ_fd = 1;
  }

  i = replay_log (0, 1);

  if (i < 0) {
    fprintf (stderr, "fatal: error reading binlog\n");
    exit (1);
  }

  if (log_limit_pos >= 0 && log_readto_pos != log_limit_pos) {
    fprintf (stderr, "fatal: binlog read up to position %lld instead of %lld\n", log_readto_pos, log_limit_pos);
    exit (1);
  }

  flush_out ();

  if (targ_fd != 1) {
    if (fdatasync (targ_fd) < 0) {
      fprintf (stderr, "error syncing %s: %m", targ_fname);
      exit (1);
    }
    close (targ_fd);
  }

  if (verbosity > 0) {
    output_stats ();
  }

  return 0;
}