/** * Generate the color pattern for a given color structure * @param t color structure * @param text text to color (not used on this function) * @param pattern pattern will be save on this buffer */ int revm_colorpattern(color_t *t, char *text, char *pattern) { char bo[16], ul[16], fg[16], bg[16]; u_short set = 0; NOPROFILER_IN(); if (t == NULL || (!t->bground && !t->fground && !t->bold && !t->underline)) NOPROFILER_ROUT(-1); /* Set every element */ COLOR_SET_ELEMENT(t->bold, bo, COLOR_BOLD); COLOR_SET_ELEMENT(t->underline, ul, COLOR_UNDERLINE); COLOR_SET_ELEMENT(t->fground, fg, t->fground); COLOR_SET_ELEMENT(t->bground, bg, t->bground); snprintf(pattern, COLOR_TOKEN_LEN - 1, "%%s%s%s%s%sm%%s%s%um%%s", (t->bold > 0 ? bo : ""), (t->underline > 0 ? ul : ""), (t->fground > 0 ? fg : ""), (t->bground > 0 ? bg : ""), S_STARTCOLOR, COLOR_NONE); NOPROFILER_ROUT(0); }
/** * Read a signed leb128 number as describe on the dwarf2 documentation * a little bit optimize * @param data pointer to a buffer where we'll read * @param bread store size readed * @return final value */ long edfmt_read_leb128(void *data, u_int *bread) { long sum = 0; u_int read = 0; u_char c; u_int s = 0; NOPROFILER_IN(); do { c = *(u_char *) (data + read) & 0xFF; read++; sum |= ((long)(c & 127) << s); s += 7; } while ((c & 128) != 0); if ((s < (8 * sizeof(sum))) && (c & 0x40)) sum |= -(((long)1) << s); if (bread) *bread = read; NOPROFILER_ROUT(sum); }
/** * @brief Initialize the hash table */ int elist_init(list_t *h, char *name, u_int type) { list_t *exist; NOPROFILER_IN(); if (type >= aspect_type_nbr) { fprintf(stderr, "Unable to initialize list %s \n", name); PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Unable to initialize list", -1); } exist = elist_find(name); if (exist) { #if 1 //__LIST_DEBUG__ fprintf(stderr, "DEBUG: List %s (%p) already exists in hash with addr %p : NOT CREATING \n", name, h, exist); #endif NOPROFILER_ROUT(1); } #if __LIST_DEBUG__ else fprintf(stderr, "DEBUG: List %s allocated at %p does not exists in hash : CREATING \n", name, h); #endif bzero(h, sizeof(list_t)); h->type = type; h->name = name; hash_add(hash_lists, name, h); NOPROFILER_ROUT(0); }
/** * Build color text * */ char *revm_colorget(char *sp, char *type, void *object) { color_t *t; char pattern[COLOR_TOKEN_LEN]; char text[COLOR_TOKEN_LEN]; char trim_text[COLOR_TOKEN_LEN]; char white_s[COLOR_TOKEN_LEN]; char white_e[COLOR_TOKEN_LEN]; char *pText; NOPROFILER_IN(); if (curtok >= COLOR_TOKENS) { printf("[E] %s:%d %s: WARNING !!!! Token overflow (val:%u)\n", __FILE__, __LINE__, __FUNCTION__, curtok); NOPROFILER_ROUT(NULL); } //printf("Before token = %016llX \n", (eresi_Addr *) object); //snprintf(text, COLOR_TOKEN_LEN - 1, sp, object); if (strchr(sp, 's') == NULL) snprintf(text, COLOR_TOKEN_LEN - 1, sp, *(eresi_Addr *) object); else snprintf(text, COLOR_TOKEN_LEN - 1, sp, object); /* Color isn't activated */ if (!nocolor) NOPROFILER_ROUT(revm_colornothing(sp, object)); t = revm_colortable(type, text); /* Color not found */ if (t == NULL) NOPROFILER_ROUT(revm_colornothing(sp, object)); /* Invalid pattern */ if (revm_colorpattern(t, text, pattern) != 0) NOPROFILER_ROUT(revm_colornothing(sp, object)); pText = text; memset(white_s, 0x00, COLOR_TOKEN_LEN); memset(white_e, 0x00, COLOR_TOKEN_LEN); /* Trim the string from blank char */ if (!trim(text, trim_text, COLOR_TOKEN_LEN, white_s, white_e)) pText = trim_text; snprintf(tokens[curtok], COLOR_TOKEN_LEN - 1, pattern, white_s, pText, white_e); NOPROFILER_ROUT(tokens[curtok++]); }
/** * Retrieve a color information structure from a color type * @param type color type * @param text text to color to filter for warnstring type * @return color structure */ color_t *revm_colortable(char *type, char *text) { NOPROFILER_IN(); /* Override color by warning color if we match the alert regex */ if (world.state.revm_use_alert && !regexec(&world.state.revm_alert, text, 0, 0, 0)) NOPROFILER_ROUT(hash_get(&t_color_hash, "warnstring")); NOPROFILER_ROUT(hash_get(&t_color_hash, type)); }
/* Special functions */ char *revm_coloradv(char *type, char *pattern, char *text) { char *p; NOPROFILER_IN(); p = revm_colorget(pattern, type, text); strncpy(text, p, BUFSIZ); text[BUFSIZ-1] = 0; curtok--; NOPROFILER_ROUT(text); }
/** * Set workspace configuration to standard I/O */ int revm_std_io(revmjob_t *job) { NOPROFILER_IN(); if (!job) NOPROFILER_ROUT(0); job->ws.io.type = REVM_IO_STD; job->ws.io.input_fd = 0; job->ws.io.input = revm_stdinput; job->ws.io.output_fd = 1; job->ws.io.output = revm_stdoutput; NOPROFILER_ROUT(0); }
/** * @brief Read a new line, avoiding comments and void lines */ char *revm_getln() { char *buf; char *sav; NOPROFILER_IN(); do { buf = world.curjob->ws.io.input(); if (buf == ((char *) REVM_INPUT_VOID)) NOPROFILER_ROUT((char *) REVM_INPUT_VOID); if (buf == NULL) NOPROFILER_ROUT(NULL); if (!*buf) { XFREE(__FILE__, __FUNCTION__, __LINE__,buf); NOPROFILER_ROUT(NULL); } sav = buf; while (IS_BLANK(*sav)) sav++; if (!*sav || *sav == REVM_COMMENT_START) { revm_log(sav); revm_log("\n"); revm_buffer_free(buf); if (world.state.revm_mode == REVM_STATE_INTERACTIVE || world.state.revm_mode == REVM_STATE_EMBEDDED) NOPROFILER_ROUT((char*) REVM_INPUT_VOID); buf = NULL; if (*sav) continue; } if (world.state.revm_mode != REVM_STATE_SCRIPT) { revm_output_nolog("\n"); /* avoid looping with readline */ if (revm_is_enabled() && buf == NULL) NOPROFILER_ROUT((char *) REVM_INPUT_VOID); if (revm_is_enabled()) break; } } while (buf == NULL); NOPROFILER_ROUT(buf); }
/** * Initialize Input/Output hooks */ int revm_initio() { static int done = 0; revmjob_t *initial; u_int i; NOPROFILER_IN(); if (done) NOPROFILER_ROUT(0); done = 1; XALLOC(__FILE__, __FUNCTION__, __LINE__,initial, sizeof(revmjob_t), -1); memset(initial, 0, sizeof(revmjob_t)); hash_init(&initial->recur[0].exprs , "job0_rec0_exprs" , 23, ASPECT_TYPE_EXPR); hash_init(&initial->recur[0].labels, "job0_rec0_labels", 23, ASPECT_TYPE_STR); revm_std_io(initial); initial->ws.active = 1; initial->ws.createtime = time(&initial->ws.createtime); world.initial = world.curjob = initial; hash_init(&world.jobs, "jobs", 11, ASPECT_TYPE_UNKNOW); hash_add(&world.jobs, "local", initial); initial->ws.name = strdup("local"); hash_init(&initial->loaded, "initial_loaded_files", 51, ASPECT_TYPE_UNKNOW); hash_init(&initial->dbgloaded, "initial_dbgloaded_files", 11, ASPECT_TYPE_UNKNOW); for (i = 0; i < REVM_MAXSRCNEST; i++) { initial->recur[i].script = NULL; initial->recur[i].lstcmd = NULL; initial->iter[i].elmidx = REVM_IDX_UNINIT; } initial->recur[0].funcname = "top-level"; profiler_setcolor(revm_endline, revm_colorinstr, revm_colorstr, revm_colorfieldstr, revm_colortypestr, revm_colorend, revm_colorwarn, revm_colorfunction, revm_colorfilename); profiler_setmorecolor(revm_coloradv, revm_colorinstr_fmt, revm_coloraddress, revm_colornumber, revm_colorstr_fmt, revm_colorfieldstr_fmt, revm_colortypestr_fmt, revm_colorwarn_fmt); NOPROFILER_ROUT(0); }
/** * Return without color * @param sp given string (pattern like %s or %d etc ..) * @param object objet to print using the string * @return generate string */ static char *revm_colornothing(char *sp, void *object) { NOPROFILER_IN(); if (!strcmp(sp, "%s")) NOPROFILER_ROUT((char *) object); if (strchr(sp, 's') == NULL) snprintf(tokens[curtok], COLOR_TOKEN_LEN - 1, sp, *(eresi_Addr *) object); else snprintf(tokens[curtok], COLOR_TOKEN_LEN - 1, sp, object); NOPROFILER_ROUT(tokens[curtok++]); }
/** * @brief Read input from the current IO file descriptor */ char *revm_read_input() { char tmpbuf[BUFSIZ + 1]; int len; u_char wantmore; NOPROFILER_IN(); /* In case we are scripting, even readline will use a read */ for (wantmore = len = 0; len < BUFSIZ; len++) switch (read(world.curjob->ws.io.input_fd, tmpbuf + len, 1)) { case 1: if (tmpbuf[len] == '\n') { if (len == 0) { //fprintf(stderr, "Read length 0 ... \n"); NOPROFILER_ROUT((char *) REVM_INPUT_VOID); } if (wantmore) { len--; wantmore = 0; continue; } if (world.state.revm_mode == REVM_STATE_EMBEDDED && world.state.revm_side == REVM_SIDE_CLIENT) tmpbuf[len + 1] = 0x00; else tmpbuf[len] = 0x00; goto end; } else if ((len > 2 && tmpbuf[len - 1] == ':' && tmpbuf[len] == ':') || tmpbuf[len] == ',') wantmore = 1; else wantmore = 0; continue; default: *tmpbuf = 0x00; goto end; } end: //fprintf(stderr, "[pid = %u] Read on fd = *%s*\n", getpid(), tmpbuf); NOPROFILER_ROUT((*tmpbuf ? strdup(tmpbuf) : NULL)); }
/** * INPUT IO handler for stdin */ char *revm_stdinput() { char *str; NOPROFILER_IN(); str = NULL; /* Case if we are using readline */ if (revm_is_enabled() && world.state.revm_mode != REVM_STATE_SCRIPT) { str = revm_input_check(); NOPROFILER_ROUT(str); } /* If not, read the stdin file descriptor */ NOPROFILER_ROUT(revm_read_input()); }
/** * @brief Initialize the hash table * @param h Pointer to the hash to initialize * @param name Name of the hash. * @param size Size to document * @param type Type to document * @param Returns 0 on success, -1 on error or 1 if hash already exists. */ int hash_init(hash_t *h, char *name, int size, u_int type) { NOPROFILER_IN(); /* First checks */ /* Initialize the global hash table of lists and the global hash table of hash tables */ if (!hash_hash) { hash_hash = (hash_t *) calloc(sizeof(hash_t), 1); hash_init(hash_hash, "hashes", 51, ASPECT_TYPE_UNKNOW); } if (type >= aspect_type_nbr) { fprintf(stderr, "Unable to initialize hash table %s \n", name); PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Unable to initialize hash table", -1); } if (h != hash_hash && hash_find(name) && h->ent) { #if __DEBUG__ fprint(stderr, "Hash table already exists and initialized\n"); #endif NOPROFILER_ROUT(1); } //printf("INIT HASH %s \n", name); /* Add a new element */ XALLOC(__FILE__, __FUNCTION__, __LINE__, h->ent, size * sizeof(listent_t), -1); h->size = size; h->type = type; h->elmnbr = 0; h->linearity = 0; h->name = name; hash_add(hash_hash, name, h); if (!hash_lists) { hash_lists = (hash_t *) calloc(sizeof(hash_t), 1); hash_init(hash_lists, "lists", 51, ASPECT_TYPE_UNKNOW); } NOPROFILER_ROUT(0); }
/** * Trim a string from blank char and copy it on to argument * @param from source * @param to destination * @param size buffer size * @param start saved starting blank chars (for replace in another place) * @param end saved ending blank chars (for replace in another place) */ static int trim(char *from, char *to, u_int size, char *start, char *end) { u_int len, istart, iend; NOPROFILER_IN(); if (size == 0 || size > COLOR_TOKEN_LEN || from == NULL || to == NULL) NOPROFILER_ROUT(-1); len = strlen(from); /* Speed check */ if (!IS_BLANK(from[0]) && !IS_BLANK(from[len])) NOPROFILER_ROUT(-1); /* Before */ for (istart = 0; istart < len && IS_BLANK(from[istart]); istart++); /* All blank, no modifications */ if (istart == len) NOPROFILER_ROUT(-1); /* After */ for (iend = len; iend > 0 && IS_BLANK(from[iend]); iend--); iend = len - iend; /* Copy the right char on to argument */ strncpy(to, from + istart, len - istart - iend); to[len - istart - iend] = 0x00; if (start) { strncpy(start, from, istart); start[istart] = 0x00; } if (end) { strncpy(end, from + len - iend, iend); end[iend] = 0x00; } NOPROFILER_ROUT(0); }
/* Return number of color chars (not total size) */ int revm_color_count(char *string) { int count = 0; int len; int i; NOPROFILER_IN(); len = strlen(string); for (i = 0; i < len; i++) { if (string[i] == C_STARTCOLOR) { count++; while (i < len && string[i] != 'm') i++; } } NOPROFILER_ROUT(count); }
/** * Read an unsigned leb128 number as describe on the dwarf2 documentation * a little bit optimize * @param data pointer to a buffer where we'll read * @param bread store size readed * @return final value */ u_long edfmt_read_uleb128(void *data, u_int *bread) { u_long sum = 0; u_int read = 0; u_char c; int s = 0; NOPROFILER_IN(); do { c = *(u_char *) (data + read) & 0xFF; read++; sum |= ((u_long)(c & 127) << s); s += 7; } while ((c & 128) != 0); if (bread) *bread = read; NOPROFILER_ROUT(sum); }
/** * Return total size of colors on a string */ int revm_color_size(char *string) { int size = 0; int len; int i; NOPROFILER_IN(); len = strlen(string); for (i = 0; i < len; i++) { if (string[i] == C_STARTCOLOR) { while (i < len && string[i] != 'm') { size++; i++; } } } NOPROFILER_ROUT(size); }
/* read a complete packet from given socket */ pkt_t *dump_recv_pkt(int s) { int tmp = 0; int tmp2 = 0; int len = 0; pkt_t *msg; int try = 0; NOPROFILER_IN(); XALLOC(__FILE__, __FUNCTION__, __LINE__,msg, sizeof (pkt_t), NULL); /* read fixed size header part */ do { tmp2 = recv(s, (void *) msg + tmp, (size_t) (HDR_SIZE - tmp), MSG_DONTWAIT); /* connection closed */ if (tmp2 == 0) { #if !defined(ERESI_INTERNAL) printf("[WW] Connection closed by remote host (1)\n"); #endif XFREE(__FILE__, __FUNCTION__, __LINE__,msg); return (pkt_t *)(-1); } /* error */ if (tmp2 == (-1)) { /* EAGAIN */ if (tmp2 == EAGAIN) { try++; if (try > DUMP_MAXTRY) { XFREE(__FILE__, __FUNCTION__, __LINE__, msg); return (pkt_t *)(-1); } continue; } #if !defined(ERESI_INTERNAL) printf("[EE] Error while reading on socket (1)\n"); perror("recv"); #endif XFREE(__FILE__, __FUNCTION__, __LINE__, msg); return (pkt_t *)(-1); } len += tmp2; tmp += tmp2; } while (tmp != (size_t)(HDR_SIZE)); if (ntohl(msg->path_len) != 0) { /* read pkt path from header */ XALLOC(__FILE__, __FUNCTION__, __LINE__, msg->path, ntohl(msg->path_len) * sizeof (dump_id_t), (pkt_t *) -1); tmp = 0; do { tmp2 = recv(s, (void *) msg->path + tmp, (size_t) ntohl(msg->path_len)*sizeof (dump_id_t) - tmp, MSG_DONTWAIT); /* connection closed */ if (tmp2 == 0) { #if !defined(ERESI_INTERNAL) printf("[WW] Connection closed by remote host (2)\n"); #endif XFREE(__FILE__, __FUNCTION__, __LINE__,msg); return (pkt_t *)(-1); } /* error */ if (tmp2 == (-1)) { /* EAGAIN */ if (tmp2 == EAGAIN) { try++; if (try > DUMP_MAXTRY) { XFREE(__FILE__, __FUNCTION__, __LINE__,msg->path); XFREE(__FILE__, __FUNCTION__, __LINE__,msg); return (pkt_t *)(-1); } continue; } #if !defined(ERESI_INTERNAL) printf("[EE] Error while reading on socket (2)\n"); perror("recv"); #endif XFREE(__FILE__, __FUNCTION__, __LINE__,msg->path); XFREE(__FILE__, __FUNCTION__, __LINE__,msg); return (pkt_t *)(-1); } len += tmp2; tmp += tmp2; } while (tmp != ntohl(msg->path_len)*sizeof (dump_id_t)); } else msg->path=NULL; /* read payload */ if (ntohl(msg->size) != 0) { XALLOC(__FILE__, __FUNCTION__, __LINE__,msg->data, (size_t) sizeof (char)*ntohl(msg->size), (pkt_t *) -1); tmp = 0; do { tmp2 = recv(s, (void *) msg->data + tmp, (size_t) ntohl(msg->size)*sizeof (char) - tmp, MSG_DONTWAIT); /* connection closed */ if (tmp2 == 0) { #if !defined(ERESI_INTERNAL) printf("[WW] Connection closed by remote host (3)\n"); #endif XFREE(__FILE__, __FUNCTION__, __LINE__,msg->path); XFREE(__FILE__, __FUNCTION__, __LINE__,msg->data); XFREE(__FILE__, __FUNCTION__, __LINE__,msg); return (pkt_t *)(-1); } /* error */ if (tmp2 == (-1)) { /* EAGAIN */ if (errno == EAGAIN) { try++; if (try > DUMP_MAXTRY) { XFREE(__FILE__, __FUNCTION__, __LINE__,msg->path); XFREE(__FILE__, __FUNCTION__, __LINE__,msg->data); XFREE(__FILE__, __FUNCTION__, __LINE__,msg); return (pkt_t *)(-1); } continue; } #if !defined(ERESI_INTERNAL) printf("[EE] Error while reading on socket (3)\n"); perror("recv"); #endif XFREE(__FILE__, __FUNCTION__, __LINE__,msg->path); XFREE(__FILE__, __FUNCTION__, __LINE__,msg->data); XFREE(__FILE__, __FUNCTION__, __LINE__,msg); return (pkt_t *)(-1); } len += tmp2; tmp += tmp2; } while (tmp != ntohl(msg->size)*sizeof (char)); } else msg->data = NULL; return msg; } /* handle RR packet */ int dump_receive_RR(pkt_t *pkt) { dump_id_t prev; dump_id_t *npath; listent_t *actual; int index; NOPROFILER_IN(); if (dump_lookup_RR_recently_seen(pkt->id)) { return (-1); } /* add packet's id to RR table */ dump_add_RR_recently_seen(pkt->id); /* sanity check */ if (ntohl(pkt->path_len) == 0) return (-1); /* add myid to path's tail */ XALLOC(__FILE__, __FUNCTION__, __LINE__,npath, sizeof (dump_id_t)*(ntohl(pkt->path_len)+1), -1); /* back the previous hop up */ prev = pkt->path[ntohl(pkt->path_len)-1]; /* copy previous path's nodes */ memcpy (npath, pkt->path, ntohl(pkt->path_len)*sizeof (dump_id_t)); /* is my id ? */ if (dump_is_myid(pkt->dst)) { /* add myid to path */ npath[ntohl(pkt->path_len) + 1 - 1] = dump_get_myid(dump_lookup_neighbor (prev)); #if __DEBUG_DUMP__ printf("[DUMP] dump_receive_RR : it's me !! \n"); #endif /* send Rr packet with new id */ if (dump_send_Rr(pkt->dst, pkt->src, (ntohl(pkt->path_len)+1), npath, dump_lookup_neighbor(prev), 0) < 0) { #if !defined(ERESI_INTERNAL) fprintf(stderr, "dump_send_Rr error (1)\n"); #endif XFREE(__FILE__, __FUNCTION__, __LINE__,npath); return (-1); } } else { #if __DEBUG_DUMP__ printf("[DUMP] dump_receive_RR : it's NOT me !! \n"); #endif /* send it to all neighbors ... */ for (index = 0; index < dump_world.ports.size; index++) for (actual = &dump_world.ports.ent[index]; actual != NULL && actual->key != NULL; actual = actual->next) { /* ... but the sender */ if (strcmp(actual->key, inet_ntoa(prev))) { #if __DEBUG_DUMP__ printf("[DUMP] dump_receive_RR :" " send to %s, it's NOT the Request sender\n", actual->key); #endif /* add myid to path */ npath[ntohl(pkt->path_len) + 1 - 1] = dump_get_myid((long) actual->data); /* send RR packet with same id */ if (dump_send_RR(pkt->src, pkt->dst, (ntohl(pkt->path_len)+1), npath, (long) actual->data, pkt->id) < 0) { #if !defined(ERESI_INTERNAL) printf("[EE] dump_send_RR error (2)\n"); #endif XFREE(__FILE__, __FUNCTION__, __LINE__,npath); return (-1); } } #if __DEBUG_DUMP__ && !defined(ERESI_INTERNAL) else { printf("[DUMP] dump_receive_RR :" " don't send to %s, it's the Request sender\n", actual->key); } #endif } } XFREE(__FILE__, __FUNCTION__, __LINE__,npath); return 0; }