int recv_pkt(pkt *Pkt, int socket, struct sockaddr_in *src_addr, uint32_t buffsize)
{
    int flags = 0;
    int src_addr_len = sizeof(*src_addr);
    //  uint32_t i;

    if (Pkt != NULL && Pkt->datagram != NULL)
    {
        Pkt->datagram_len = s_recvfrom(socket, Pkt->datagram, buffsize+HDR_LEN, flags,
                                       (struct sockaddr *)src_addr, (socklen_t *)&(src_addr_len));
        Pkt->data_len = Pkt->datagram_len - HDR_LEN;
        if (pkt_checksum(Pkt) == CHECKSUM_GOOD)
        {
            get_hdr(Pkt);
            //	  printf("--Recv--\n");
            //	  print_hdr(Pkt);
            //	  printf("--------\n");
            return 1;
        }
        else
            return 0;
    }
    return 0;
}
Exemple #2
0
/* Re-parsing version of build_local() function:
 * it builds a local CANCEL or ACK (for non-200 response) request based on
 * the previous INVITE which was sent out.
 *
 * Can not be used to build other type of requests!
 */
char *build_local_reparse(struct cell *Trans,unsigned int branch,
	unsigned int *len, char *method, int method_len, str *to
#ifdef CANCEL_REASON_SUPPORT
	, struct cancel_reason *reason
#endif /* CANCEL_REASON_SUPPORT */
	)
{
	char	*invite_buf, *invite_buf_end;
	char	*cancel_buf;
	char	*s, *s1, *d;	/* source and destination buffers */
	short	invite_len;
	enum _hdr_types_t	hf_type;
	int	first_via, to_len;
	int cancel_buf_len;
#ifdef CANCEL_REASON_SUPPORT
	int reason_len, code_len;
	struct hdr_field *reas1, *reas_last, *hdr;
#endif /* CANCEL_REASON_SUPPORT */
	int hadded = 0;
	sr_cfgenv_t *cenv = NULL;

	invite_buf = Trans->uac[branch].request.buffer;
	invite_len = Trans->uac[branch].request.buffer_len;

	if (!invite_buf || !invite_len) {
		LM_ERR("INVITE is missing\n");
		goto error;
	}
	if ((*invite_buf != 'I') && (*invite_buf != 'i')) {
		LM_ERR("trying to build with local reparse"
					" for a non-INVITE request?\n");
		goto error;
	}

#ifdef CANCEL_REASON_SUPPORT
	reason_len = 0;
	reas1 = 0;
	reas_last = 0;
	/* compute reason size (if no reason or disabled => reason_len == 0)*/
	if (reason && reason->cause != CANCEL_REAS_UNKNOWN){
		if (likely(reason->cause > 0 &&
					cfg_get(tm, tm_cfg, local_cancel_reason))){
			/* Reason: SIP;cause=<reason->cause>[;text=<reason->u.text.s>] */
			reason_len = REASON_PREFIX_LEN + USHORT2SBUF_MAX_LEN +
				(reason->u.text.s?
					REASON_TEXT_LEN + 1 + reason->u.text.len + 1 : 0) +
				CRLF_LEN;
		} else if (likely(reason->cause == CANCEL_REAS_PACKED_HDRS &&
					!(Trans->flags & T_NO_E2E_CANCEL_REASON))) {
			reason_len = reason->u.packed_hdrs.len;
		} else if (reason->cause == CANCEL_REAS_RCVD_CANCEL &&
					reason->u.e2e_cancel &&
					!(Trans->flags & T_NO_E2E_CANCEL_REASON)) {
			/* parse the entire cancel, to get all the Reason headers */
			if(parse_headers(reason->u.e2e_cancel, HDR_EOH_F, 0)<0) {
				LM_WARN("failed to parse headers\n");
			}
			for(hdr=get_hdr(reason->u.e2e_cancel, HDR_REASON_T), reas1=hdr;
					hdr; hdr=next_sibling_hdr(hdr)) {
				/* hdr->len includes CRLF */
				reason_len += hdr->len;
				reas_last=hdr;
			}
		} else if (unlikely(reason->cause < CANCEL_REAS_MIN))
			LM_BUG("unhandled reason cause %d\n", reason->cause);
	}
#endif /* CANCEL_REASON_SUPPORT */

	invite_buf_end = invite_buf + invite_len;
	s = invite_buf;

	/* Allocate memory for the new message.
	The new request will be smaller than the INVITE, so the same size is enough.
	I just extend it with the length of new To HF to be sure.
	Ugly, but we avoid lots of checks and memory allocations this way */
	to_len = to ? to->len : 0;
#ifdef CANCEL_REASON_SUPPORT
	cancel_buf_len = invite_len + to_len + reason_len;
#else
	cancel_buf_len = invite_len + to_len;
#endif /* CANCEL_REASON_SUPPORT */
	cancel_buf = shm_malloc(sizeof(char)*cancel_buf_len);
	if (!cancel_buf)
	{
		LM_ERR("cannot allocate shared memory\n");
		goto error;
	}
	d = cancel_buf;

	/* method name + space */
	append_str(d, method, method_len);
	*d = ' ';
	d++;
	/* skip "INVITE " and copy the rest of the line including CRLF */
	s += 7;
	s1 = s;
	s = eat_line(s, invite_buf_end - s);
	append_str(d, s1, s - s1);

	cenv = sr_cfgenv_get();

	/* check every header field name,
	we must exclude and modify some of the headers */
	first_via = 1;
	while (s < invite_buf_end) {
		s1 = s;
		if ((*s == '\n') || (*s == '\r')) {
			/* end of SIP msg */
			hf_type = HDR_EOH_T;
		} else {
			/* parse HF name */
			s = lw_get_hf_name(s, invite_buf_end,
						&hf_type);
		}

		switch(hf_type) {
			case HDR_CSEQ_T:
				/* find the method name and replace it */
				while ((s < invite_buf_end)
					&& ((*s == ':') || (*s == ' ') || (*s == '\t') ||
						((*s >= '0') && (*s <= '9')))
					) s++;
				append_str(d, s1, s - s1);
				append_str(d, method, method_len);
				append_str(d, CRLF, CRLF_LEN);
				s = lw_next_line(s, invite_buf_end);
				break;

			case HDR_VIA_T:
				s = lw_next_line(s, invite_buf_end);
				if (first_via) {
					/* copy hf */
					append_str(d, s1, s - s1);
					first_via = 0;
				} /* else skip this line, we need olny the first via */
				break;

			case HDR_TO_T:
				if (to_len == 0) {
					/* there is no To tag required, just copy paste
					 * the header */
					s = lw_next_line(s, invite_buf_end);
					append_str(d, s1, s - s1);
				} else {
					/* use the given To HF instead of the original one */
					append_str(d, to->s, to->len);
					/* move the pointer to the next line */
					s = lw_next_line(s, invite_buf_end);
				}
				break;

			case HDR_FROM_T:
			case HDR_CALLID_T:
			case HDR_ROUTE_T:
			case HDR_MAXFORWARDS_T:
				/* copy hf */
				s = lw_next_line(s, invite_buf_end);
				append_str(d, s1, s - s1);
				break;

			case HDR_REQUIRE_T:
			case HDR_PROXYREQUIRE_T:
				/* skip this line */
				s = lw_next_line(s, invite_buf_end);
				break;

			case HDR_CONTENTLENGTH_T:
				/* copy hf name with 0 value */
				append_str(d, s1, s - s1);
				append_str(d, ": 0" CRLF, 3 + CRLF_LEN);
				/* move the pointer to the next line */
				s = lw_next_line(s, invite_buf_end);
				break;

			case HDR_EOH_T:
				/* end of SIP message found */
#ifdef CANCEL_REASON_SUPPORT
				/* add reason if needed */
				if (reason_len) {
					/* if reason_len !=0, no need for any reason enabled
					 * checks */
					if (likely(reason->cause > 0)) {
						append_str(d, REASON_PREFIX, REASON_PREFIX_LEN);
						code_len=ushort2sbuf(reason->cause, d,
										cancel_buf_len-(int)(d-cancel_buf));
						if (unlikely(code_len==0))
							LM_BUG("not enough space to write reason code");
						d+=code_len;
						if (reason->u.text.s){
							append_str(d, REASON_TEXT, REASON_TEXT_LEN);
							*d='"'; d++;
							append_str(d, reason->u.text.s,
											reason->u.text.len);
							*d='"'; d++;
						}
						append_str(d, CRLF, CRLF_LEN);
					} else if (likely(reason->cause ==
										CANCEL_REAS_PACKED_HDRS)) {
							append_str(d, reason->u.packed_hdrs.s,
											reason->u.packed_hdrs.len);
					} else if (reason->cause == CANCEL_REAS_RCVD_CANCEL) {
						for(hdr=reas1; hdr; hdr=next_sibling_hdr(hdr)) {
							/* hdr->len includes CRLF */
							append_str(d, hdr->name.s, hdr->len);
							if (likely(hdr==reas_last))
								break;
						}
					}
				}
#endif /* CANCEL_REASON_SUPPORT */
				/* final (end-of-headers) CRLF */
				append_str(d, CRLF, CRLF_LEN);
				*len = d - cancel_buf;
				/* LOG(L_DBG, "DBG: build_local: %.*s\n", *len, cancel_buf); */
				return cancel_buf;

			default:
				s = lw_next_line(s, invite_buf_end);
				hadded = 0;

				/* uac auth headers */
				if(Trans->uas.request &&
						(Trans->uas.request->msg_flags & FL_UAC_AUTH)) {
					if(s1 + cenv->uac_cseq_auth.len + 2 < invite_buf_end) {
						if(s1[cenv->uac_cseq_auth.len]==':'
								&& strncmp(s1, cenv->uac_cseq_auth.s,
									cenv->uac_cseq_auth.len)==0) {
							hadded = 1;
							append_str(d, s1, s - s1);
						} else if(s1[cenv->uac_cseq_refresh.len]==':'
								&& strncmp(s1, cenv->uac_cseq_refresh.s,
									cenv->uac_cseq_refresh.len)==0) {
							hadded = 1;
							append_str(d, s1, s - s1);
						}
					}
				}

				if(likely(hadded==0)) {
					if (cfg_get(tm, tm_cfg, ac_extra_hdrs).len
							&& (s1 + cfg_get(tm, tm_cfg, ac_extra_hdrs).len < invite_buf_end)
							&& (strncasecmp(s1,
									cfg_get(tm, tm_cfg, ac_extra_hdrs).s,
									cfg_get(tm, tm_cfg, ac_extra_hdrs).len) == 0)) {
						append_str(d, s1, s - s1);
					}
				}
				break;
		}
	}

	/* HDR_EOH_T was not found in the buffer, the message is corrupt */
	LM_ERR("HDR_EOH_T was not found\n");

	shm_free(cancel_buf);
error:
	LM_ERR("cannot build %.*s request\n", method_len, method);
	return NULL;

}
Exemple #3
0
/* Build a local request based on a previous request; main
 * customers of this function are local ACK and local CANCEL
 */
