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; }
/* 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; }
/* 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; }
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; }
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); }
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; }
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; }
static struct stats_record *get_end(struct stats_file *file) { unsigned int off = get_hdr(file)->end; return (struct stats_record *)(file->addr + off); }
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; }
static struct stats_record32 *get_begin32(struct stats_file *file) { unsigned int off = get_hdr(file)->begin; return (struct stats_record32 *)(file->addr + off); }