char *build_local(struct cell *Trans,unsigned int branch,
	unsigned int *len, char *method, int method_len, str *to
#ifdef CANCEL_REASON_SUPPORT
	, struct cancel_reason* reason
#endif /* CANCEL_REASON_SUPPORT */
	)
{
	char                *cancel_buf, *p, *via;
	unsigned int         via_len;
	struct hdr_field    *hdr;
	char branch_buf[MAX_BRANCH_PARAM_LEN];
	int branch_len;
	str branch_str;
	str via_id;
	struct hostport hp;
#ifdef CANCEL_REASON_SUPPORT
	int reason_len, code_len;
	struct hdr_field *reas1, *reas_last;
#endif /* CANCEL_REASON_SUPPORT */

	/* init */
	via_id.s=0;
	via_id.len=0;

	/* method, separators, version: "CANCEL sip:[email protected] SIP/2.0" */
	*len=SIP_VERSION_LEN + method_len + 2 /* spaces */ + CRLF_LEN;
	*len+=Trans->uac[branch].uri.len;

	/*via*/
	if (!t_calc_branch(Trans,  branch,
		branch_buf, &branch_len ))
		goto error;
	branch_str.s=branch_buf;
	branch_str.len=branch_len;
	set_hostport(&hp, (is_local(Trans))?0:(Trans->uas.request));
#ifdef USE_TCP
	if (!is_local(Trans) && ((Trans->uas.request->rcv.proto==PROTO_TCP)
#ifdef USE_TLS
				|| (Trans->uas.request->rcv.proto==PROTO_TLS)
#endif /* USE_TLS */
		)){
		if ((via_id.s=id_builder(Trans->uas.request,
									(unsigned int*)&via_id.len))==0){
			LM_ERR("id builder failed\n");
			/* try to continue without id */
		}
	}
#endif /* USE_TCP */
	via=via_builder(&via_len, NULL, &Trans->uac[branch].request.dst,
		&branch_str, via_id.s?&via_id:0 , &hp );

	/* via_id.s not needed anylonger => free it */
	if (via_id.s) {
		pkg_free(via_id.s);
		via_id.s=0;
		via_id.len=0;
	}

	if (!via) {
		LM_ERR("no via header got from builder\n");
		goto error;
	}
	*len+= via_len;
	/*headers*/
	*len+=Trans->from.len+Trans->callid.len+to->len+
		+Trans->cseq_n.len+1+method_len+CRLF_LEN+MAXFWD_HEADER_LEN;


	/* copy'n'paste Route headers */
	if (!is_local(Trans)) {
		for ( hdr=Trans->uas.request->headers ; hdr ; hdr=hdr->next )
			if (hdr->type==HDR_ROUTE_T)
				*len+=hdr->len;
	}

	/* User Agent */
	if (server_signature) {
		*len += user_agent_hdr.len + CRLF_LEN;
	}
	/* Content Length, EoM */
	*len+=CONTENT_LENGTH_LEN+1 + CRLF_LEN;
#ifdef CANCEL_REASON_SUPPORT
	reason_len = 0;
	reas1 = 0;
	reas_last = 0;
	/* compute reason size (if no reason or disabled => reason_len == 0)*/
	if (reason && reason->cause != CANCEL_REAS_UNKNOWN){
		if (likely(reason->cause > 0 &&
					cfg_get(tm, tm_cfg, local_cancel_reason))){
			/* Reason: SIP;cause=<reason->cause>[;text=<reason->u.text.s>] */
			reason_len = REASON_PREFIX_LEN + USHORT2SBUF_MAX_LEN +
				(reason->u.text.s?
					REASON_TEXT_LEN + 1 + reason->u.text.len + 1 : 0) +
				CRLF_LEN;
		} else if (likely(reason->cause == CANCEL_REAS_PACKED_HDRS &&
					!(Trans->flags & T_NO_E2E_CANCEL_REASON))) {
			reason_len = reason->u.packed_hdrs.len;
		} else if (reason->cause == CANCEL_REAS_RCVD_CANCEL &&
					reason->u.e2e_cancel &&
					!(Trans->flags & T_NO_E2E_CANCEL_REASON)) {
			/* parse the entire cancel, to get all the Reason headers */
			if(parse_headers(reason->u.e2e_cancel, HDR_EOH_F, 0)<0) {
				LM_WARN("failed to parse headers\n");
			}
			for(hdr=get_hdr(reason->u.e2e_cancel, HDR_REASON_T), reas1=hdr;
					hdr; hdr=next_sibling_hdr(hdr)) {
				/* hdr->len includes CRLF */
				reason_len += hdr->len;
				reas_last=hdr;
			}
		} else if (unlikely(reason->cause < CANCEL_REAS_MIN))
			LM_BUG("unhandled reason cause %d\n", reason->cause);
	}
	*len+= reason_len;
#endif /* CANCEL_REASON_SUPPORT */
	*len+= CRLF_LEN; /* end of msg. */

	cancel_buf=shm_malloc( *len+1 );
	if (!cancel_buf) {
		LM_ERR("cannot allocate memory\n");
		goto error01;
	}
	p = cancel_buf;

	append_str( p, method, method_len );
	append_str( p, " ", 1 );
	append_str( p, Trans->uac[branch].uri.s, Trans->uac[branch].uri.len);
	append_str( p, " " SIP_VERSION CRLF, 1+SIP_VERSION_LEN+CRLF_LEN );

	/* insert our via */
	append_str(p,via,via_len);

	/*other headers*/
	append_str( p, Trans->from.s, Trans->from.len );
	append_str( p, Trans->callid.s, Trans->callid.len );
	append_str( p, to->s, to->len );

	append_str( p, Trans->cseq_n.s, Trans->cseq_n.len );
	append_str( p, " ", 1 );
	append_str( p, method, method_len );
	append_str( p, CRLF, CRLF_LEN );
	append_str( p, MAXFWD_HEADER, MAXFWD_HEADER_LEN );

	if (!is_local(Trans))  {
		for ( hdr=Trans->uas.request->headers ; hdr ; hdr=hdr->next )
			if(hdr->type==HDR_ROUTE_T) {
				append_str(p, hdr->name.s, hdr->len );
			}
	}

	/* User Agent header */
	if (server_signature) {
		append_str(p, user_agent_hdr.s, user_agent_hdr.len );
		append_str(p, CRLF, CRLF_LEN );
	}
	/* Content Length */
	append_str(p, CONTENT_LENGTH "0" CRLF, CONTENT_LENGTH_LEN + 1 + CRLF_LEN);
#ifdef CANCEL_REASON_SUPPORT
	/* add reason if needed */
	if (reason_len) {
		if (likely(reason->cause > 0)) {
			append_str(p, REASON_PREFIX, REASON_PREFIX_LEN);
			code_len=ushort2sbuf(reason->cause, p,
									*len-(int)(p-cancel_buf));
			if (unlikely(code_len==0))
				LM_BUG("not enough space to write reason code");
			p+=code_len;
			if (reason->u.text.s){
				append_str(p, REASON_TEXT, REASON_TEXT_LEN);
				*p='"'; p++;
				append_str(p, reason->u.text.s, reason->u.text.len);
				*p='"'; p++;
			}
			append_str(p, CRLF, CRLF_LEN);
		} else if (likely(reason->cause == CANCEL_REAS_PACKED_HDRS)) {
			append_str(p, reason->u.packed_hdrs.s, reason->u.packed_hdrs.len);
		} else if (reason->cause == CANCEL_REAS_RCVD_CANCEL) {
			for(hdr=reas1; hdr; hdr=next_sibling_hdr(hdr)) {
				/* hdr->len includes CRLF */
				append_str(p, hdr->name.s, hdr->len);
				if (likely(hdr==reas_last))
					break;
			}
		}
	}
#endif /* CANCEL_REASON_SUPPORT */
	append_str(p, CRLF, CRLF_LEN); /* msg. end */
	*p=0;

	pkg_free(via);
	return cancel_buf;
error01:
	pkg_free(via);
error:
	return NULL;
}
Exemple #4
0
int main(int argc, char *argv[])
{
	GOptionContext *context;
	GError *error = NULL;

	struct stats_file_header *hdr;
	struct stats_file data, *data_file;
	struct stats_record *rec;
	time_t start_ts;
	int err;

	rec = NULL;

	data_file = &data;

	putenv("TZ=GMT0");

	context = g_option_context_new(NULL);
	g_option_context_add_main_entries(context, options, NULL);

	if (!g_option_context_parse(context, &argc, &argv, &error)) {
		if (error) {
			g_printerr("%s\n", error->message);
			g_error_free(error);
		} else
			g_printerr("An unknown error occurred\n");
		exit(1);
	}

	g_option_context_free(context);

	if (argc < 2) {
		printf("Usage: %s [FILENAME]\n", argv[0]);
		exit(0);
	}

	err = stats_open(data_file, argv[1]);
	if (err < 0) {
		fprintf(stderr, "failed open file %s\n", argv[1]);
		exit(1);
	}

	if (option_last_file_name) {
		struct stats_file last;
		if (stats_open(&last, option_last_file_name) < 0) {
			fprintf(stderr, "failed open file %s\n",
				option_last_file_name);
			exit(1);
		}

		rec = get_end(&last);
	}

	if (option_start_ts == -1)
		start_ts = time(NULL);
	else
		start_ts = option_start_ts;

	if (option_create > 0)
		stats_create(data_file, option_create, option_interval,
				start_ts, rec);

	hdr = get_hdr(data_file);
	if (hdr->magic != MAGIC) {
		fprintf(stderr, "header file magic test failed\n");
		goto err;
	}

	stats_file_update_cache(data_file);

	stats_hdr_info(data_file);

	if (option_dump)
		stats_print_entries(data_file);

	if (option_summary)
		stats_print_diff(data_file);

	if (option_info_file_name)
		history_file_update(data_file, option_info_file_name);

err:
	stats_close(data_file);

	return 0;
}
Exemple #5
0
static void WINAPI con_interrupt(CONTEXT*ctx)
{
  int *scan;
  REQUEST_HEADER *hdr = get_hdr(SYSTEM_STRATEGY_CON,(void **)&scan);
  BIOSDATA *bios = DOSVM_BiosData();
  WORD CurOfs = bios->NextKbdCharPtr;
  DOS_LISTOFLISTS *lol = DOSMEM_LOL();
  DOS_DATASEG *dataseg = (DOS_DATASEG *)lol;
  BYTE *linebuffer = dataseg->buffer;
  BYTE *curbuffer = (lol->offs_unread_CON) ?
    (((BYTE*)dataseg) + lol->offs_unread_CON) : NULL;
  DOS_DEVICE_HEADER *con = dataseg->dev;
  DWORD w;

  switch (hdr->command) {
  case CMD_INPUT:
    {
      REQ_IO *io = (REQ_IO *)hdr;
      WORD count = io->count, len = 0;
      BYTE *buffer = CTX_SEG_OFF_TO_LIN(ctx,
					SELECTOROF(io->buffer),
					(DWORD)OFFSETOF(io->buffer));

      hdr->status = STAT_BUSY;
      /* first, check whether we already have data in line buffer */
      if (curbuffer) {
	/* yep, copy as much as we can */
	BYTE data = 0;
	while ((len<count) && (data != '\r')) {
	  data = *curbuffer++;
	  buffer[len++] = data;
	}
	if (data == '\r') {
	  /* line buffer emptied */
	  lol->offs_unread_CON = 0;
	  curbuffer = NULL;
	  /* if we're not in raw mode, call it a day */
	  if (!(con->attr & ATTR_RAW)) {
	    hdr->status = STAT_DONE;
	    io->count = len;
	    break;
	  }
	} else {
	  /* still some data left */
	  lol->offs_unread_CON = curbuffer - (BYTE*)lol;
	  /* but buffer was filled, we're done */
	  hdr->status = STAT_DONE;
	  io->count = len;
	  break;
	}
      }

      /* if we're in raw mode, we just need to fill the buffer */
      if (con->attr & ATTR_RAW) {
	while (len<count) {
	  WORD data;

	  /* do we have a waiting scancode? */
	  if (*scan) {
	    /* yes, store scancode in buffer */
	    buffer[len++] = *scan;
	    *scan = 0;
	    if (len==count) break;
	  }

	  /* check for new keyboard input */
	  while (CurOfs == bios->FirstKbdCharPtr) {
	    /* no input available yet, so wait... */
	    DOSVM_Wait( ctx );
	  }
	  /* read from keyboard queue (call int16?) */
	  data = ((WORD*)bios)[CurOfs];
	  CurOfs += 2;
	  if (CurOfs >= bios->KbdBufferEnd) CurOfs = bios->KbdBufferStart;
	  bios->NextKbdCharPtr = CurOfs;
	  /* if it's an extended key, save scancode */
	  if (LOBYTE(data) == 0) *scan = HIBYTE(data);
	  /* store ASCII char in buffer */
	  buffer[len++] = LOBYTE(data);
	}
      } else {
	/* we're not in raw mode, so we need to do line input... */
	while (TRUE) {
	  WORD data;
	  /* check for new keyboard input */
	  while (CurOfs == bios->FirstKbdCharPtr) {
	    /* no input available yet, so wait... */
	    DOSVM_Wait( ctx );
	  }
	  /* read from keyboard queue (call int16?) */
	  data = ((WORD*)bios)[CurOfs];
	  CurOfs += 2;
	  if (CurOfs >= bios->KbdBufferEnd) CurOfs = bios->KbdBufferStart;
	  bios->NextKbdCharPtr = CurOfs;

	  if (LOBYTE(data) == '\r') {
	    /* it's the return key, we're done */
	    linebuffer[len++] = LOBYTE(data);
	    break;
	  }
	  else if (LOBYTE(data) >= ' ') {
	    /* a character */
	    if ((len+1)<CON_BUFFER) {
	      linebuffer[len] = LOBYTE(data);
	      WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), &linebuffer[len++], 1, &w, NULL);
	    }
	    /* else beep, but I don't like noise */
	  }
	  else switch (LOBYTE(data)) {
	  case '\b':
	    if (len>0) {
	      len--;
	      WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), "\b \b", 3, &w, NULL);
	    }
	    break;
	  }
	}
	if (len > count) {
	  /* save rest of line for later */
	  lol->offs_unread_CON = linebuffer - (BYTE*)lol + count;
	  len = count;
	}
	memcpy(buffer, linebuffer, len);
      }
      hdr->status = STAT_DONE;
      io->count = len;
    }
    break;
  case CMD_SAFEINPUT:
    if (curbuffer) {
      /* some line input waiting */
      hdr->status = STAT_DONE;
      ((REQ_SAFEINPUT*)hdr)->data = *curbuffer;
    }
    else if (con->attr & ATTR_RAW) {
      if (CurOfs == bios->FirstKbdCharPtr) {
	/* no input */
	hdr->status = STAT_DONE|STAT_BUSY;
      } else {
	/* some keyboard input waiting */
	hdr->status = STAT_DONE;
	((REQ_SAFEINPUT*)hdr)->data = ((BYTE*)bios)[CurOfs];
      }
    } else {
      /* no line input */
      hdr->status = STAT_DONE|STAT_BUSY;
    }
    break;
  case CMD_INSTATUS:
    if (curbuffer) {
      /* we have data */
      hdr->status = STAT_DONE;
    }
    else if (con->attr & ATTR_RAW) {
      if (CurOfs == bios->FirstKbdCharPtr) {
	/* no input */
	hdr->status = STAT_DONE|STAT_BUSY;
      } else {
	/* some keyboard input waiting */
	hdr->status = STAT_DONE;
      }
    } else {
      /* no line input */
      hdr->status = STAT_DONE|STAT_BUSY;
    }

    break;
  case CMD_INFLUSH:
    /* flush line and keyboard queue */
    lol->offs_unread_CON = 0;
    bios->NextKbdCharPtr = bios->FirstKbdCharPtr;
    break;
  case CMD_OUTPUT:
  case CMD_SAFEOUTPUT:
    {
      REQ_IO *io = (REQ_IO *)hdr;
      BYTE *buffer = CTX_SEG_OFF_TO_LIN(ctx,
					SELECTOROF(io->buffer),
					(DWORD)OFFSETOF(io->buffer));
      DWORD result = 0;
      WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buffer, io->count, &result, NULL);
      io->count = result;
      hdr->status = STAT_DONE;
    }
    break;
  default:
    hdr->status = STAT_DONE;
  }
  do_lret(ctx);
}
Exemple #6
0
static int stats_create(struct stats_file *file, unsigned int nr,
			unsigned int interval, time_t start_ts,
			struct stats_record *start)
{
	unsigned int i;
	int err;
	struct stats_record *cur, *next;
	struct stats_file_header *hdr;
	unsigned int pkt;
	unsigned int step_ts;
	unsigned int roaming = FALSE;

	hdr = get_hdr(file);

	hdr->magic = MAGIC;
	hdr->begin = sizeof(struct stats_file_header);
	hdr->end = sizeof(struct stats_file_header);
	hdr->home = UINT_MAX;
	hdr->roaming = UINT_MAX;

	stats_file_update_cache(file);

	if (start) {
		struct stats_record *rec;

		rec = get_end(file);
		memcpy(rec, start, sizeof(struct stats_record));
	} else {
		get_end(file)->ts = start_ts;
	}

	for (i = 0; i < nr; i++) {
		if (file->last == get_end(file)) {
			err = stats_file_remap(file, file->len +
						sysconf(_SC_PAGESIZE));
			if (err < 0)
				return err;

			stats_file_update_cache(file);
		}
		cur = get_end(file);
		next = get_next(file, cur);

		step_ts = (rand() % interval);
		if (step_ts == 0)
			step_ts = 1;

		next->ts = cur->ts + step_ts;
		next->roaming = roaming;
		next->data.time = cur->data.time + step_ts;

		next->data.rx_packets = cur->data.rx_packets;
		next->data.rx_bytes = cur->data.rx_bytes;

		if (rand() % 3 == 0) {
			pkt = rand() % 5;
			next->data.rx_packets += pkt;
			next->data.rx_bytes += pkt * (rand() % 1500);
		}

		next->data.tx_packets = cur->data.tx_packets;
		next->data.tx_bytes = cur->data.tx_bytes;

		if (rand() % 3 == 0) {
			pkt = rand() % 5;
			next->data.tx_packets += pkt;
			next->data.tx_bytes += pkt * (rand() % 1500);
		}

		set_end(file, next);

		if ((rand() % 50) == 0)
			roaming = roaming ? FALSE : TRUE;

	}

	return 0;
}
Exemple #7
0
static int stats_open(struct stats_file *file, const char *name)
{
	struct stats_file_header *hdr;
	struct stat tm;
	int err;
	size_t size = 0;

	bzero(file, sizeof(struct stats_file));

	if (name) {
		file->name = g_strdup(name);

		file->fd = TFR(open(file->name,
					O_RDWR | O_CREAT | O_CLOEXEC, 0644));
		if (file->fd == -1) {
			fprintf(stderr, "open error %s for %s\n",
				strerror(errno), file->name);
			return -errno;
		}

		err = fstat(file->fd, &tm);
		if (err < 0) {
			fprintf(stderr, "fstat error %s for %s\n",
				strerror(errno), file->name);
			return err;
		}

		size = (size_t)tm.st_size;
	} else {
		file->name = g_strdup("stats.XXXXXX.tmp");
		file->fd = g_mkstemp_full(file->name, O_RDWR | O_CREAT, 0644);
		if (file->fd == -1) {
			fprintf(stderr, "creating tmp failed\n");
			return -1;
		}
	}

	if (size == 0)
		size = sysconf(_SC_PAGESIZE);

	err = stats_file_remap(file, size);
	if (err < 0) {
		fprintf(stderr, "remap failed\n");
		return err;
	}

	/* Initialize new file */
	hdr = get_hdr(file);
	if (hdr->magic != MAGIC ||
			hdr->begin < sizeof(struct stats_file_header) ||
			hdr->end < sizeof(struct stats_file_header) ||
			hdr->home < sizeof(struct stats_file_header) ||
			hdr->roaming < sizeof(struct stats_file_header) ||
			hdr->begin > file->len ||
			hdr->end > file->len) {
		hdr->magic = MAGIC;
		hdr->begin = sizeof(struct stats_file_header);
		hdr->end = sizeof(struct stats_file_header);
		hdr->home = UINT_MAX;
		hdr->roaming = UINT_MAX;

	}
	stats_file_update_cache(file);

	return 0;
}
Exemple #8
0
static struct stats_record *get_end(struct stats_file *file)
{
	unsigned int off = get_hdr(file)->end;

	return (struct stats_record *)(file->addr + off);
}
Exemple #9
0
static int stats_file_setup(struct stats_file *file)
{
	struct stats_file_header *hdr;
	struct stat st;
	size_t size = 0;
	int err;

	DBG("file %p fd %d name %s", file, file->fd, file->name);

	err = fstat(file->fd, &st);
	if (err < 0) {
		connman_error("fstat error %s for %s\n",
			strerror(errno), file->name);

		TFR(close(file->fd));
		g_free(file->name);
		file->name = NULL;

		return -errno;
	}

	size = (size_t)st.st_size;
	file->max_len = STATS_MAX_FILE_SIZE;

	if (size < (size_t)sysconf(_SC_PAGESIZE))
		size = sysconf(_SC_PAGESIZE);

	err = stats_file_remap(file, size);
	if (err < 0) {
		TFR(close(file->fd));
		g_free(file->name);
		file->name = NULL;

		return err;
	}

	hdr = get_hdr(file);

	/* Check if data file is in old format and convert */
	if (hdr->magic == MAGIC32 &&
			hdr->begin >= sizeof(struct stats_file_header) &&
			hdr->end >= sizeof(struct stats_file_header) &&
			hdr->home >= sizeof(struct stats_file_header) &&
			hdr->roaming >= sizeof(struct stats_file_header) &&
			hdr->begin <= file->len &&
			hdr->end <= file->len) {
			stats_convert(file);
			/* conversion changes the mapped address */
			hdr = get_hdr(file);
	}

	if (hdr->magic != MAGIC64 ||
			hdr->begin < sizeof(struct stats_file_header) ||
			hdr->end < sizeof(struct stats_file_header) ||
			hdr->home < sizeof(struct stats_file_header) ||
			hdr->roaming < sizeof(struct stats_file_header) ||
			hdr->begin > file->len ||
			hdr->end > file->len) {
		hdr->magic = MAGIC64;
		hdr->begin = sizeof(struct stats_file_header);
		hdr->end = sizeof(struct stats_file_header);
		hdr->home = UINT_MAX;
		hdr->roaming = UINT_MAX;

		stats_file_update_cache(file);
	}

	return 0;
}
Exemple #10
0
static struct stats_record32 *get_begin32(struct stats_file *file)
{
	unsigned int off = get_hdr(file)->begin;

	return (struct stats_record32 *)(file->addr + off);
}